[examples/fdfd] split fdfd example into two files
This commit is contained in:
parent
d4f1008c5c
commit
fb3bef23bf
103
examples/fdfd0.py
Normal file
103
examples/fdfd0.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import numpy
|
||||||
|
from numpy.linalg import norm
|
||||||
|
from matplotlib import pyplot, colors
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import meanas
|
||||||
|
from meanas import fdtd
|
||||||
|
from meanas.fdmath import vec, unvec
|
||||||
|
from meanas.fdfd import waveguide_3d, functional, scpml, operators
|
||||||
|
from meanas.fdfd.solvers import generic as generic_solver
|
||||||
|
|
||||||
|
import gridlock
|
||||||
|
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
logging.getLogger('matplotlib').setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
__author__ = 'Jan Petykiewicz'
|
||||||
|
|
||||||
|
|
||||||
|
def pcolor(ax, v) -> None:
|
||||||
|
mappable = ax.pcolor(v, cmap='seismic', norm=colors.CenteredNorm())
|
||||||
|
ax.axis('equal')
|
||||||
|
ax.get_figure().colorbar(mappable)
|
||||||
|
|
||||||
|
|
||||||
|
def test0(solver=generic_solver):
|
||||||
|
dx = 50 # discretization (nm/cell)
|
||||||
|
pml_thickness = 10 # (number of cells)
|
||||||
|
|
||||||
|
wl = 1550 # Excitation wavelength
|
||||||
|
omega = 2 * numpy.pi / wl
|
||||||
|
|
||||||
|
# Device design parameters
|
||||||
|
radii = (1, 0.6)
|
||||||
|
th = 220
|
||||||
|
center = [0, 0, 0]
|
||||||
|
|
||||||
|
# refractive indices
|
||||||
|
n_ring = numpy.sqrt(12.6) # ~Si
|
||||||
|
n_air = 4.0 # air
|
||||||
|
|
||||||
|
# Half-dimensions of the simulation grid
|
||||||
|
xyz_max = numpy.array([1.2, 1.2, 0.3]) * 1000 + pml_thickness * dx
|
||||||
|
|
||||||
|
# Coordinates of the edges of the cells.
|
||||||
|
half_edge_coords = [numpy.arange(dx/2, m + dx, step=dx) for m in xyz_max]
|
||||||
|
edge_coords = [numpy.hstack((-h[::-1], h)) for h in half_edge_coords]
|
||||||
|
|
||||||
|
# #### Create the grid, mask, and draw the device ####
|
||||||
|
grid = gridlock.Grid(edge_coords)
|
||||||
|
epsilon = grid.allocate(n_air**2, dtype=numpy.float32)
|
||||||
|
grid.draw_cylinder(
|
||||||
|
epsilon,
|
||||||
|
h = dict(axis='z', center=center[2], span=th),
|
||||||
|
radius = max(radii),
|
||||||
|
center2d = center[:2],
|
||||||
|
foreground = n_ring ** 2,
|
||||||
|
num_points = 24,
|
||||||
|
)
|
||||||
|
grid.draw_cylinder(
|
||||||
|
epsilon,
|
||||||
|
h = dict(axis='z', center=center[2], span=th * 1.1),
|
||||||
|
radius = min(radii),
|
||||||
|
center2d = center[:2],
|
||||||
|
foreground = n_air ** 2,
|
||||||
|
num_points = 24,
|
||||||
|
)
|
||||||
|
|
||||||
|
dxes = [grid.dxyz, grid.autoshifted_dxyz()]
|
||||||
|
for a in (0, 1, 2):
|
||||||
|
for p in (-1, 1):
|
||||||
|
dxes = meanas.fdfd.scpml.stretch_with_scpml(dxes, axis=a, polarity=p, omega=omega,
|
||||||
|
thickness=pml_thickness)
|
||||||
|
|
||||||
|
J = [numpy.zeros_like(epsilon[0], dtype=complex) for _ in range(3)]
|
||||||
|
J[1][15, grid.shape[1]//2, grid.shape[2]//2] = 1
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Solve!
|
||||||
|
#
|
||||||
|
sim_args = dict(
|
||||||
|
omega = omega,
|
||||||
|
dxes = dxes,
|
||||||
|
epsilon = vec(epsilon),
|
||||||
|
)
|
||||||
|
x = solver(J=vec(J), **sim_args)
|
||||||
|
|
||||||
|
A = operators.e_full(omega, dxes, vec(epsilon)).tocsr()
|
||||||
|
b = -1j * omega * vec(J)
|
||||||
|
print('Norm of the residual is ', norm(A @ x - b) / norm(b))
|
||||||
|
|
||||||
|
E = unvec(x, grid.shape)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Plot results
|
||||||
|
#
|
||||||
|
grid.visualize_slice(E.real, plane=dict(z=0), which_shifts=1, pcolormesh_args=dict(norm=colors.CenteredNorm(), cmap='bwr'))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test0()
|
||||||
@ -1,6 +1,8 @@
|
|||||||
import importlib
|
import importlib
|
||||||
import numpy
|
import numpy
|
||||||
from numpy.linalg import norm
|
from numpy.linalg import norm
|
||||||
|
from matplotlib import pyplot, colors
|
||||||
|
import logging
|
||||||
|
|
||||||
import meanas
|
import meanas
|
||||||
from meanas import fdtd
|
from meanas import fdtd
|
||||||
@ -10,9 +12,6 @@ from meanas.fdfd.solvers import generic as generic_solver
|
|||||||
|
|
||||||
import gridlock
|
import gridlock
|
||||||
|
|
||||||
from matplotlib import pyplot
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
logging.getLogger('matplotlib').setLevel(logging.WARNING)
|
logging.getLogger('matplotlib').setLevel(logging.WARNING)
|
||||||
@ -20,86 +19,6 @@ logging.getLogger('matplotlib').setLevel(logging.WARNING)
|
|||||||
__author__ = 'Jan Petykiewicz'
|
__author__ = 'Jan Petykiewicz'
|
||||||
|
|
||||||
|
|
||||||
def test0(solver=generic_solver):
|
|
||||||
dx = 50 # discretization (nm/cell)
|
|
||||||
pml_thickness = 10 # (number of cells)
|
|
||||||
|
|
||||||
wl = 1550 # Excitation wavelength
|
|
||||||
omega = 2 * numpy.pi / wl
|
|
||||||
|
|
||||||
# Device design parameters
|
|
||||||
radii = (1, 0.6)
|
|
||||||
th = 220
|
|
||||||
center = [0, 0, 0]
|
|
||||||
|
|
||||||
# refractive indices
|
|
||||||
n_ring = numpy.sqrt(12.6) # ~Si
|
|
||||||
n_air = 4.0 # air
|
|
||||||
|
|
||||||
# Half-dimensions of the simulation grid
|
|
||||||
xyz_max = numpy.array([1.2, 1.2, 0.3]) * 1000 + pml_thickness * dx
|
|
||||||
|
|
||||||
# Coordinates of the edges of the cells.
|
|
||||||
half_edge_coords = [numpy.arange(dx/2, m + dx, step=dx) for m in xyz_max]
|
|
||||||
edge_coords = [numpy.hstack((-h[::-1], h)) for h in half_edge_coords]
|
|
||||||
|
|
||||||
# #### Create the grid, mask, and draw the device ####
|
|
||||||
grid = gridlock.Grid(edge_coords)
|
|
||||||
epsilon = grid.allocate(n_air**2, dtype=numpy.float32)
|
|
||||||
grid.draw_cylinder(
|
|
||||||
epsilon,
|
|
||||||
surface_normal=2,
|
|
||||||
center=center,
|
|
||||||
radius=max(radii),
|
|
||||||
thickness=th,
|
|
||||||
foreground=n_ring**2,
|
|
||||||
num_points=24,
|
|
||||||
)
|
|
||||||
grid.draw_cylinder(
|
|
||||||
epsilon,
|
|
||||||
surface_normal=2,
|
|
||||||
center=center,
|
|
||||||
radius=min(radii),
|
|
||||||
thickness=th*1.1,
|
|
||||||
foreground=n_air ** 2,
|
|
||||||
num_points=24,
|
|
||||||
)
|
|
||||||
|
|
||||||
dxes = [grid.dxyz, grid.autoshifted_dxyz()]
|
|
||||||
for a in (0, 1, 2):
|
|
||||||
for p in (-1, 1):
|
|
||||||
dxes = meanas.fdfd.scpml.stretch_with_scpml(dxes, axis=a, polarity=p, omega=omega,
|
|
||||||
thickness=pml_thickness)
|
|
||||||
|
|
||||||
J = [numpy.zeros_like(epsilon[0], dtype=complex) for _ in range(3)]
|
|
||||||
J[1][15, grid.shape[1]//2, grid.shape[2]//2] = 1
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Solve!
|
|
||||||
#
|
|
||||||
sim_args = {
|
|
||||||
'omega': omega,
|
|
||||||
'dxes': dxes,
|
|
||||||
'epsilon': vec(epsilon),
|
|
||||||
}
|
|
||||||
x = solver(J=vec(J), **sim_args)
|
|
||||||
|
|
||||||
A = operators.e_full(omega, dxes, vec(epsilon)).tocsr()
|
|
||||||
b = -1j * omega * vec(J)
|
|
||||||
print('Norm of the residual is ', norm(A @ x - b))
|
|
||||||
|
|
||||||
E = unvec(x, grid.shape)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Plot results
|
|
||||||
#
|
|
||||||
pyplot.figure()
|
|
||||||
pyplot.pcolor(numpy.real(E[1][:, :, grid.shape[2]//2]), cmap='seismic')
|
|
||||||
pyplot.axis('equal')
|
|
||||||
pyplot.show()
|
|
||||||
|
|
||||||
|
|
||||||
def test1(solver=generic_solver):
|
def test1(solver=generic_solver):
|
||||||
dx = 40 # discretization (nm/cell)
|
dx = 40 # discretization (nm/cell)
|
||||||
pml_thickness = 10 # (number of cells)
|
pml_thickness = 10 # (number of cells)
|
||||||
@ -126,7 +45,7 @@ def test1(solver=generic_solver):
|
|||||||
# #### Create the grid and draw the device ####
|
# #### Create the grid and draw the device ####
|
||||||
grid = gridlock.Grid(edge_coords)
|
grid = gridlock.Grid(edge_coords)
|
||||||
epsilon = grid.allocate(n_air**2, dtype=numpy.float32)
|
epsilon = grid.allocate(n_air**2, dtype=numpy.float32)
|
||||||
grid.draw_cuboid(epsilon, center=center, dimensions=[8e3, w, th], foreground=n_wg**2)
|
grid.draw_cuboid(epsilon, x=dict(center=0, span=8e3), y=dict(center=0, span=w), z=dict(center=0, span=th), foreground=n_wg**2)
|
||||||
|
|
||||||
dxes = [grid.dxyz, grid.autoshifted_dxyz()]
|
dxes = [grid.dxyz, grid.autoshifted_dxyz()]
|
||||||
for a in (0, 1, 2):
|
for a in (0, 1, 2):
|
||||||
@ -160,17 +79,9 @@ def test1(solver=generic_solver):
|
|||||||
# grid.draw_cuboid(pmcg, center=[700, 0, 0], dimensions=[80, 1e8, 1e8], eps=1)
|
# grid.draw_cuboid(pmcg, center=[700, 0, 0], dimensions=[80, 1e8, 1e8], eps=1)
|
||||||
# grid.visualize_isosurface(pmcg)
|
# grid.visualize_isosurface(pmcg)
|
||||||
|
|
||||||
def pcolor(v) -> None:
|
grid.visualize_slice(J.imag, plane=dict(y=6*dx), which_shifts=1, pcolormesh_args=dict(norm=colors.CenteredNorm(), cmap='bwr'))
|
||||||
vmax = numpy.max(numpy.abs(v))
|
fig, ax = pyplot.subplots()
|
||||||
pyplot.pcolor(v, cmap='seismic', vmin=-vmax, vmax=vmax)
|
ax.pcolormesh((numpy.abs(J).sum(axis=2).sum(axis=0) > 0).astype(float).T, cmap='hot')
|
||||||
pyplot.axis('equal')
|
|
||||||
pyplot.colorbar()
|
|
||||||
|
|
||||||
ss = (1, slice(None), J.shape[2]//2+6, slice(None))
|
|
||||||
# pyplot.figure()
|
|
||||||
# pcolor(J3[ss].T.imag)
|
|
||||||
# pyplot.figure()
|
|
||||||
# pcolor((numpy.abs(J3).sum(axis=2).sum(axis=0) > 0).astype(float).T)
|
|
||||||
pyplot.show(block=True)
|
pyplot.show(block=True)
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -196,16 +107,14 @@ def test1(solver=generic_solver):
|
|||||||
# Plot results
|
# Plot results
|
||||||
#
|
#
|
||||||
center = grid.pos2ind([0, 0, 0], None).astype(int)
|
center = grid.pos2ind([0, 0, 0], None).astype(int)
|
||||||
pyplot.figure()
|
fig, axes = pyplot.subplots(2, 2)
|
||||||
pyplot.subplot(2, 2, 1)
|
grid.visualize_slice(E.real, plane=dict(x=0), which_shifts=1, ax=axes[0, 0], finalize=False, pcolormesh_args=dict(norm=colors.CenteredNorm(), cmap='bwr'))
|
||||||
pcolor(numpy.real(E[1][center[0], :, :]).T)
|
grid.visualize_slice(E.real, plane=dict(z=0), which_shifts=1, ax=axes[0, 1], finalize=False, pcolormesh_args=dict(norm=colors.CenteredNorm(), cmap='bwr'))
|
||||||
pyplot.subplot(2, 2, 2)
|
# pcolor(axes[0, 0], numpy.real(E[1][center[0], :, :]).T)
|
||||||
pyplot.plot(numpy.log10(numpy.abs(E[1][:, center[1], center[2]]) + 1e-10))
|
# pcolor(axes[0, 1], numpy.real(E[1][:, :, center[2]]).T)
|
||||||
pyplot.grid(alpha=0.6)
|
axes[1, 0].plot(numpy.log10(numpy.abs(E[1][:, center[1], center[2]]) + 1e-10))
|
||||||
pyplot.ylabel('log10 of field')
|
axes[1, 0].grid(alpha=0.6)
|
||||||
pyplot.subplot(2, 2, 3)
|
axes[1, 0].set_ylabel('log10 of field')
|
||||||
pcolor(numpy.real(E[1][:, :, center[2]]).T)
|
|
||||||
pyplot.subplot(2, 2, 4)
|
|
||||||
|
|
||||||
def poyntings(E):
|
def poyntings(E):
|
||||||
H = functional.e2h(omega, dxes)(E)
|
H = functional.e2h(omega, dxes)(E)
|
||||||
@ -219,34 +128,35 @@ def test1(solver=generic_solver):
|
|||||||
return s0, s1, s2
|
return s0, s1, s2
|
||||||
|
|
||||||
s0x, s1x, s2x = poyntings(E)
|
s0x, s1x, s2x = poyntings(E)
|
||||||
pyplot.plot(s0x[0].sum(axis=2).sum(axis=1), label='s0', marker='.')
|
ax = axes[1, 1]
|
||||||
pyplot.plot(s1x[0].sum(axis=2).sum(axis=1), label='s1', marker='.')
|
ax.plot(s0x[0].sum(axis=2).sum(axis=1), label='s0', marker='.')
|
||||||
pyplot.plot(s2x[0].sum(axis=2).sum(axis=1), label='s2', marker='.')
|
ax.plot(s1x[0].sum(axis=2).sum(axis=1), label='s1', marker='.')
|
||||||
pyplot.plot(E[1][:, center[1], center[2]].real.T, label='Ey', marker='x')
|
ax.plot(s2x[0].sum(axis=2).sum(axis=1), label='s2', marker='.')
|
||||||
pyplot.grid(alpha=0.6)
|
ax.plot(E[1][:, center[1], center[2]].real.T, label='Ey', marker='x')
|
||||||
pyplot.legend()
|
ax.grid(alpha=0.6)
|
||||||
pyplot.show()
|
ax.legend()
|
||||||
|
|
||||||
|
p_in = (-E * J.conj()).sum() / 2 * (dx * dx * dx)
|
||||||
|
print(f'{p_in=}')
|
||||||
|
|
||||||
q = []
|
q = []
|
||||||
for i in range(-5, 30):
|
for i in range(-5, 30):
|
||||||
e_ovl_rolled = numpy.roll(e_overlap, i, axis=1)
|
e_ovl_rolled = numpy.roll(e_overlap, i, axis=1)
|
||||||
q += [numpy.abs(vec(E) @ vec(e_ovl_rolled).conj())]
|
q += [numpy.abs(vec(E).conj() @ vec(e_ovl_rolled))]
|
||||||
pyplot.figure()
|
fig, ax = pyplot.subplots()
|
||||||
pyplot.plot(q, marker='.')
|
ax.plot(q, marker='.')
|
||||||
pyplot.grid(alpha=0.6)
|
ax.grid(alpha=0.6)
|
||||||
pyplot.title('Overlap with mode')
|
ax.set_title('Overlap with mode')
|
||||||
pyplot.show()
|
|
||||||
print('Average overlap with mode:', sum(q[8:32])/len(q[8:32]))
|
print('Average overlap with mode:', sum(q[8:32])/len(q[8:32]))
|
||||||
|
|
||||||
|
pyplot.show(block=True)
|
||||||
|
|
||||||
|
|
||||||
def module_available(name):
|
def module_available(name):
|
||||||
return importlib.util.find_spec(name) is not None
|
return importlib.util.find_spec(name) is not None
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
#test0()
|
|
||||||
# test1()
|
|
||||||
|
|
||||||
if module_available('opencl_fdfd'):
|
if module_available('opencl_fdfd'):
|
||||||
from opencl_fdfd import cg_solver as opencl_solver
|
from opencl_fdfd import cg_solver as opencl_solver
|
||||||
test1(opencl_solver)
|
test1(opencl_solver)
|
||||||
@ -257,3 +167,4 @@ if __name__ == '__main__':
|
|||||||
# test1(magma_solver)
|
# test1(magma_solver)
|
||||||
else:
|
else:
|
||||||
test1()
|
test1()
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user