def test_empty_array(): "Confirm that an empty array has the expected dimensions and lookup" sim = openmodes.Simulation() name = "SRR" mesh_tol = 1e-3 sim = openmodes.Simulation(name=name) mesh = sim.load_mesh(osp.join(openmodes.geometry_dir, name+'.geo'), mesh_tol=mesh_tol) part1 = sim.place_part(mesh) part2 = sim.place_part(mesh, location=[0, 0, 5e-3]) vec = sim.empty_array() s = 2j*np.pi*1e9 Z = sim.impedance(s) pw = PlaneWaveSource([0, 1, 0], [0, 0, 1]) V = sim.source_vector(pw, 0) I = Z.solve(V) assert(vec.shape == I.shape) assert(vec.lookup == I.lookup) vec2 = sim.empty_array(part2) assert(vec2.shape == I[:, part2].shape) assert(vec2.lookup == I[:, part2].lookup)
def test_closed(): "Check whether the meshes are closed" # For each file, list whether each of the meshes it contains is closed. # There may be multiple meshes per file. # TODO: get all geometries working mesh_values = [ #('asymmetric_ring.geo', (False, False)), # ('canonical_spiral.geo', (False,)), ('circle.geo', (False, )), ('circled_cross.geo', (False, )), ('closed_ring.geo', (False, )), ('cross.geo', (False, )), ('ellipsoid.geo', (True, )), ('horseshoe_rect.geo', (True, )), ('isosceles.geo', (False, )), ('rectangle.geo', (False, )), ('single.geo', (False, )), ('sphere.geo', (True, )), ('SRR.geo', (False, )), # ('torus.geo', (True,)), # ('v_antenna.geo', (False,)), ] sim = openmodes.Simulation() for filename, closed in mesh_values: mesh = sim.load_mesh(osp.join(openmodes.geometry_dir, filename), force_tuple=True) assert all(m.closed_surface == closed_val for (m, closed_val) in zip(mesh, closed)), \ ("%s closed_surface is not %s" % (filename, closed))
def save(): name = "SRR" mesh_tol = 1e-3 sim = openmodes.Simulation(name=name) mesh = sim.load_mesh(osp.join(openmodes.geometry_dir, name+'.geo'), mesh_tol=mesh_tol) parent_part = sim.place_part() sim.place_part(mesh, parent=parent_part) sim.place_part(mesh, parent=parent_part, location=[10, 10, 10]) sim.place_part(mesh, location=[10, 10, 10]) parents_dict = {} for part in sim.parts.iter_all(): print("Original part", part) if part.parent_ref is None: parents_dict[str(part.id)] = 'None' else: parents_dict[str(part.id)] = str(part.parent_ref().id) pw = PlaneWaveSource([0, 1, 0], [0, 0, 1]) V = sim.source_vector(pw, 0) with tempfile.NamedTemporaryFile(delete=False) as output_file: file_name = output_file.name pickle.dump(V, output_file, protocol=0) return file_name, parents_dict
def test_indexing(): "Basic test for array indexing" sim = openmodes.Simulation() mesh = sim.load_mesh(osp.join(openmodes.geometry_dir, "SRR.geo")) group1 = sim.place_part() group2 = sim.place_part() srr1 = sim.place_part(mesh, parent=group1) srr2 = sim.place_part(mesh, parent=group1) srr3 = sim.place_part(mesh, parent=group2) basis = sim.basis_container[srr1] basis_len = len(basis) A = LookupArray( ((group1, sim.basis_container), (group2, sim.basis_container), 5, 3)) assert (A.shape == (2 * basis_len, basis_len, 5, 3)) A[group1, srr3] = 22.5 assert (np.all(A[srr1, :] == 22.5)) assert (np.all(A[srr2] == 22.5)) V = LookupArray((("E", "H"), (sim.parts, sim.basis_container)), dtype=np.complex128) V["E", group1] = -4.7 + 22j V["H", srr1] = 5.2 V["H", srr2] = 6.7 assert (np.all(V["E", group1] == V["E"][group1])) assert (np.all(V["E", srr1] == -4.7 + 22j)) assert (np.all(V["E", srr2].imag == 22))
def srr_pair_combined_poles(plot=False): "Cauchy integral for poles of an SRR pair considered as a single part" sim = openmodes.Simulation(basis_class=LoopStarBasis, operator_class=EfieOperator) mesh = sim.load_mesh(meshfile) srr1 = sim.place_part(mesh) srr2 = sim.place_part(mesh, location=[0, 0, 1e-3]) # calculate modes of the SRR pair contour = ExternalModeContour(-0.5e11 + 1.2e11j, overlap_axes=0.2e6) result = sim.estimate_poles(contour) refined = sim.refine_poles(result) s_estimate = result.s s_refined = refined.s if plot: plt.figure(figsize=(6, 4)) plt.plot(s_estimate.imag, s_estimate.real, 'x') plt.plot(s_refined.imag, s_refined.real, '+') contour_points = np.array([s for s, w in contour]) plt.plot(contour_points.imag, contour_points.real) plt.show() return { 'name': 'srr_pair_combined_poles', 'results': { 's': s_refined.simple_view() }, 'rtol': { 's': 1e-5 } }
def test_list_indexing(): "List mucks up LookupArrays, which is now warned about" sim = openmodes.Simulation() mesh = sim.load_mesh(osp.join(openmodes.geometry_dir, "SRR.geo")) srr1 = sim.place_part(mesh) srr2 = sim.place_part(mesh) res = LookupArray((sim.operator.unknowns, (sim.parts, sim.basis_container), ('modes', ), (srr2, sim.basis_container)), dtype=np.complex128) with pytest.warns(UserWarning): res[0, :, 0, [2]]
def test_horseshoe_modes(plot=False, skip_asserts=False, write_reference=False): "Modes of horseshoe" sim = openmodes.Simulation(name='horseshoe_modes', basis_class=openmodes.basis.LoopStarBasis) shoe = sim.load_mesh(osp.join(mesh_dir, 'horseshoe_rect.msh')) sim.place_part(shoe) s_start = 2j * np.pi * 10e9 estimates = sim.estimate_poles(s_start, modes=3, cauchy_integral=False) modes = sim.refine_poles(estimates) mode_s = modes.s mode_j = modes.vr print("Singularities found at", mode_s) if write_reference: write_1d_complex(osp.join(reference_dir, 'eigenvector_0.txt'), mode_j["J", :, 'modes', 0]) write_1d_complex(osp.join(reference_dir, 'eigenvector_1.txt'), mode_j["J", :, 'modes', 1]) write_1d_complex(osp.join(reference_dir, 'eigenvector_2.txt'), mode_j["J", :, 'modes', 2]) j_0_ref = read_1d_complex(osp.join(reference_dir, 'eigenvector_0.txt')) j_1_ref = read_1d_complex(osp.join(reference_dir, 'eigenvector_1.txt')) j_2_ref = read_1d_complex(osp.join(reference_dir, 'eigenvector_2.txt')) if not skip_asserts: assert_allclose(mode_s[0], [ -2.585729e+09 + 3.156438e+10j, -1.887518e+10 + 4.500579e+10j, -1.991163e+10 + 6.846221e+10j ], rtol=1e-3) assert_allclose_sign(mode_j["J", :, 'modes', 0], j_0_ref, rtol=1e-2) assert_allclose_sign(mode_j["J", :, 'modes', 1], j_1_ref, rtol=1e-2) assert_allclose_sign(mode_j["J", :, 'modes', 2], j_2_ref, rtol=1e-2) if plot: sim.plot_3d(solution=mode_j["J", :, 'modes', 0], output_format='mayavi', compress_scalars=3) sim.plot_3d(solution=mode_j["J", :, 'modes', 1], output_format='mayavi', compress_scalars=3) sim.plot_3d(solution=mode_j["J", :, 'modes', 2], output_format='mayavi', compress_scalars=3)
def test_extinction_all(plot_extinction=False, skip_asserts=False, write_reference=False): "Extinction of a PEC sphere with EFIE, MFIE, CFIE" tests = (("EFIE", EfieOperator, 'extinction_efie.npy'), ("MFIE", MfieOperator, 'extinction_mfie.npy'), ) for operator_name, operator_class, reference_filename in tests: sim = openmodes.Simulation(name='horseshoe_extinction', basis_class=DivRwgBasis, operator_class=operator_class) sphere = sim.load_mesh(osp.join(mesh_dir, 'sphere.msh')) sim.place_part(sphere) s = 2j*np.pi*2e9 Z = sim.impedance(s)
def test_extinction(plot_extinction=False, skip_asserts=False, write_reference=False): "Test extinction of a horseshoe" sim = openmodes.Simulation(name='horseshoe_extinction', basis_class=openmodes.basis.LoopStarBasis) shoe = sim.load_mesh(osp.join(mesh_dir, 'horseshoe_rect.msh')) sim.place_part(shoe) num_freqs = 101 freqs = np.linspace(1e8, 20e9, num_freqs) extinction = np.empty(num_freqs, np.complex128) e_inc = np.array([1, 0, 0], dtype=np.complex128) k_hat = np.array([0, 0, 1], dtype=np.complex128) pw = PlaneWaveSource(e_inc, k_hat) for freq_count, s in sim.iter_freqs(freqs): Z = sim.impedance(s) V = sim.source_vector(pw, s) extinction[freq_count] = np.vdot(V, Z.solve(V)) if write_reference: # generate the reference extinction solution write_1d_complex(osp.join(reference_dir, 'extinction.txt'), extinction) extinction_ref = read_1d_complex(osp.join(reference_dir, 'extinction.txt')) if not skip_asserts: assert_allclose(extinction, extinction_ref, rtol=1e-3) if plot_extinction: # to plot the generated and reference solutions plt.figure() plt.plot(freqs * 1e-9, extinction.real) plt.plot(freqs * 1e-9, extinction_ref.real, '--') plt.plot(freqs * 1e-9, extinction.imag) plt.plot(freqs * 1e-9, extinction_ref.imag, '--') plt.xlabel('f (GHz)') plt.show()
def test_srr_pair_combined_poles(plot_figures=False): "Cauchy integral for poles of an SRR pair considered as a single part" sim = openmodes.Simulation(basis_class=LoopStarBasis, operator_class=EfieOperator) parameters = {'inner_radius': 2.5e-3, 'outer_radius': 4e-3} mesh = sim.load_mesh(osp.join(openmodes.geometry_dir, 'SRR.geo'), parameters=parameters, mesh_tol=0.5e-3) srr1 = sim.place_part(mesh) srr2 = sim.place_part(mesh, location=[0, 0, 1e-3]) s_min = -0.5e11 - 1e9j s_max = -2e6 + 1.2e11j integration_line_i = np.array( (s_min.imag, s_max.imag, s_max.imag, s_min.imag, s_min.imag)) integration_line_r = np.array( (s_min.real, s_min.real, s_max.real, s_max.real, s_min.real)) # calculate modes of the SRR pair result = sim.estimate_poles(RectangularContour(s_min, s_max)) refined = sim.refine_poles(result) s_estimate = result.s s_refined = refined.s s_reference = [ -1.18100087e+09 + 4.30266982e+10j, -1.34656915e+07 + 4.74170628e+10j, -3.05500910e+10 + 8.60872257e+10j, -7.57094449e+08 + 9.52970974e+10j ] assert_allclose(s_refined[0], s_reference, rtol=1e-5) if plot_figures: plt.figure(figsize=(6, 4)) plt.plot(s_estimate.imag, s_estimate.real, 'x') plt.plot(s_refined.imag, s_refined.real, '+') plt.plot(integration_line_i, integration_line_r, 'r--') plt.show()
def test_srr_pair_separate_poles(plot_figures=False): "Cauchy integral for poles of an SRR pair considered as a single part" sim = openmodes.Simulation(basis_class=LoopStarBasis, operator_class=EfieOperator) parameters = {'inner_radius': 2.5e-3, 'outer_radius': 4e-3} mesh = sim.load_mesh(osp.join(openmodes.geometry_dir, 'SRR.geo'), parameters=parameters, mesh_tol=0.5e-3) srr1 = sim.place_part(mesh) srr2 = sim.place_part(mesh, location=[0, 0, 1e-3]) s_min = -0.5e11 - 1e9j s_max = -2e6 + 1.2e11j integration_line_i = np.array( (s_min.imag, s_max.imag, s_max.imag, s_min.imag, s_min.imag)) integration_line_r = np.array( (s_min.real, s_min.real, s_max.real, s_max.real, s_min.real)) # calculate modes of the SRR pair result = sim.estimate_poles(RectangularContour(s_min, s_max), parts=[srr1, srr2]) refined = sim.refine_poles(result) s_estimate = result[srr1].s s_refined = refined[srr1].s s_reference = [ -1.07078080e+09 + 4.44309178e+10j, -2.46067038e+10 + 9.46785130e+10j ] assert_allclose(s_refined[0], s_reference, rtol=1e-5) if plot_figures: plt.figure(figsize=(6, 4)) plt.plot(s_estimate.imag, s_estimate.real, 'x') plt.plot(s_refined.imag, s_refined.real, '+') plt.plot(integration_line_i, integration_line_r, 'r--') plt.show()
def test_surface_normals(plot=False, skip_asserts=False, write_reference=False): "Test the surface normals of a horseshoe mesh" sim = openmodes.Simulation() mesh = sim.load_mesh(osp.join(mesh_dir, 'horseshoe_rect.msh')) part = sim.place_part(mesh) basis = sim.basis_container[part] r, rho = basis.integration_points(mesh.nodes, triangle_centres) normals = mesh.surface_normals r = r.reshape((-1, 3)) if write_reference: write_2d_real(osp.join(reference_dir, 'surface_r.txt'), r) write_2d_real(osp.join(reference_dir, 'surface_normals.txt'), normals) r_ref = read_2d_real(osp.join(reference_dir, 'surface_r.txt')) normals_ref = read_2d_real(osp.join(reference_dir, 'surface_normals.txt')) if not skip_asserts: assert_allclose(r, r_ref) assert_allclose(normals, normals_ref) if plot: from mayavi import mlab mlab.figure() mlab.quiver3d(r[:, 0], r[:, 1], r[:, 2], normals[:, 0], normals[:, 1], normals[:, 2], mode='cone') mlab.view(distance='auto') mlab.show()
def discard_ref(): sim = openmodes.Simulation(name=name) mesh = sim.load_mesh(osp.join(openmodes.geometry_dir, name+'.geo'), mesh_tol=mesh_tol) part = sim.place_part(mesh) return weakref.ref(part)
def test_extinction_all(plot_extinction=False, skip_asserts=False, write_reference=False): "Extinction of a PEC sphere with EFIE, MFIE, CFIE" tests = (("EFIE", EfieOperator, 'extinction_efie.npy'), ("MFIE", MfieOperator, 'extinction_mfie.npy'), ("CFIE", CfieOperator, 'extinction_cfie.npy')) for operator_name, operator_class, reference_filename in tests: sim = openmodes.Simulation(name='horseshoe_extinction', basis_class=DivRwgBasis, operator_class=operator_class) radius = 5e-3 sphere = sim.load_mesh(osp.join(mesh_dir, 'sphere.msh')) sim.place_part(sphere) num_freqs = 101 freqs = np.linspace(1e8, 20e9, num_freqs) extinction = np.empty(num_freqs, np.complex128) e_inc = np.array([1, 0, 0], dtype=np.complex128) k_hat = np.array([0, 0, 1], dtype=np.complex128) pw = PlaneWaveSource(e_inc, k_hat) for freq_count, s in sim.iter_freqs(freqs): Z = sim.impedance(s) V = sim.source_vector(pw, s) V_E = sim.source_vector(pw, s, extinction_field=True) extinction[freq_count] = np.vdot(V_E, Z.solve(V)) extinction_filename = osp.join(reference_dir, reference_filename) if write_reference: # generate the reference extinction solution write_1d_complex(extinction_filename, extinction) extinction_ref = read_1d_complex(extinction_filename) if not skip_asserts: assert_allclose(extinction, extinction_ref, rtol=1e-3) if plot_extinction: # to plot the generated and reference solutions # calculate analytically extinction_analytical = sphere_extinction_analytical(freqs, radius) plt.figure(figsize=(8, 6)) plt.plot(freqs*1e-9, extinction.real) plt.plot(freqs*1e-9, extinction_ref.real, '--') plt.plot(freqs*1e-9, extinction_analytical, 'x') plt.plot(freqs*1e-9, extinction.imag) plt.plot(freqs*1e-9, extinction_ref.imag, '--') plt.xlabel('f (GHz)') plt.legend(('Calculated (Re)', 'Reference (Re)', 'Analytical (Re)', 'Calculated (Im)', 'Reference (Im)'), loc='right') plt.title('Extinction with operator %s' % operator_name) plt.ylim(ymin=0) plt.show()
def pec_sphere_multipoles(plot=False): "Multipole expansion of a PEC sphere" sim = openmodes.Simulation(name='pec_sphere_multipoles') mesh = sim.load_mesh(meshfile) sim.place_part(mesh) k0r = np.linspace(0.1, 3, 50) freqs = k0r * c / (2 * np.pi) pw = PlaneWaveSource([1, 0, 0], [0, 0, 1], p_inc=1.0) multipole_order = 4 extinction = np.empty(len(freqs), dtype=np.complex128) a_e = {} a_m = {} for l in range(multipole_order + 1): for m in range(-l, l + 1): a_e[l, m] = np.empty(len(freqs), dtype=np.complex128) a_m[l, m] = np.empty(len(freqs), dtype=np.complex128) for freq_count, s in sim.iter_freqs(freqs): Z = sim.impedance(s) V = sim.source_vector(pw, s) V_E = sim.source_vector(pw, s, extinction_field=True) I = Z.solve(V) extinction[freq_count] = np.vdot(V_E, I) a_en, a_mn = sim.multipole_decomposition(I, multipole_order, s) for l in range(multipole_order + 1): for m in range(-l, l + 1): a_e[l, m][freq_count] = a_en[l, m] a_m[l, m][freq_count] = a_mn[l, m] if plot: plt.figure() plt.plot(k0r, extinction.real) plt.plot( k0r, np.pi / k0r**2 * sum( sum((np.abs(a_e[l, m])**2 + np.abs(a_m[l, m])**2) for m in range(-l, l + 1)) for l in range(1, multipole_order + 1)), 'x') plt.plot( k0r, np.pi / k0r**2 * sum( sum( np.sqrt(2 * l + 1) * (-m * a_e[l, m].real - a_m[l, m].real) for m in range(-l, l + 1)) for l in range(1, multipole_order + 1)), '+') plt.xlabel('$k_{0}r$') plt.title("Total extinction vs multipole extinction and scattering") plt.show() plt.figure() for l in range(1, multipole_order + 1): for m in range(-l, l + 1): plt.plot(k0r, np.pi / k0r**2 * np.abs(a_e[l, m])**2) plt.plot(k0r, np.pi / k0r**2 * np.abs(a_m[l, m])**2, '--') plt.title("Multipole contributions to scattering") plt.xlabel('$k_{0}r$') plt.show() plt.figure() for l in range(1, multipole_order + 1): for m in (-1, 1): plt.plot( k0r, -np.pi / k0r**2 * np.sqrt(2 * l + 1) * m * a_e[l, m].real) plt.plot(k0r, -np.pi / k0r**2 * np.sqrt(2 * l + 1) * a_m[l, m].real, '--') plt.title("Multipole contributions to extinction") plt.xlabel('$k_{0}r$') plt.show() else: return { 'name': 'pec_sphere_multipoles', 'results': { 'k0r': k0r, 'extinction': extinction, 'a_e': a_e, 'a_m': a_m }, 'rtol': { 'a_e': 1e-6, 'a_m': 1e-6 } }
def horseshoe_extinction_modes(): sim = openmodes.Simulation(name='horseshoe_extinction_modes', basis_class=openmodes.basis.LoopStarBasis) shoe = sim.load_mesh( osp.join('input', 'test_horseshoe', 'horseshoe_rect.msh')) sim.place_part(shoe) s_start = 2j * np.pi * 10e9 num_modes = 5 mode_s, mode_j = sim.part_singularities(s_start, num_modes) models = sim.construct_models(mode_s, mode_j)[0] num_freqs = 101 freqs = np.linspace(1e8, 20e9, num_freqs) extinction = np.empty(num_freqs, np.complex128) extinction_sem = np.empty((num_freqs, num_modes), np.complex128) extinction_eem = np.empty((num_freqs, num_modes), np.complex128) e_inc = np.array([1, 0, 0], dtype=np.complex128) k_hat = np.array([0, 0, 1], dtype=np.complex128) z_sem = np.empty((num_freqs, num_modes), np.complex128) z_eem = np.empty((num_freqs, num_modes), np.complex128) z_eem_direct = np.empty((num_freqs, num_modes), np.complex128) for freq_count, s in sim.iter_freqs(freqs): Z = sim.impedance(s)[0][0] V = sim.source_plane_wave(e_inc, s / c * k_hat)[0] extinction[freq_count] = np.vdot(V, la.solve(Z[:], V)) z_sem[freq_count] = [model.scalar_impedance(s) for model in models] extinction_sem[freq_count] = [ np.vdot(V, model.solve(s, V)) for model in models ] z_eem_direct[freq_count], _ = Z.eigenmodes(num_modes, use_gram=False) z_eem[freq_count], j_eem = Z.eigenmodes(start_j=mode_j[0], use_gram=True) extinction_eem[freq_count] = [ np.vdot(V, j_eem[:, mode]) * np.dot(V, j_eem[:, mode]) / z_eem[freq_count, mode] for mode in range(num_modes) ] plt.figure(figsize=(10, 5)) plt.subplot(121) plt.plot(freqs * 1e-9, extinction.real) plt.plot(freqs * 1e-9, np.sum(extinction_sem.real, axis=1), '--') plt.plot(freqs * 1e-9, np.sum(extinction_eem.real, axis=1), '-.') plt.xlabel('f (GHz)') plt.subplot(122) plt.plot(freqs * 1e-9, extinction.imag) plt.plot(freqs * 1e-9, np.sum(extinction_sem.imag, axis=1), '--') plt.plot(freqs * 1e-9, np.sum(extinction_eem.imag, axis=1), '-.') plt.suptitle("Extinction") plt.show() plt.figure(figsize=(10, 5)) plt.subplot(121) plt.plot(freqs * 1e-9, z_eem_direct.real) #plt.ylim(0, 80) plt.xlabel('f (GHz)') plt.subplot(122) plt.plot(freqs * 1e-9, z_eem_direct.imag) plt.plot([freqs[0] * 1e-9, freqs[-1] * 1e-9], [0, 0], 'k') plt.suptitle("EEM impedance without Gram matrix") plt.show() plt.figure(figsize=(10, 5)) plt.subplot(121) plt.plot(freqs * 1e-9, z_eem.real) plt.plot(freqs * 1e-9, z_sem.real, '--') #plt.ylim(0, 80) plt.xlabel('f (GHz)') plt.subplot(122) plt.plot(freqs * 1e-9, z_eem.imag) plt.plot(freqs * 1e-9, z_sem.imag, '--') plt.ylim(-100, 100) # plt.semilogy(freqs*1e-9, abs(z_eem.imag)) # plt.semilogy(freqs*1e-9, abs(z_sem.imag), '--') plt.suptitle("SEM and EEM impedance") plt.show() y_sem = 1 / z_sem y_eem = 1 / z_eem plt.figure(figsize=(10, 5)) plt.subplot(121) plt.plot(freqs * 1e-9, y_eem.real) plt.plot(freqs * 1e-9, y_sem.real, '--') plt.xlabel('f (GHz)') plt.subplot(122) plt.plot(freqs * 1e-9, y_eem.imag) plt.plot(freqs * 1e-9, y_sem.imag, '--') plt.xlabel('f (GHz)') plt.suptitle("SEM and EEM admittance") plt.show()
def geometry_extinction_modes(name, freqs, num_modes, mesh_tol, plot_currents=False, plot_admittance=True, parameters={}, model_class=ScalarModelLeastSq): """Load a geometry file, calculate its modes by searching for singularities, and plot them in 3D. Then use the modes to calculate extinction, and compare with exact calculation """ sim = openmodes.Simulation(name=name, basis_class=openmodes.basis.LoopStarBasis) mesh = sim.load_mesh(osp.join(openmodes.geometry_dir, name+'.geo'), mesh_tol=mesh_tol, parameters=parameters) part = sim.place_part(mesh) s_start = 2j*np.pi*0.5*(freqs[0]+freqs[-1]) mode_s, mode_j = sim.singularities(s_start, num_modes, part) if plot_currents: for mode in range(num_modes): current = sim.empty_vector() current[:] = mode_j[:, mode] sim.plot_3d(solution=current, output_format='mayavi', compress_scalars=1) if not plot_admittance: return models = sim.construct_models(mode_s, mode_j, part, model_class=model_class) num_freqs = len(freqs) extinction = np.empty(num_freqs, np.complex128) extinction_sem = np.empty((num_freqs, num_modes), np.complex128) extinction_eem = np.empty((num_freqs, num_modes), np.complex128) e_inc = np.array([1, 1, 0], dtype=np.complex128)/np.sqrt(2) k_hat = np.array([0, 0, 1], dtype=np.complex128) pw = PlaneWaveSource(e_inc, k_hat) z_sem = np.empty((num_freqs, num_modes), np.complex128) z_eem = np.empty((num_freqs, num_modes), np.complex128) # z_eem_direct = np.empty((num_freqs, num_modes), np.complex128) for freq_count, s in sim.iter_freqs(freqs): Z = sim.impedance(s) V = sim.source_vector(pw, s) I = Z.solve(V) extinction[freq_count] = np.vdot(V[part], I) z_sem[freq_count] = [model.scalar_impedance(s) for model in models] extinction_sem[freq_count] = [np.vdot(V, model.solve(s, V)) for model in models] # z_eem_direct[freq_count], _ = Z.eigenmodes(num_modes, use_gram=False) z_eem[freq_count], j_eem = Z.eigenmodes(start_j=mode_j, use_gram=True) extinction_eem[freq_count] = [np.vdot(V, j_eem[:, mode]) * V.dot(j_eem[:, mode]) / z_eem[freq_count, mode] for mode in range(num_modes)] plt.figure(figsize=(10, 5)) plt.subplot(121) plt.plot(freqs*1e-9, extinction.real) plt.plot(freqs*1e-9, np.sum(extinction_sem.real, axis=1), '--') #plt.plot(freqs*1e-9, np.sum(extinction_eem.real, axis=1), '-.') plt.xlabel('f (GHz)') plt.subplot(122) plt.plot(freqs*1e-9, extinction.imag) plt.plot(freqs*1e-9, np.sum(extinction_sem.imag, axis=1), '--') #plt.plot(freqs*1e-9, np.sum(extinction_eem.imag, axis=1), '-.') plt.suptitle("Extinction") plt.show() # plt.figure(figsize=(10,5)) # plt.subplot(121) # plt.plot(freqs*1e-9, z_eem_direct.real) # #plt.ylim(0, 80) # plt.xlabel('f (GHz)') # plt.subplot(122) # plt.plot(freqs*1e-9, z_eem_direct.imag) # plt.plot([freqs[0]*1e-9, freqs[-1]*1e-9], [0, 0], 'k') # plt.suptitle("EEM impedance without Gram matrix") # plt.show() y_sem = 1/z_sem y_eem = 1/z_eem z_sem *= 2j*np.pi*freqs[:, None] z_eem *= 2j*np.pi*freqs[:, None] plt.figure(figsize=(10, 5)) plt.subplot(121) plt.plot(freqs*1e-9, z_eem.real) plt.plot(freqs*1e-9, z_sem.real, '--') plt.xlabel('f (GHz)') plt.subplot(122) plt.plot(freqs*1e-9, z_eem.imag) plt.plot(freqs*1e-9, z_sem.imag, '--') plt.suptitle("SEM and EEM impedance") plt.show() plt.figure(figsize=(10, 5)) plt.subplot(121) plt.plot(freqs*1e-9, y_eem.real) plt.plot(freqs*1e-9, y_sem.real, '--') plt.xlabel('f (GHz)') plt.subplot(122) plt.plot(freqs*1e-9, y_eem.imag) plt.plot(freqs*1e-9, y_sem.imag, '--') plt.xlabel('f (GHz)') plt.suptitle("SEM and EEM admittance") plt.show()