Skip to content

Commit

Permalink
Merge pull request #721 from ketch/add_pytests
Browse files Browse the repository at this point in the history
Add pytest-based tests and remove nose tests.
  • Loading branch information
mandli authored Aug 7, 2024
2 parents 05b28dc + c2f1594 commit 1d7ba17
Show file tree
Hide file tree
Showing 66 changed files with 739 additions and 1,821 deletions.
9 changes: 5 additions & 4 deletions examples/acoustics_1d_homogeneous/acoustics_1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@

def setup(use_petsc=False, kernel_language='Fortran', solver_type='classic',
outdir='./_output', ptwise=False, weno_order=5,
time_integrator='SSP104', disable_output=False, output_style=1):
time_integrator='SSP104', disable_output=False, output_style=1,
num_cells=100):

if use_petsc:
import clawpack.petclaw as pyclaw
Expand Down Expand Up @@ -54,7 +55,7 @@ def setup(use_petsc=False, kernel_language='Fortran', solver_type='classic',

solver.kernel_language = kernel_language

x = pyclaw.Dimension(0.0, 1.0, 100, name='x')
x = pyclaw.Dimension(0.0, 1.0, num_cells, name='x')
domain = pyclaw.Domain(x)
num_eqn = 2
state = pyclaw.State(domain, num_eqn)
Expand All @@ -71,9 +72,9 @@ def setup(use_petsc=False, kernel_language='Fortran', solver_type='classic',
state.problem_data['cc'] = sqrt(bulk/rho) # Sound speed

xc = domain.grid.x.centers
beta = 100
beta = 200
gamma = 0
x0 = 0.75
x0 = 0.5
state.q[0, :] = exp(-beta * (xc-x0)**2) * cos(gamma * (xc - x0))
state.q[1, :] = 0.0

Expand Down
118 changes: 48 additions & 70 deletions examples/acoustics_1d_homogeneous/test_acoustics.py
Original file line number Diff line number Diff line change
@@ -1,70 +1,48 @@

def test_1d_acoustics():
"""test_1d_acoustics
tests against known classic, sharpclaw, and high-order weno results """

from . import acoustics_1d

def verify_expected(expected):
""" binds the expected value to the acoustics_verify methods """
def acoustics_verify(claw):
from clawpack.pyclaw.util import check_diff
import numpy as np

# tests are done across the entire domain of q normally
q0 = claw.frames[0].state.get_q_global()
qfinal = claw.frames[claw.num_output_times].state.get_q_global()

# and q_global is only returned on process 0
if q0 is not None and qfinal is not None:
q0 = q0.reshape([-1])
qfinal = qfinal.reshape([-1])
dx = claw.solution.domain.grid.delta[0]
test = dx*np.sum(np.abs(qfinal-q0))
return check_diff(expected, test, abstol=1e-4)
else:
return
return acoustics_verify

from clawpack.pyclaw.util import gen_variants

classic_tests = gen_variants(acoustics_1d.setup, verify_expected(0.001049),
kernel_languages=('Python', 'Fortran'),
solver_type='classic', disable_output=True)

time_step_test = gen_variants(acoustics_1d.setup, verify_expected(0.002020),
kernel_languages=('Python',),
solver_type='classic', disable_output=True,
output_style=(3))

ptwise_tests = gen_variants(acoustics_1d.setup, verify_expected(0.001049),
kernel_languages=('Fortran',), ptwise=True,
solver_type='classic', disable_output=True)

sharp_tests_rk = gen_variants(acoustics_1d.setup, verify_expected(0.000299),
kernel_languages=('Python', 'Fortran'),
solver_type='sharpclaw',
time_integrator='SSP104', disable_output=True)

sharp_tests_lmm = gen_variants(acoustics_1d.setup,
verify_expected(0.000231),
kernel_languages=('Python', 'Fortran'),
solver_type='sharpclaw',
time_integrator='SSPLMMk3',
disable_output=True)

weno_tests = gen_variants(acoustics_1d.setup, verify_expected(0.000153),
kernel_languages=('Fortran',),
solver_type='sharpclaw', time_integrator='SSP104',
weno_order=17, disable_output=True)

from itertools import chain
for test in chain(classic_tests, time_step_test, ptwise_tests,
sharp_tests_rk, sharp_tests_lmm, weno_tests):
yield test


if __name__ == "__main__":
import nose
nose.main()
from . import acoustics_1d
from clawpack.pyclaw.util import check_diff
import numpy as np

def error(**kwargs):
"""
Compute difference between initial and final solutions.
This should vanish due to the periodic boundary conditions
"""

claw = acoustics_1d.setup(disable_output=True,**kwargs)
claw.run()

# tests are done across the entire domain of q normally
q0 = claw.frames[0].state.get_q_global()
qfinal = claw.frames[claw.num_output_times].state.get_q_global()

q0 = q0.reshape([-1])
qfinal = qfinal.reshape([-1])
dx = claw.solution.domain.grid.delta[0]
diff = dx*np.sum(np.abs(qfinal-q0))
return diff

class TestRegression:
def test_python_classic(self):
assert abs(error(kernel_language='Python',solver_type='classic')-0.001981)<1e-5

def test_fortran_classic(self):
assert abs(error(kernel_language='Fortran',solver_type='classic')-0.001981)<1e-5

def test_sharpclaw(self):
assert abs(error(kernel_language='Fortran',solver_type='sharpclaw')-0.001540)<1e-5
assert abs(error(kernel_language='Fortran',solver_type='sharpclaw',weno_order=11)-0.000521)<1e-5
assert abs(error(kernel_language='Fortran',solver_type='sharpclaw',time_integrator='SSPLMMk3')-0.001545)<1e-5

class TestAccuracy:

def test_python_classic(self):
assert abs(error(num_cells=2000,kernel_language='Python',solver_type='classic'))<1e-5

def test_fortran_classic(self):
assert abs(error(num_cells=2000,kernel_language='Fortran',solver_type='classic'))<1e-5
assert abs(error(num_cells=4000,kernel_language='Fortran',solver_type='classic'))<2e-6

def test_sharpclaw(self):
assert abs(error(num_cells=2000,kernel_language='Fortran',solver_type='sharpclaw'))<1e-8
assert abs(error(num_cells=2000,kernel_language='Fortran',solver_type='sharpclaw',weno_order=11))<1e-8
assert abs(error(num_cells=2000,kernel_language='Fortran',solver_type='sharpclaw',time_integrator='SSPLMMk3'))<2e-8
63 changes: 22 additions & 41 deletions examples/acoustics_2d_homogeneous/test_2d_acoustics.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,30 @@
def test_2d_acoustics():
"""test_2d_acoustics"""
from . import acoustics_2d
import numpy as np
from clawpack.pyclaw.util import check_diff
import os

def verify_data(data_filename):
def verify(claw):
""" verifies 2d homogeneous acoustics from a previously verified run """
import os
import numpy as np
from clawpack.pyclaw.util import check_diff
def check_error(data_filename,**kwargs):

claw = acoustics_2d.setup(disable_output=True,**kwargs)
claw.run()

#grabs parallel results to process 0, None to other processes
test_q=claw.solution.state.get_q_global()
test_pressure = claw.frames[-1].q[0,:,:]
thisdir = os.path.dirname(__file__)
expected_pressure = np.loadtxt(os.path.join(thisdir,data_filename))
return check_diff(expected_pressure, test_pressure, reltol=1e-3,
delta=claw.solution.grid.delta)

if test_q is not None:
test_pressure = test_q[0,:,:]
thisdir = os.path.dirname(__file__)
expected_pressure = np.loadtxt(os.path.join(thisdir,data_filename))
return check_diff(expected_pressure, test_pressure, reltol=1e-3,
delta=claw.solution.grid.delta)
else:
return
return verify

from clawpack.pyclaw.util import gen_variants
from . import acoustics_2d
class TestAcoustics2D:
def test_classic(self):
assert check_error('verify_classic.txt',solver_type='classic')==None

classic_tests = gen_variants(acoustics_2d.setup, verify_data('verify_classic.txt'),
kernel_languages=('Fortran',), solver_type='classic', disable_output=True)
def test_classic_ptwise(self):
assert check_error('verify_classic.txt',solver_type='classic',ptwise=True)==None

ptwise_tests = gen_variants(acoustics_2d.setup, verify_data('verify_classic.txt'),
kernel_languages=('Fortran',), ptwise=True, solver_type='classic', disable_output=True)
def test_sharpclaw(self):
assert check_error('verify_sharpclaw.txt',solver_type='sharpclaw')==None

sharp_tests_rk = gen_variants(acoustics_2d.setup, verify_data('verify_sharpclaw.txt'),
kernel_languages=('Fortran',), solver_type='sharpclaw',
time_integrator='SSP104', disable_output=True)

sharp_tests_lmm = gen_variants(acoustics_2d.setup, verify_data('verify_sharpclaw_lmm.txt'),
kernel_languages=('Fortran',), solver_type='sharpclaw',
time_integrator='SSPLMMk2', disable_output=True)

from itertools import chain
for test in chain(classic_tests, ptwise_tests, sharp_tests_rk, sharp_tests_lmm):
yield test


if __name__=="__main__":
import nose
nose.main()
def test_sharpclaw_multistep(self):
assert check_error('verify_sharpclaw_lmm.txt',solver_type='sharpclaw',
time_integrator='SSPLMMk2')==None
51 changes: 16 additions & 35 deletions examples/acoustics_2d_mapped/test_acoustics_2d_mapped.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,21 @@
def test_acoustics_2d_variable():
"""Test variable-coefficient 2D acoustics on mapped grids"""
from . import acoustics_2d_inclusions
import numpy as np
from clawpack.pyclaw.util import check_diff
import os

import acoustics_2d_inclusions
def check_error(data_filename,**kwargs):

def verify_acoustics_inclusions(controller, solver_type='classic'):
""" Regression test against data from a previous run."""
import os
from clawpack.pyclaw.util import check_diff
import numpy as np
claw = acoustics_2d_inclusions.setup(disable_output=True,**kwargs)
claw.run()
test_pressure = claw.frames[-1].q[0,:,:]

state = controller.frames[controller.num_output_times].state
dx, dy = controller.solution.domain.grid.delta
test_q = state.get_q_global()
thisdir = os.path.dirname(__file__)
expected_pressure = np.load(os.path.join(thisdir, 'pressure.npz'))['arr_0']
test_err = np.max(np.abs(expected_pressure[:].reshape(-1) -
test_pressure[:].reshape(-1)))
return check_diff(0, test_err, abstol=1e-7)

if test_q is not None:
thisdir = os.path.dirname(__file__)
expected_pressure = np.load(os.path.join(thisdir,
'pressure.npz'))['arr_0']
test_pressure = test_q[0,:,:]
test_err = np.max(np.abs(expected_pressure[:].reshape(-1) -
test_pressure[:].reshape(-1)))
return check_diff(0, test_err, abstol=1e-7)


from clawpack.pyclaw.util import gen_variants

verify_func = lambda controller: verify_acoustics_inclusions(controller, solver_type='classic')
classic_tests = gen_variants(acoustics_2d_inclusions.setup, verify_func,
solver_type='classic', disable_output=True,
num_cells=100,num_output_times=1)

from itertools import chain
for test in chain(classic_tests):
yield test


if __name__=="__main__":
import nose
nose.main()
def test_classic():
assert check_error('verify_classic.txt',solver_type='classic',
num_cells=100,num_output_times=1)==None
71 changes: 23 additions & 48 deletions examples/acoustics_2d_variable/test_acoustics_2d_variable.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,30 @@
def test_acoustics_2d_variable():
"""Test variable-coefficient 2D acoustics"""
from . import acoustics_2d_interface
import numpy as np
from clawpack.pyclaw.util import check_diff
import os

from . import acoustics_2d_interface
def check_error(**kwargs):

def verify_acoustics(controller, solver_type='classic'):
""" Verifies 2d variable-coefficient acoustics from a previously verified classic run """
import os
from clawpack.pyclaw.util import check_diff
import numpy as np
solver_type = kwargs['solver_type']
claw = acoustics_2d_interface.setup(disable_output=True,**kwargs)
claw.run()
test_pressure = claw.frames[-1].q[0,:,:]

state = controller.frames[controller.num_output_times].state
dx, dy = controller.solution.domain.grid.delta
test_q = state.get_q_global()
thisdir = os.path.dirname(__file__)
expected_pressure = np.loadtxt(os.path.join(thisdir, 'pressure_%s.txt' % solver_type))
test_err = np.max(np.abs(expected_pressure[:].reshape(-1) -
test_pressure[:].reshape(-1)))
print(test_err)
return check_diff(0, test_err, abstol=1e-1)

if test_q is not None:
thisdir = os.path.dirname(__file__)
expected_pressure = np.loadtxt(os.path.join(thisdir,
'pressure_%s.txt' % solver_type))
test_pressure = test_q[0,:,:]
#test_err = dx*dy*np.linalg.norm(expected_pressure-test_pressure)
test_err = np.max(np.abs(expected_pressure[:].reshape(-1) -
test_pressure[:].reshape(-1)))
return check_diff(0, test_err, abstol=1e-1)

class TestAcoustics2D:
def test_classic(self):
assert check_error(solver_type='classic',num_cells=(50,50))==None

from clawpack.pyclaw.util import gen_variants
def test_sharpclaw(self):
assert check_error(solver_type='sharpclaw',num_cells=(50,50))==None

verify_func = lambda controller: verify_acoustics(controller, solver_type='classic')
classic_tests = gen_variants(acoustics_2d_interface.setup, verify_func,
solver_type='classic', disable_output=True,
num_cells=(50, 50))

verify_func = lambda controller: verify_acoustics(controller, solver_type='sharpclaw')
sharp_tests_rk = gen_variants(acoustics_2d_interface.setup,
verify_func,
solver_type='sharpclaw',
time_integrator='SSP104',
disable_output=True, num_cells=(50, 50))

sharp_tests_lmm = gen_variants(acoustics_2d_interface.setup,
verify_func, lim_type=1,
solver_type='sharpclaw',
time_integrator='SSPLMMk2',
disable_output=True,
num_cells=(50, 50))

from itertools import chain
for test in chain(classic_tests, sharp_tests_rk, sharp_tests_lmm):
yield test


if __name__=="__main__":
import nose
nose.main()
def test_sharpclaw_multistep(self):
assert check_error(solver_type='sharpclaw',num_cells=(50,50),
time_integrator='SSPLMMk2')==None
Loading

0 comments on commit 1d7ba17

Please sign in to comment.