diff --git a/python/tests/test_3rd_harm_1d.py b/python/tests/test_3rd_harm_1d.py index 70d439d63..6c0b52b05 100644 --- a/python/tests/test_3rd_harm_1d.py +++ b/python/tests/test_3rd_harm_1d.py @@ -2,9 +2,9 @@ import unittest import meep as mp -from utils import VectorComparisonMixin +from utils import ApproxComparisonTestCase -class Test3rdHarm1d(VectorComparisonMixin, unittest.TestCase): +class Test3rdHarm1d(ApproxComparisonTestCase): def setUp(self): self.sz = 100 @@ -53,7 +53,7 @@ def test_3rd_harm_1d(self): harmonics = [self.k, self.amp, mp.get_fluxes(self.trans1)[0], mp.get_fluxes(self.trans3)[0]] tol = 3e-5 if mp.is_single_precision() else 1e-7 - self.assertVectorsClose(expected_harmonics, harmonics, epsilon=tol) + self.assertClose(expected_harmonics, harmonics, epsilon=tol) if __name__ == '__main__': diff --git a/python/tests/test_adjoint_jax.py b/python/tests/test_adjoint_jax.py index 6a6c4ab49..346946b13 100644 --- a/python/tests/test_adjoint_jax.py +++ b/python/tests/test_adjoint_jax.py @@ -1,7 +1,7 @@ import unittest import parameterized -from utils import VectorComparisonMixin +from utils import ApproxComparisonTestCase import jax import jax.numpy as jnp @@ -166,7 +166,7 @@ def test_design_region_monitor_helpers(self): self.assertEqual(value.dtype, onp.complex128) -class WrapperTest(VectorComparisonMixin, unittest.TestCase): +class WrapperTest(ApproxComparisonTestCase): @parameterized.parameterized.expand([ ('1500_1550bw_01relative_gaussian', onp.linspace(1 / 1.50, 1 / 1.55, 3).tolist(), 0.1, 1.0), @@ -237,7 +237,7 @@ def loss_fn(x): fd_projection = onp.stack(fd_projection) # Check that dp . ∇T ~ T(p + dp) - T(p) - self.assertVectorsClose( + self.assertClose( projection, fd_projection, epsilon=_TOL, diff --git a/python/tests/test_adjoint_solver.py b/python/tests/test_adjoint_solver.py index 227aab136..b8bb7d44c 100644 --- a/python/tests/test_adjoint_solver.py +++ b/python/tests/test_adjoint_solver.py @@ -8,7 +8,7 @@ from autograd import tensor_jacobian_product import unittest from enum import Enum -from utils import VectorComparisonMixin +from utils import ApproxComparisonTestCase MonitorObject = Enum('MonitorObject', 'EIGENMODE DFT') @@ -173,7 +173,7 @@ def mapping(x,filter_radius,eta,beta): return projected_field.flatten() -class TestAdjointSolver(VectorComparisonMixin, unittest.TestCase): +class TestAdjointSolver(ApproxComparisonTestCase): def test_adjoint_solver_DFT_fields(self): print("*** TESTING DFT ADJOINT FEATURES ***") @@ -187,7 +187,7 @@ def test_adjoint_solver_DFT_fields(self): ## compare objective results print("|Ez|^2 -- adjoint solver: {}, traditional simulation: {}".format(adjsol_obj,S12_unperturbed)) - self.assertVectorsClose(adjsol_obj,S12_unperturbed,epsilon=1e-3) + self.assertClose(adjsol_obj,S12_unperturbed,epsilon=1e-3) ## compute perturbed S12 S12_perturbed = forward_simulation(p+dp, MonitorObject.DFT, frequencies) @@ -199,7 +199,7 @@ def test_adjoint_solver_DFT_fields(self): fd_grad = S12_perturbed-S12_unperturbed print("Directional derivative -- adjoint solver: {}, FD: {}".format(adj_scale,fd_grad)) tol = 0.3 if mp.is_single_precision() else 0.01 - self.assertVectorsClose(adj_scale,fd_grad,epsilon=tol) + self.assertClose(adj_scale,fd_grad,epsilon=tol) def test_adjoint_solver_eigenmode(self): @@ -215,7 +215,7 @@ def test_adjoint_solver_eigenmode(self): ## compare objective results print("S12 -- adjoint solver: {}, traditional simulation: {}".format(adjsol_obj,S12_unperturbed)) - self.assertVectorsClose(adjsol_obj,S12_unperturbed,epsilon=1e-3) + self.assertClose(adjsol_obj,S12_unperturbed,epsilon=1e-3) ## compute perturbed S12 S12_perturbed = forward_simulation(p+dp, MonitorObject.EIGENMODE, frequencies, use_complex) @@ -227,7 +227,7 @@ def test_adjoint_solver_eigenmode(self): fd_grad = S12_perturbed-S12_unperturbed print("Directional derivative -- adjoint solver: {}, FD: {}".format(adj_scale,fd_grad)) tol = 0.1 if mp.is_single_precision() else 0.03 - self.assertVectorsClose(adj_scale,fd_grad,epsilon=tol) + self.assertClose(adj_scale,fd_grad,epsilon=tol) def test_gradient_backpropagation(self): @@ -257,7 +257,7 @@ def test_gradient_backpropagation(self): ## compare objective results print("S12 -- adjoint solver: {}, traditional simulation: {}".format(adjsol_obj,S12_unperturbed)) tol = 1e-2 if mp.is_single_precision() else 1e-3 - self.assertVectorsClose(adjsol_obj,S12_unperturbed,epsilon=tol) + self.assertClose(adjsol_obj,S12_unperturbed,epsilon=tol) ## compute perturbed S12 S12_perturbed = forward_simulation(mapping(p+dp,filter_radius,eta,beta), MonitorObject.EIGENMODE,frequencies) @@ -268,7 +268,7 @@ def test_gradient_backpropagation(self): fd_grad = S12_perturbed-S12_unperturbed print("Directional derivative -- adjoint solver: {}, FD: {}".format(adj_scale,fd_grad)) tol = 0.04 if mp.is_single_precision() else 0.03 - self.assertVectorsClose(adj_scale,fd_grad,epsilon=tol) + self.assertClose(adj_scale,fd_grad,epsilon=tol) if __name__ == '__main__': diff --git a/python/tests/test_cavity_arrayslice.py b/python/tests/test_cavity_arrayslice.py index a8c9b5271..bbedbebe6 100644 --- a/python/tests/test_cavity_arrayslice.py +++ b/python/tests/test_cavity_arrayslice.py @@ -1,11 +1,11 @@ import meep as mp -from utils import VectorComparisonMixin +from utils import ApproxComparisonTestCase import os import unittest import numpy as np -class TestCavityArraySlice(VectorComparisonMixin, unittest.TestCase): +class TestCavityArraySlice(ApproxComparisonTestCase): data_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'data')) expected_1d = np.load(os.path.join(data_dir, 'cavity_arrayslice_1d.npy')) @@ -59,14 +59,14 @@ def test_1d_slice(self): vol = mp.Volume(center=self.center_1d, size=self.size_1d) hl_slice1d = self.sim.get_array(mp.Hz, vol) tol = 1e-5 if mp.is_single_precision() else 1e-8 - self.assertVectorsClose(self.expected_1d, hl_slice1d, epsilon=tol) + self.assertClose(self.expected_1d, hl_slice1d, epsilon=tol) def test_2d_slice(self): self.sim.run(until_after_sources=0) vol = mp.Volume(center=self.center_2d, size=self.size_2d) hl_slice2d = self.sim.get_array(mp.Hz, vol) tol = 1e-5 if mp.is_single_precision() else 1e-8 - self.assertVectorsClose(self.expected_2d, hl_slice2d, epsilon=tol) + self.assertClose(self.expected_2d, hl_slice2d, epsilon=tol) def test_1d_slice_user_array(self): self.sim.run(until_after_sources=0) @@ -74,7 +74,7 @@ def test_1d_slice_user_array(self): vol = mp.Volume(center=self.center_1d, size=self.size_1d) self.sim.get_array(mp.Hz, vol, arr=arr) tol = 1e-5 if mp.is_single_precision() else 1e-8 - self.assertVectorsClose(self.expected_1d, arr, epsilon=tol) + self.assertClose(self.expected_1d, arr, epsilon=tol) def test_2d_slice_user_array(self): self.sim.run(until_after_sources=0) @@ -82,7 +82,7 @@ def test_2d_slice_user_array(self): vol = mp.Volume(center=self.center_2d, size=self.size_2d) self.sim.get_array(mp.Hz, vol, arr=arr) tol = 1e-5 if mp.is_single_precision() else 1e-8 - self.assertVectorsClose(self.expected_2d, arr, epsilon=tol) + self.assertClose(self.expected_2d, arr, epsilon=tol) def test_illegal_user_array(self): self.sim.run(until_after_sources=0) diff --git a/python/tests/test_cavity_farfield.py b/python/tests/test_cavity_farfield.py index 05c1e2214..861831c94 100644 --- a/python/tests/test_cavity_farfield.py +++ b/python/tests/test_cavity_farfield.py @@ -1,11 +1,11 @@ import meep as mp -from utils import VectorComparisonMixin +from utils import ApproxComparisonTestCase import os import unittest import h5py -class TestCavityFarfield(VectorComparisonMixin, unittest.TestCase): +class TestCavityFarfield(ApproxComparisonTestCase): data_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'data')) @@ -76,12 +76,12 @@ def run_test(self, nfreqs): ref_hz = mp.complexarray(f['hz.r'][()], f['hz.i'][()]) tol = 1e-5 if mp.is_single_precision() else 1e-7 - self.assertVectorsClose(ref_ex, result['Ex'], epsilon=tol) - self.assertVectorsClose(ref_ey, result['Ey'], epsilon=tol) - self.assertVectorsClose(ref_ez, result['Ez'], epsilon=tol) - self.assertVectorsClose(ref_hx, result['Hx'], epsilon=tol) - self.assertVectorsClose(ref_hy, result['Hy'], epsilon=tol) - self.assertVectorsClose(ref_hz, result['Hz'], epsilon=tol) + self.assertClose(ref_ex, result['Ex'], epsilon=tol) + self.assertClose(ref_ey, result['Ey'], epsilon=tol) + self.assertClose(ref_ez, result['Ez'], epsilon=tol) + self.assertClose(ref_hx, result['Hx'], epsilon=tol) + self.assertClose(ref_hy, result['Hy'], epsilon=tol) + self.assertClose(ref_hz, result['Hz'], epsilon=tol) def test_cavity_farfield(self): diff --git a/python/tests/test_dispersive_eigenmode.py b/python/tests/test_dispersive_eigenmode.py index 0a56b815a..5fce1d96d 100644 --- a/python/tests/test_dispersive_eigenmode.py +++ b/python/tests/test_dispersive_eigenmode.py @@ -1,19 +1,19 @@ # dispersive_eigenmode.py - Tests the meep eigenmode features (eigenmode source, # eigenmode decomposition, and get_eigenmode) with dispersive materials. -# TODO: +# TODO: # * check materials with off diagonal components # * check magnetic profiles # * once imaginary component is supported, check that import meep as mp -from utils import VectorComparisonMixin +from utils import ApproxComparisonTestCase import unittest import numpy as np import h5py import os -class TestDispersiveEigenmode(VectorComparisonMixin, unittest.TestCase): +class TestDispersiveEigenmode(ApproxComparisonTestCase): # ----------------------------------------- # # ----------- Helper Functions ------------ # # ----------------------------------------- # @@ -35,7 +35,7 @@ def call_chi1(self,material,frequency): n_actual = np.real(np.sqrt(material.epsilon(frequency).astype(np.complex128))) tol = 1e-6 if mp.is_single_precision() else 1e-8 - self.assertVectorsClose(n, n_actual, epsilon=tol) + self.assertClose(n, n_actual, epsilon=tol) @classmethod def setUpClass(cls): @@ -52,7 +52,7 @@ def verify_output_and_slice(self,material,frequency): chi1inv = np.diag(chi1inv) N = chi1inv.size n = np.sqrt(N/np.sum(chi1inv)) - + sim = mp.Simulation(cell_size=mp.Vector3(2,2,2), default_material=material, resolution=20, @@ -60,7 +60,7 @@ def verify_output_and_slice(self,material,frequency): ) sim.use_output_directory(self.temp_dir) sim.init_sim() - + # Check to make sure the get_slice routine is working with frequency n_slice = np.sqrt(np.max(sim.get_epsilon(frequency=frequency,snap=True))) self.assertAlmostEqual(n,n_slice, places=4) @@ -74,17 +74,17 @@ def verify_output_and_slice(self,material,frequency): with h5py.File(filename, 'r') as f: n_h5 = np.sqrt(np.max(mp.complexarray(f['eps.r'][()],f['eps.i'][()]))) self.assertAlmostEqual(n,n_h5, places=4) - + # ----------------------------------------- # # ----------- Test Routines --------------- # # ----------------------------------------- # def test_chi1_routine(self): - # Checks the newly implemented get_chi1inv routines within the - # fields and structure classes by comparing their output to the + # Checks the newly implemented get_chi1inv routines within the + # fields and structure classes by comparing their output to the # python epsilon output. from meep.materials import Si, Ag, LiNbO3, Au - + # Check Silicon w0 = Si.valid_freq_range.min w1 = Si.valid_freq_range.max @@ -101,7 +101,7 @@ def test_chi1_routine(self): w0 = Au.valid_freq_range.min w1 = Au.valid_freq_range.max self.call_chi1(Au,w0) - self.call_chi1(Au,w1) + self.call_chi1(Au,w1) # Check Lithium Niobate (X,X) w0 = LiNbO3.valid_freq_range.min @@ -115,13 +115,13 @@ def test_chi1_routine(self): rotLiNbO3.rotate(mp.Vector3(1,1,1),np.radians(34)) self.call_chi1(rotLiNbO3,w0) self.call_chi1(rotLiNbO3,w1) - + def test_get_with_dispersion(self): # Checks the get_array_slice and output_fields method # with dispersive materials. from meep.materials import Si, Ag, LiNbO3, Au - + # Check Silicon w0 = Si.valid_freq_range.min w1 = Si.valid_freq_range.max @@ -138,7 +138,7 @@ def test_get_with_dispersion(self): w0 = Au.valid_freq_range.min w1 = Au.valid_freq_range.max self.verify_output_and_slice(Au,w0) - self.verify_output_and_slice(Au,w1) + self.verify_output_and_slice(Au,w1) # Check Lithium Niobate w0 = LiNbO3.valid_freq_range.min @@ -152,7 +152,7 @@ def test_get_with_dispersion(self): rotLiNbO3.rotate(mp.Vector3(1,1,1),np.radians(34)) self.verify_output_and_slice(rotLiNbO3,w0) self.verify_output_and_slice(rotLiNbO3,w1) - + if __name__ == '__main__': unittest.main() diff --git a/python/tests/test_holey_wvg_cavity.py b/python/tests/test_holey_wvg_cavity.py index 1f7cd2fc0..5b486273f 100644 --- a/python/tests/test_holey_wvg_cavity.py +++ b/python/tests/test_holey_wvg_cavity.py @@ -1,9 +1,9 @@ import meep as mp -from utils import VectorComparisonMixin +from utils import ApproxComparisonTestCase import unittest -class TestHoleyWvgCavity(VectorComparisonMixin, unittest.TestCase): +class TestHoleyWvgCavity(ApproxComparisonTestCase): def setUp(self): eps = 13 @@ -72,7 +72,7 @@ def test_resonant_modes(self): res = [m.freq, m.decay, m.Q, abs(m.amp), m.amp.real, m.amp.imag] tol = 1e-6 if mp.is_single_precision() else 1e-8 - self.assertVectorsClose(expected, res, epsilon=tol) + self.assertClose(expected, res, epsilon=tol) def test_transmission_spectrum(self): expected = [ @@ -145,7 +145,7 @@ def test_transmission_spectrum(self): tol = 1e-8 if mp.is_single_precision() else 1e-10 for e, r in zip(expected, res): - self.assertVectorsClose(e, r, epsilon=tol) + self.assertClose(e, r, epsilon=tol) diff --git a/python/tests/test_refl_angular.py b/python/tests/test_refl_angular.py index 15ad269e6..89acd03a4 100644 --- a/python/tests/test_refl_angular.py +++ b/python/tests/test_refl_angular.py @@ -1,11 +1,11 @@ import meep as mp -from utils import VectorComparisonMixin +from utils import ApproxComparisonTestCase import math import unittest import numpy as np -class TestReflAngular(VectorComparisonMixin, unittest.TestCase): +class TestReflAngular(ApproxComparisonTestCase): def test_refl_angular(self): resolution = 100 @@ -121,7 +121,7 @@ def test_refl_angular(self): ] tol = 1e-7 if mp.is_single_precision() else 1e-8 - self.assertVectorsClose(expected, list(zip(freqs, refl_flux)), epsilon=tol) + self.assertClose(expected, list(zip(freqs, refl_flux)), epsilon=tol) if __name__ == '__main__': diff --git a/python/tests/test_ring_cyl.py b/python/tests/test_ring_cyl.py index 862801c4d..dec776920 100644 --- a/python/tests/test_ring_cyl.py +++ b/python/tests/test_ring_cyl.py @@ -2,9 +2,9 @@ import unittest import meep as mp -from utils import VectorComparisonMixin +from utils import ApproxComparisonTestCase -class TestRingCyl(VectorComparisonMixin, unittest.TestCase): +class TestRingCyl(ApproxComparisonTestCase): def setUp(self): n = 3.4 @@ -66,7 +66,7 @@ def test_ring_cyl(self): res = [m.freq, m.decay, m.Q, abs(m.amp), m.amp.real, m.amp.imag] tol = 1e-6 if mp.is_single_precision() else 1e-7 - self.assertVectorsClose(expected, res, epsilon=tol) + self.assertClose(expected, res, epsilon=tol) if __name__ == '__main__': diff --git a/python/tests/utils.py b/python/tests/utils.py index 5dfbe42c1..a249e8e26 100644 --- a/python/tests/utils.py +++ b/python/tests/utils.py @@ -15,10 +15,10 @@ def compare_arrays(test_instance, exp, res, tol=1e-3): test_instance.assertLess(diff, tol) -class VectorComparisonMixin(unittest.TestCase): +class ApproxComparisonTestCase(unittest.TestCase): """A mixin for adding proper floating point value and vector comparison.""" - def assertVectorsClose(self, x, y, epsilon = 1e-2, msg = ''): + def assertClose(self, x, y, epsilon = 1e-2, msg = ''): """Asserts that two values or vectors satisfy ‖x-y‖ ≤ ε * max(‖x‖, ‖y‖).""" x = np.atleast_1d(x).ravel() y = np.atleast_1d(y).ravel()