def cs_vs_wl(wavelength): geom = create_geometry(wavelength, pml_width=wavelength) pw = PlaneWave(wavelength=wavelength, angle=0, dim=2, domain=geom.mesh, degree=2) omega = 2 * np.pi * c / (wavelength * 1e-9) epsilon = dict(box=1, core=2, shell=epsilon_silver(omega)) s = Scattering( geom, epsilon, mu, pw, degree=2, polarization="TE", ) s.solve() cs = s.get_cross_sections() return cs["absorption"], cs
def test_simple(pmesh=10): polarization = "TM" degree = 2 wavelength = 0.3 options = { "General.NumThreads": 0, "Mesh.Algorithm": 6, "General.Verbosity": 2 } geom = BoxPML( dim=2, box_size=(4 * wavelength, 4 * wavelength), pml_width=(wavelength, wavelength), options=options, ) cyl = geom.add_circle(0, 0, 0, 0.2) cyl, box = geom.fragment(cyl, geom.box) geom.add_physical(box, "box") geom.add_physical(cyl, "cyl") geom.set_size("box", wavelength / pmesh) geom.set_size("cyl", wavelength / pmesh) t = -time.time() geom.build() t += time.time() print(f"mesh time: {t:.3f}s") epsilon = dict(box=1, cyl=3) mu = dict(box=1, cyl=1) pw = PlaneWave(wavelength=wavelength, angle=0, dim=2, domain=geom.mesh, degree=degree) s = Scattering(geom, epsilon, mu, pw, degree=degree, polarization=polarization) u = s.solve() list_time()
def test_grating3d(degree=1): dolfin.parameters["form_compiler"]["quadrature_degree"] = 2 ## ---------- incident wave ---------- p = 1000 lambda0 = p * 3 theta0 = 0 * np.pi / 180 phi0 = 0 * np.pi / 180 psi0 = 0 * np.pi / 180 ## ---------- geometry ---------- period = (p, p) grooove_thickness = p / 20 hole_radius = p / 4 thicknesses = OrderedDict({ "pml_bottom": lambda0, "substrate": lambda0 / 1, "groove": grooove_thickness, "superstrate": lambda0 / 1, "pml_top": lambda0, }) ## ---------- mesh ---------- parmesh = 4 parmesh_hole = parmesh * 1 parmesh_groove = parmesh parmesh_pml = parmesh * 2 / 3 mesh_params = dict({ "pml_bottom": parmesh_pml, "substrate": parmesh, "groove": parmesh_groove * 2, "hole": parmesh_hole * 2, "superstrate": parmesh, "pml_top": parmesh_pml, }) ## ---------- materials ---------- eps_groove = (1.75 - 1.5j)**2 eps_hole = 1 eps_substrate = 1.5**2 epsilon = dict({ "substrate": eps_substrate, "groove": eps_groove, "hole": eps_hole, "superstrate": 1, }) mu = dict({"substrate": 1, "groove": 1, "hole": 1, "superstrate": 1}) index = dict() for e, m in zip(epsilon.items(), mu.items()): index[e[0]] = np.mean( (np.array(e[1]).real.max() * np.array(m[1]).real.max())**0.5).real ## ---------- build geometry ---------- geom = Layered3D(period, thicknesses, finalize=False) groove = geom.layers["groove"] substrate = geom.layers["substrate"] superstrate = geom.layers["superstrate"] z0 = geom.z_position["groove"] hole = geom.add_cylinder( 0, 0, z0, 0, 0, z0 + grooove_thickness, hole_radius, ) superstrate, substrate, hole, groove = geom.fragment( [superstrate, substrate, groove], hole) # hole, groove = geom.fragment(hole, groove) geom.add_physical(groove, "groove") geom.add_physical(hole, "hole") geom.add_physical(substrate, "substrate") geom.add_physical(superstrate, "superstrate") index["pml_top"] = index["substrate"] index["pml_bottom"] = index["substrate"] pmesh = { k: lambda0 / (index[k] * mesh_params[k]) for k, p in mesh_params.items() } geom.set_mesh_size(pmesh) mesh_object = geom.build() pw = PlaneWave( wavelength=lambda0, angle=(np.pi / 2, 0, 0), dim=3, domain=geom.mesh, degree=degree, ) bcs = {} s = Grating3D( geom, epsilon, mu, pw, boundary_conditions=bcs, degree=degree, periodic_map_tol=1e-6, ) s.solve() list_time() print(" >> computing diffraction efficiencies") print("---------------------------------------") effs = s.diffraction_efficiencies(2, subdomain_absorption=True, orders=True) # effs = s.diffraction_efficiencies(2, subdomain_absorption=False, orders=True) pprint(effs) R = np.sum(effs["R"]) T = np.sum(effs["T"]) Q = sum([q for t in effs["Q"].values() for q in t.values()]) print("ΣR = ", R) print("ΣT = ", T) print("ΣQ = ", Q) print("B = ", effs["B"]) list_time()
geom.add_physical(shell, "shell") [geom.set_size(pml, lmin * 1) for pml in geom.pmls] geom.set_size("box", lmin) geom.set_size("core", 0.5 * lmin / ncore) geom.set_size("shell", 0.5 * lmin / nAg) geom.build() return geom geom = create_geometry(wavelength, pml_width=wavelength) ############################################################################## # Define the incident plane wave and materials pw = PlaneWave(wavelength=wavelength, angle=0, dim=2, domain=geom.mesh, degree=2) omega = 2 * np.pi * c / (wavelength * 1e-9) epsilon = dict(box=1, core=eps_core, shell=epsilon_silver(omega)) mu = dict(box=1, core=1, shell=1) ############################################################################## # Scattering problem s = Scattering( geom, epsilon, mu, pw, degree=2, polarization="TE",
def test_maxwell2d(): degree = 2 wavelength = 0.3 pmesh = 8 lmin = wavelength / pmesh geom = BoxPML( dim=2, box_size=(4 * wavelength, 4 * wavelength), pml_width=(wavelength, wavelength), ) cyl = geom.add_circle(0, 0, 0, 0.2) cyl, box = geom.fragment(cyl, geom.box) geom.add_physical(box, "box") geom.add_physical(cyl, "cyl") [geom.set_size(pml, lmin) for pml in geom.pmls] geom.set_size("box", lmin) geom.set_size("cyl", lmin) geom.build() mesh = geom.mesh_object["mesh"] markers = geom.mesh_object["markers"]["triangle"] mapping = geom.subdomains["surfaces"] epsilon = dict(box=1, cyl=3) mu = dict(box=1, cyl=1) stretch = 1 - 1j pmlx = PML("x", stretch=stretch, matched_domain="box", applied_domain="pmlx") pmly = PML("y", stretch=stretch, matched_domain="box", applied_domain="pmly") pmlxy = PML("xy", stretch=stretch, matched_domain="box", applied_domain="pmlxy") epsilon_coeff = Coefficient(epsilon, geometry=geom, pmls=[pmlx, pmly, pmlxy]) mu_coeff = Coefficient(mu, geometry=geom, pmls=[pmlx, pmly, pmlxy]) coefficients = epsilon_coeff, mu_coeff V = ComplexFunctionSpace(mesh, "CG", degree) pw = PlaneWave(wavelength=wavelength, angle=0, dim=2, domain=mesh, degree=degree) bcs = {} m = Maxwell2D( geom, coefficients, V, source=pw, boundary_conditions=bcs, source_domains="cyl", reference="box", ) ########################### geom = BoxPML( dim=2, box_size=(4 * wavelength, 4 * wavelength), pml_width=(wavelength, wavelength), ) cyl = geom.add_circle(0, 0, 0, 0.2) box = geom.cut(geom.box, cyl) geom.add_physical(box, "box") cyl_bnds = geom.get_boundaries("box")[-1] geom.add_physical(cyl_bnds, "cyl_bnds", dim=1) [geom.set_size(pml, lmin) for pml in geom.pmls] geom.set_size("box", lmin) geom.build(0) mesh = geom.mesh_object["mesh"] markers = geom.mesh_object["markers"]["triangle"] mapping = geom.subdomains["surfaces"] epsilon = dict(box=1, cyl=3) mu = dict(box=1, cyl=1) stretch = 1 - 1j pmlx = PML("x", stretch=stretch, matched_domain="box", applied_domain="pmlx") pmly = PML("y", stretch=stretch, matched_domain="box", applied_domain="pmly") pmlxy = PML("xy", stretch=stretch, matched_domain="box", applied_domain="pmlxy") epsilon_coeff = Coefficient(epsilon, geometry=geom, pmls=[pmlx, pmly, pmlxy]) mu_coeff = Coefficient(mu, geometry=geom, pmls=[pmlx, pmly, pmlxy]) coefficients = epsilon_coeff, mu_coeff function_space = ComplexFunctionSpace(mesh, "CG", degree) pw = PlaneWave(wavelength=wavelength, angle=0, dim=2, domain=mesh, degree=degree) bcs = {"cyl_bnds": "PEC"} maxwell = Maxwell2D( geom, coefficients, function_space, source=pw, boundary_conditions=bcs, source_domains="cyl", reference="box", ) maxwell.build_boundary_conditions()
stretch = 1 - 1j pml_top = PML("y", stretch=stretch, matched_domain="superstrate", applied_domain="pml_top") pml_bottom = PML("y", stretch=stretch, matched_domain="substrate", applied_domain="pml_bottom") epsilon_coeff = Coefficient(epsilon, geometry=geom, pmls=[pml_top, pml_bottom]) mu_coeff = Coefficient(mu, geometry=geom, pmls=[pml_top, pml_bottom]) coefficients = epsilon_coeff, mu_coeff function_space = ComplexFunctionSpace(geom.mesh, "CG", degree) pw = PlaneWave(wavelength=lambda0, angle=np.pi / 4, dim=2, domain=geom.mesh, degree=degree) from gyptis.stack import make_stack out = make_stack( geom, coefficients, pw, polarization="TM", source_domains=["groove"], degree=1, dim=2, ) bcs = {}
def test_scatterring3d(shared_datadir): degree = 1 ## needed for surface integral in parallel (mpi) dolfin.parameters["ghost_mode"] = "shared_facet" dolfin.parameters["form_compiler"]["quadrature_degree"] = 2 scs_file = shared_datadir / "sphere_diel.csv" benchmark = np.loadtxt(scs_file, delimiter=",") degree = 1 pmesh = 1 pmesh_scatt = 1 * pmesh eps_sphere = 4 # plt.ion() plt.close("all") plt.plot(benchmark[:, 0], benchmark[:, 1], "k") SCSN = [] Gamma = np.linspace(0.1, 5, 100) Gamma = [2] for gamma in Gamma: # gamma = 1.5 R_sphere = 0.25 circ = 2 * np.pi * R_sphere lambda0 = circ / gamma b = R_sphere * 3 box_size = (b, b, b) pml_width = (lambda0, lambda0, lambda0) g = BoxPML3D(box_size=box_size, pml_width=pml_width) radius_cs_sphere = 0.8 * min(g.box_size) / 2 box = g.box sphere = g.add_sphere(0, 0, 0, R_sphere) sphere_cross_sections = g.add_sphere(0, 0, 0, radius_cs_sphere) sphere, sphere_cross_sections, box = g.fragment( sphere, [sphere_cross_sections, box]) g.add_physical([box, sphere_cross_sections], "box") g.add_physical(sphere, "sphere") # g.add_physical(sphere_cross_sections, "sphere_cross_sections") # surf = g.get_boundaries("sphere_cross_sections")[0] surf = g.get_boundaries(sphere_cross_sections, physical=False)[0] # g.remove(g.dimtag(sphere_cross_sections)) g.add_physical(surf, "calc", dim=2) # g.add_physical(sphere_cross_sections, "sphere_cross_sections") smin = 1 * R_sphere / 2 s = min(lambda0 / pmesh, smin) # s =lambda0 / pmesh smin_pml = lambda0 / (0.66 * pmesh) for coord in ["x", "y", "z", "xy", "xz", "yz", "xyz"]: g.set_mesh_size({"pml" + coord: smin_pml}) g.set_size(box, s) g.set_size(sphere_cross_sections, s) g.set_size(surf, s, dim=2) s = min(lambda0 / (eps_sphere**0.5 * pmesh_scatt), smin) # s = lambda0 / (eps_sphere ** 0.5 * pmesh_scatt) g.set_size(sphere, s) g.build(0) epsilon = dict(sphere=eps_sphere, box=1) mu = dict(sphere=1, box=1) pw = PlaneWave(wavelength=lambda0, angle=(0, 0, 0), dim=3, domain=g.mesh, degree=degree) bcs = {} s = Scatt3D( g, epsilon, mu, pw, boundary_conditions=bcs, degree=degree, ) s.solve() # # E = s.solution["diffracted"] # W = dolfin.FunctionSpace(g.mesh, "DG", 0) # dolfin.File("test.pvd") << project(E.module, W) # # # # import os # # os.system("paraview test.pvd") Z0 = np.sqrt(mu_0 / epsilon_0) S0 = 1 / (2 * Z0) # test = assemble(1*s.dS("calc")) # check = 4*np.pi*radius_cs_sphere**2 # # print(test) # # print(check) n_out = g.unit_normal_vector Es = s.solution["diffracted"] inv_mu_coeff = s.coefficients[1].invert().as_subdomain() omega = s.source.pulsation Hs = inv_mu_coeff / Complex(0, dolfin.Constant( omega * mu_0)) * curl(Es) # Hs = s.inv_mu_coeff / (Complex(0, s.omega * mu_0)) * curl(Es) Ps = dolfin.Constant(0.5) * cross(Es, Hs.conj).real Ws = -assemble(dot(n_out, Ps)("+") * s.dS("calc")) # Ws = -assemble(Es[0].real("+")* s.dS("calc")) Sigma_s = Ws / S0 # S_sphere = R_sphere ** 2 * 4 * np.pi S_sphere = R_sphere**2 * np.pi Sigma_s_norm = Sigma_s / S_sphere print(Sigma_s_norm) SCSN.append(Sigma_s_norm) plt.plot(gamma, Sigma_s_norm, "or")