Skip to content

Commit

Permalink
Added unit tests for Spectral Volume and interpreter option to run-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Yannick Kuhn committed Aug 18, 2020
1 parent cdb105f commit f746a5c
Show file tree
Hide file tree
Showing 3 changed files with 715 additions and 81 deletions.
146 changes: 73 additions & 73 deletions pybamm/spatial_methods/spectral_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,79 +437,79 @@ def penalty_matrix(self, domain, auxiliary_domains):

return pybamm.Matrix(matrix)

def spectral_volume_internal_neumann_condition(
self, left_symbol_disc, right_symbol_disc, left_mesh, right_mesh
):
"""
A method to find the internal neumann conditions between two
symbols on adjacent subdomains. This method is never called,
it's just here to show how a reconstructed gradient-based
internal neumann_condition would look like.
Parameters
----------
left_symbol_disc : :class:`pybamm.Symbol`
The discretised symbol on the left subdomain
right_symbol_disc : :class:`pybamm.Symbol`
The discretised symbol on the right subdomain
left_mesh : list
The mesh on the left subdomain
right_mesh : list
The mesh on the right subdomain
"""

second_dim_repeats = self._get_auxiliary_domain_repeats(
left_symbol_disc.domains
)

if second_dim_repeats != self._get_auxiliary_domain_repeats(
right_symbol_disc.domains
):
raise pybamm.DomainError(
"Number of secondary points in subdomains do not match"
)

# Use the Spectral Volume reconstruction and differentiation.
left_reconstruction_matrix = self.cv_boundary_reconstruction_matrix(
left_symbol_disc.domain,
left_symbol_disc.auxiliary_domains
)
left_gradient_matrix = self.gradient_matrix(
left_symbol_disc.domain,
left_symbol_disc.auxiliary_domains
).entries[-1]
left_matrix = left_gradient_matrix @ left_reconstruction_matrix

right_reconstruction_matrix = self.cv_boundary_reconstruction_matrix(
right_symbol_disc.domain,
right_symbol_disc.auxiliary_domains
)
right_gradient_matrix = self.gradient_matrix(
right_symbol_disc.domain,
right_symbol_disc.auxiliary_domains
).entries[0]
right_matrix = right_gradient_matrix @ right_reconstruction_matrix

# Remove domains to avoid clash
left_domain = left_symbol_disc.domain
right_domain = right_symbol_disc.domain
left_auxiliary_domains = left_symbol_disc.auxiliary_domains
right_auxiliary_domains = right_symbol_disc.auxiliary_domains
left_symbol_disc.clear_domains()
right_symbol_disc.clear_domains()

# Spectral Volume derivative (i.e., the mean of the two
# reconstructed gradients from each side)
# Note that this is the version without "penalty_matrix".
dy_dx = 0.5 * (right_matrix @ right_symbol_disc
+ left_matrix @ left_symbol_disc)

# Change domains back
left_symbol_disc.domain = left_domain
right_symbol_disc.domain = right_domain
left_symbol_disc.auxiliary_domains = left_auxiliary_domains
right_symbol_disc.auxiliary_domains = right_auxiliary_domains

return dy_dx
#def spectral_volume_internal_neumann_condition(
# self, left_symbol_disc, right_symbol_disc, left_mesh, right_mesh
#):
# """
# A method to find the internal neumann conditions between two
# symbols on adjacent subdomains. This method is never called,
# it's just here to show how a reconstructed gradient-based
# internal neumann_condition would look like.
# Parameters
# ----------
# left_symbol_disc : :class:`pybamm.Symbol`
# The discretised symbol on the left subdomain
# right_symbol_disc : :class:`pybamm.Symbol`
# The discretised symbol on the right subdomain
# left_mesh : list
# The mesh on the left subdomain
# right_mesh : list
# The mesh on the right subdomain
# """
#
# second_dim_repeats = self._get_auxiliary_domain_repeats(
# left_symbol_disc.domains
# )
#
# if second_dim_repeats != self._get_auxiliary_domain_repeats(
# right_symbol_disc.domains
# ):
# raise pybamm.DomainError(
# "Number of secondary points in subdomains do not match"
# )
#
# # Use the Spectral Volume reconstruction and differentiation.
# left_reconstruction_matrix = self.cv_boundary_reconstruction_matrix(
# left_symbol_disc.domain,
# left_symbol_disc.auxiliary_domains
# )
# left_gradient_matrix = self.gradient_matrix(
# left_symbol_disc.domain,
# left_symbol_disc.auxiliary_domains
# ).entries[-1]
# left_matrix = left_gradient_matrix @ left_reconstruction_matrix
#
# right_reconstruction_matrix = self.cv_boundary_reconstruction_matrix(
# right_symbol_disc.domain,
# right_symbol_disc.auxiliary_domains
# )
# right_gradient_matrix = self.gradient_matrix(
# right_symbol_disc.domain,
# right_symbol_disc.auxiliary_domains
# ).entries[0]
# right_matrix = right_gradient_matrix @ right_reconstruction_matrix
#
# # Remove domains to avoid clash
# left_domain = left_symbol_disc.domain
# right_domain = right_symbol_disc.domain
# left_auxiliary_domains = left_symbol_disc.auxiliary_domains
# right_auxiliary_domains = right_symbol_disc.auxiliary_domains
# left_symbol_disc.clear_domains()
# right_symbol_disc.clear_domains()
#
# # Spectral Volume derivative (i.e., the mean of the two
# # reconstructed gradients from each side)
# # Note that this is the version without "penalty_matrix".
# dy_dx = 0.5 * (right_matrix @ right_symbol_disc
# + left_matrix @ left_symbol_disc)
#
# # Change domains back
# left_symbol_disc.domain = left_domain
# right_symbol_disc.domain = right_domain
# left_symbol_disc.auxiliary_domains = left_auxiliary_domains
# right_symbol_disc.auxiliary_domains = right_auxiliary_domains
#
# return dy_dx

def replace_dirichlet_values(self, symbol, discretised_symbol, bcs):
"""
Expand Down
25 changes: 17 additions & 8 deletions run-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import subprocess


def run_code_tests(executable=False, folder: str = "unit"):
def run_code_tests(executable=False, folder: str = "unit", interpreter="python"):
"""
Runs tests, exits if they don't finish.
Parameters
Expand All @@ -35,8 +35,8 @@ def run_code_tests(executable=False, folder: str = "unit"):
suite = unittest.defaultTestLoader.discover(tests, pattern="test*.py")
unittest.TextTestRunner(verbosity=2).run(suite)
else:
print("Running {} tests with executable 'python'".format(folder))
cmd = ["python", "-m", "unittest", "discover", "-v", tests]
print("Running {} tests with executable '{}'".format(folder, interpreter))
cmd = [interpreter, "-m", "unittest", "discover", "-v", tests]
p = subprocess.Popen(cmd)
try:
ret = p.wait()
Expand Down Expand Up @@ -365,6 +365,14 @@ def export_notebook(ipath, opath):
action="store_true",
help="Run quick checks (unit tests, flake8, docs)",
)
# Non-standard Python interpreter name for subprocesses
parser.add_argument(
"--interpreter",
nargs="?",
default="python",
metavar="python",
help="Give the name of the Python interpreter if it is not 'python'",
)

# Parse!
args = parser.parse_args()
Expand All @@ -373,13 +381,14 @@ def export_notebook(ipath, opath):
has_run = False
# Unit vs integration
folder = args.folder[0]
interpreter = args.interpreter
# Unit tests
if args.unit:
has_run = True
run_code_tests(True, folder)
run_code_tests(True, folder, interpreter)
if args.nosub:
has_run = True
run_code_tests(folder=folder)
run_code_tests(folder=folder, interpreter=interpreter)
# Flake8
if args.flake8:
has_run = True
Expand All @@ -391,18 +400,18 @@ def export_notebook(ipath, opath):
# Notebook tests
if args.allexamples:
has_run = True
run_notebook_and_scripts()
run_notebook_and_scripts(executable=interpreter)
elif args.examples:
has_run = True
run_notebook_and_scripts(True)
run_notebook_and_scripts(True, interpreter)
if args.debook:
has_run = True
export_notebook(*args.debook)
# Combined test sets
if args.quick:
has_run = True
run_flake8()
run_code_tests(folder)
run_code_tests(folder, interpreter=interpreter)
run_doc_tests()
# Help
if not has_run:
Expand Down
Loading

0 comments on commit f746a5c

Please sign in to comment.