From 3c805369e85d27bdc13a234ae0968a1b0101024d Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Wed, 14 Oct 2015 13:04:50 +0100 Subject: [PATCH 1/7] parameter setting for full 3000 second run --- .travis.yml | 7 ++ examples/boussinesq_2d_imex/playground.py | 14 ++-- requirements.txt | 3 + tests/test_collocation.py | 84 +++++++++++++++++++++++ 4 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 .travis.yml create mode 100644 requirements.txt create mode 100644 tests/test_collocation.py diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..1fe1bf0fda --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: python +python: + - "2.7" +# command to install dependencies +install: "pip install -r requirements.txt" +# +script: py.test -v tests/ \ No newline at end of file diff --git a/examples/boussinesq_2d_imex/playground.py b/examples/boussinesq_2d_imex/playground.py index 69401f0f2c..f75816e03b 100644 --- a/examples/boussinesq_2d_imex/playground.py +++ b/examples/boussinesq_2d_imex/playground.py @@ -28,7 +28,7 @@ # This comes as read-in for the level class lparams = {} - lparams['restol'] = 1E-14 + lparams['restol'] = 1E-8 swparams = {} swparams['collocation_class'] = collclass.CollGaussLobatto @@ -36,14 +36,14 @@ swparams['do_LU'] = True sparams = {} - sparams['maxiter'] = 4 + sparams['maxiter'] = 12 # setup parameters "in time" t0 = 0 - #Tend = 3000 - #Nsteps = 500 - Tend = 30 - Nsteps = 5 + Tend = 3000 + Nsteps = 500 + #Tend = 30 + #Nsteps = 5 dt = Tend/float(Nsteps) # This comes as read-in for the problem class @@ -58,7 +58,7 @@ pparams['order_upw'] = [5, 1] pparams['gmres_maxiter'] = [50, 50] pparams['gmres_restart'] = [20, 20] - pparams['gmres_tol'] = [1e-6, 1e-6] + pparams['gmres_tol'] = [1e-8, 1e-8] # This comes as read-in for the transfer operations tparams = {} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..51c58dc2ae --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +py.test +numpy +scipy diff --git a/tests/test_collocation.py b/tests/test_collocation.py new file mode 100644 index 0000000000..d998ba06eb --- /dev/null +++ b/tests/test_collocation.py @@ -0,0 +1,84 @@ +import pySDC.Collocation +from pySDC.CollocationClasses import * +import numpy as np +import pytest + +# py.test excludes classes with a constructor by default, so define parameter here +t_start = 0.0 +t_end = 1.0 +classes = [ ["CollGaussLegendre", 2, 2]] +#classes = [ ["CollGaussLegendre", 2, 12], ["CollGaussLobatto", 2, 12], ["CollGaussRadau_Right", 2, 12] ] + +class TestCollocation: + + # TEST 1: + # Check that the quadrature rule integrates polynomials up to order p-1 exactly + # ----------------------------------------------------------------------------- + def test_1(self): + for type in classes: + for M in range(type[1],type[2]+1): + coll = getattr(pySDC.CollocationClasses, type[0])(M, t_start, t_end) + + # some basic consistency tests + assert np.size(coll.nodes)==np.size(coll.weights), "For node type " + type[0] + ", number of entries in nodes and weights is different" + assert np.size(coll.nodes)==M, "For node type " + type[0] + ", requesting M nodes did not produce M entries in nodes and weights" + + + # generate random set of polynomial coefficients + poly_coeff = np.random.rand(coll.order-1) + # evaluate polynomial at collocation nodes + poly_vals = np.polyval(poly_coeff, coll.nodes) + # use python's polyint function to compute anti-derivative of polynomial + poly_int_coeff = np.polyint(poly_coeff) + # Compute integral from 0.0 to 1.0 + int_ex = np.polyval(poly_int_coeff, t_end) - np.polyval(poly_int_coeff, t_start) + # use quadrature rule to compute integral + int_coll = coll.evaluate(coll.weights, poly_vals) + # For large values of M, substantial differences from different round of error have to be considered + assert abs(int_ex - int_coll) < 1e-10, "For node type " + type[0] + ", failed to integrate polynomial of degree " + str(coll.order-1) + " exactly. Error: %5.3e" % abs(int_ex - int_coll) + + + # TEST 2: + # Check that the Qmat entries are equal to the sum of Smat entries + # ---------------------------------------------------------------- + def test_2(self): + for type in classes: + for M in range(type[1],type[2]+1): + coll = getattr(pySDC.CollocationClasses, type[0])(M, t_start, t_end) + Q = coll.Qmat + Q = Q[1:,1:] + S = coll.Smat + S = S[1:,1:] + #print Q + #print S + assert np.shape(Q) == np.shape(S), "For node type " + type[0] + ", Qmat and Smat have different shape" + shape = np.shape(Q) + assert shape[0] == shape[1], "For node type " + type[0] + ", Qmat / Smat are not quadratic" + for i in range(0,M): + Ssum = np.sum(S[0:i,:], axis=0) + #print Ssum + #print Q[i,:] + # ...the matrices do not have size MxM, but rather (M+1)x(M+1)... how does the summation property look like here + + # TEST 3: + # Check that the partial quadrature rules from Qmat entries have order equal to number of nodes M + # ----------------------------------------------------------------------------------------------- + def test_3(self): + for type in classes: + for M in range(type[1],type[2]+1): + coll = getattr(pySDC.CollocationClasses, type[0])(M, t_start, t_end) + Q = coll.Qmat + Q = Q[1:,1:] + # as in TEST 1, create and integrate a polynomial with random coefficients, but now of degree M-1 + poly_coeff = np.random.rand(M-1) + poly_vals = np.polyval(poly_coeff, coll.nodes) + poly_int_coeff = np.polyint(poly_coeff) + #print Q + for i in range(0,M): + int_ex = np.polyval(poly_int_coeff, coll.nodes[i]) - np.polyval(poly_int_coeff, t_start) + print np.shape(Q) + #int_coll = np.dot(poly_vals, Q[i,:]) + + # TEST 4: + # Check that the quadrature rules for [tau_m, tau_m+1] defined by Smat have order equal to number of nodes M + # ---------------------------------------------------------------------------------------------------------- From 0864f27bd5c306616b213baebda2151412c9f7ba Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Fri, 20 Nov 2015 15:46:48 +0000 Subject: [PATCH 2/7] test for summation property of Qmat and Smat now running correctly --- tests/test_collocation.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/tests/test_collocation.py b/tests/test_collocation.py index d998ba06eb..6de7960e69 100644 --- a/tests/test_collocation.py +++ b/tests/test_collocation.py @@ -6,8 +6,8 @@ # py.test excludes classes with a constructor by default, so define parameter here t_start = 0.0 t_end = 1.0 -classes = [ ["CollGaussLegendre", 2, 2]] -#classes = [ ["CollGaussLegendre", 2, 12], ["CollGaussLobatto", 2, 12], ["CollGaussRadau_Right", 2, 12] ] +#classes = [ ["CollGaussLegendre", 2, 2]] +classes = [ ["CollGaussLegendre", 2, 12], ["CollGaussLobatto", 2, 12], ["CollGaussRadau_Right", 2, 12] ] class TestCollocation: @@ -45,20 +45,14 @@ def test_2(self): for type in classes: for M in range(type[1],type[2]+1): coll = getattr(pySDC.CollocationClasses, type[0])(M, t_start, t_end) - Q = coll.Qmat - Q = Q[1:,1:] - S = coll.Smat - S = S[1:,1:] - #print Q - #print S + Q = coll.Qmat[1:,1:] + S = coll.Smat[1:,1:] assert np.shape(Q) == np.shape(S), "For node type " + type[0] + ", Qmat and Smat have different shape" shape = np.shape(Q) assert shape[0] == shape[1], "For node type " + type[0] + ", Qmat / Smat are not quadratic" + SSum = np.cumsum(S[:,:],axis=0) for i in range(0,M): - Ssum = np.sum(S[0:i,:], axis=0) - #print Ssum - #print Q[i,:] - # ...the matrices do not have size MxM, but rather (M+1)x(M+1)... how does the summation property look like here + assert np.linalg.norm( Q[i,:] - SSum[i,:] ) < 1e-15, "For node type " + type[0] + ", Qmat and Smat did not satisfy the expected summation property." # TEST 3: # Check that the partial quadrature rules from Qmat entries have order equal to number of nodes M From 3d41c5012e5044ec42d215f484ee6bf0ca7989d6 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Fri, 20 Nov 2015 15:49:13 +0000 Subject: [PATCH 3/7] order check for partial quadrature rules now running --- tests/test_collocation.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/test_collocation.py b/tests/test_collocation.py index 6de7960e69..6b20837588 100644 --- a/tests/test_collocation.py +++ b/tests/test_collocation.py @@ -61,17 +61,15 @@ def test_3(self): for type in classes: for M in range(type[1],type[2]+1): coll = getattr(pySDC.CollocationClasses, type[0])(M, t_start, t_end) - Q = coll.Qmat - Q = Q[1:,1:] + Q = coll.Qmat[1:,1:] # as in TEST 1, create and integrate a polynomial with random coefficients, but now of degree M-1 poly_coeff = np.random.rand(M-1) poly_vals = np.polyval(poly_coeff, coll.nodes) poly_int_coeff = np.polyint(poly_coeff) - #print Q for i in range(0,M): int_ex = np.polyval(poly_int_coeff, coll.nodes[i]) - np.polyval(poly_int_coeff, t_start) - print np.shape(Q) - #int_coll = np.dot(poly_vals, Q[i,:]) + int_coll = np.dot(poly_vals, Q[i,:]) + assert abs(int_ex - int_coll)<1e-10, "For node type " + type[0] + ", partial quadrature rule failed to integrate polynomial of degree M-1 exactly for M = " + str(M) # TEST 4: # Check that the quadrature rules for [tau_m, tau_m+1] defined by Smat have order equal to number of nodes M From b2f405e579d2c1fadb25553bdddba418a558b560 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Fri, 20 Nov 2015 15:59:10 +0000 Subject: [PATCH 4/7] added test to make sure that node-to-node integration using Smat entries integrates polynomials of degree M-1 exactly --- .travis.yml | 14 ++++++++++---- requirements.txt | 3 +-- tests/test_collocation.py | 18 ++++++++++++++---- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1fe1bf0fda..705de3fda9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,13 @@ language: python +sudo: false + python: - - "2.7" + - "2.7.10" # command to install dependencies -install: "pip install -r requirements.txt" -# -script: py.test -v tests/ \ No newline at end of file + +install: + - conda update -yes conda + - conda install -r requirements.txt + +# command to run tests +script: py.test tests/ diff --git a/requirements.txt b/requirements.txt index 51c58dc2ae..8fac0898a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,2 @@ -py.test -numpy +pytest scipy diff --git a/tests/test_collocation.py b/tests/test_collocation.py index 6b20837588..c435428ef0 100644 --- a/tests/test_collocation.py +++ b/tests/test_collocation.py @@ -69,8 +69,18 @@ def test_3(self): for i in range(0,M): int_ex = np.polyval(poly_int_coeff, coll.nodes[i]) - np.polyval(poly_int_coeff, t_start) int_coll = np.dot(poly_vals, Q[i,:]) - assert abs(int_ex - int_coll)<1e-10, "For node type " + type[0] + ", partial quadrature rule failed to integrate polynomial of degree M-1 exactly for M = " + str(M) + assert abs(int_ex - int_coll)<1e-12, "For node type " + type[0] + ", partial quadrature from Qmat rule failed to integrate polynomial of degree M-1 exactly for M = " + str(M) - # TEST 4: - # Check that the quadrature rules for [tau_m, tau_m+1] defined by Smat have order equal to number of nodes M - # ---------------------------------------------------------------------------------------------------------- + def test_4(self): + for type in classes: + for M in range(type[1],type[2]+1): + coll = getattr(pySDC.CollocationClasses, type[0])(M, t_start, t_end) + S = coll.Smat[1:,1:] + # as in TEST 1, create and integrate a polynomial with random coefficients, but now of degree M-1 + poly_coeff = np.random.rand(M-1) + poly_vals = np.polyval(poly_coeff, coll.nodes) + poly_int_coeff = np.polyint(poly_coeff) + for i in range(1,M): + int_ex = np.polyval(poly_int_coeff, coll.nodes[i]) - np.polyval(poly_int_coeff, coll.nodes[i-1]) + int_coll = np.dot(poly_vals, S[i,:]) + assert abs(int_ex - int_coll)<1e-12, "For node type " + type[0] + ", partial quadrature rule from Smat failed to integrate polynomial of degree M-1 exactly for M = " + str(M) From 3902b639c212d328a58b063720fbfe4bd492eeb6 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Mon, 23 Nov 2015 16:12:55 +0000 Subject: [PATCH 5/7] renamed function to plot convergence of FD matrix, so it does not get included by nosetests --- .../{testFDOrder.py => plotFDconvergence.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/advection_1d_implicit/{testFDOrder.py => plotFDconvergence.py} (100%) diff --git a/examples/advection_1d_implicit/testFDOrder.py b/examples/advection_1d_implicit/plotFDconvergence.py similarity index 100% rename from examples/advection_1d_implicit/testFDOrder.py rename to examples/advection_1d_implicit/plotFDconvergence.py From 62a99cf18135b967d8f9b07c6b38d7574902ac61 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Mon, 23 Nov 2015 16:14:43 +0000 Subject: [PATCH 6/7] commented out python version test; runs for versions before 3.3. --- tests/tests_core.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/tests_core.py b/tests/tests_core.py index e2d5bae227..a680e2b337 100644 --- a/tests/tests_core.py +++ b/tests/tests_core.py @@ -1,9 +1,9 @@ import numpy as np -def test_python_version(): - import sys - assert sys.version_info >= (3, 3), "Need Python 3.3 at least" +#def test_python_version(): +# import sys +# assert sys.version_info >= (3, 3), "Need Python 3.3 at least" # def test_return_types(): # import pySDC.problem as pr @@ -177,4 +177,4 @@ def check_datatypes_particles(init): assert p7 >= 0 assert np.all(p8.pos.values==1.0) assert np.all(p8.vel.values==10.0) - assert np.all(a3.values==300.0) \ No newline at end of file + assert np.all(a3.values==300.0) From f207fd2533e6fb379d13dfa244b1c6ab5df53998 Mon Sep 17 00:00:00 2001 From: Daniel Ruprecht Date: Tue, 24 Nov 2015 11:17:35 +0000 Subject: [PATCH 7/7] randomised interval boundaries in collocation test --- .travis.yml | 13 ------------- requirements.txt | 2 -- tests/test_collocation.py | 10 ++++++---- 3 files changed, 6 insertions(+), 19 deletions(-) delete mode 100644 .travis.yml delete mode 100644 requirements.txt diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 705de3fda9..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: python -sudo: false - -python: - - "2.7.10" -# command to install dependencies - -install: - - conda update -yes conda - - conda install -r requirements.txt - -# command to run tests -script: py.test tests/ diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 8fac0898a5..0000000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -pytest -scipy diff --git a/tests/test_collocation.py b/tests/test_collocation.py index c435428ef0..efa7cfd687 100644 --- a/tests/test_collocation.py +++ b/tests/test_collocation.py @@ -4,10 +4,12 @@ import pytest # py.test excludes classes with a constructor by default, so define parameter here -t_start = 0.0 -t_end = 1.0 -#classes = [ ["CollGaussLegendre", 2, 2]] -classes = [ ["CollGaussLegendre", 2, 12], ["CollGaussLobatto", 2, 12], ["CollGaussRadau_Right", 2, 12] ] + +# generate random boundaries for the time slice with 0.0 <= t_start < 0.2 and 0.8 <= t_end < 1.0 +t_start = np.random.rand(1)*0.2 +t_end = 0.8 + np.random.rand(1)*0.2 + +classes = [ ["CollGaussLegendre", 2, 12], ["CollGaussLobatto", 2, 12], ["CollGaussRadau_Right", 2, 12] ] class TestCollocation: