NanoComp / mpb

MIT Photonic-Bands: computation of photonic band structures in periodic media
GNU General Public License v2.0
160 stars 87 forks source link

Prism can't work properly in lattice coordinates #160

Open knifelees3 opened 1 year ago

knifelees3 commented 1 year ago

I have started a discussion and now I think the Prism methods can't work properly in lattice coordinates. I want to define some holes with different shapes in a lattice, image

but only the square and round holes can be realized by using Block and Cylinder function. If I use Prism to realize square or hexagonal shapes, the shapes are still rhombus acccording to the lattice basis. For example, If we define the square holes by changing e1,e2

s=0.125
geometry=[mp.Block(mp.Vector3(0.25,0.25),center=mp.Vector3(0,0), material=slab,
                  e1 = mp.cartesian_to_lattice(mp.Vector3(1,0,0), geometry_lattice),
                  e2 = mp.cartesian_to_lattice(mp.Vector3(0,1,0), geometry_lattice))]

it works well image But If we define the square via Prism, the shape is not correct

s=0.125
vertices1 = [mp.cartesian_to_lattice(mp.Vector3(-1*s,-1*s),geometry_lattice),
             mp.cartesian_to_lattice(mp.Vector3(-1*s,1*s),geometry_lattice),
             mp.cartesian_to_lattice(mp.Vector3(s*1,s*1),geometry_lattice),
             mp.cartesian_to_lattice(mp.Vector3(1*s,-1*s),geometry_lattice)]
geometry=[mp.Prism(vertices1, height=mp.inf, center=mp.Vector3(0,0), material=slab)]

image

In the above results, the lattice basis I used is not vertical:

# Lattice geometry
geometry_lattice = mp.Lattice(
    size=mp.Vector3(1, 1),
    basis2=mp.Vector3(0.5,math.sqrt(3) / 2),
    basis1=mp.Vector3(1, 0),
)

I also tried the Lattice that is perpendicular to the coordinate axis

# Lattice geometry
geometry_lattice = mp.Lattice(
    size=mp.Vector3(1, 1),
    basis2=mp.Vector3(0,1),
    basis1=mp.Vector3(1, 0),
)

, but the corresponding shapes such as triangles and hexagons still cannot come out, they are still rectangle holes.

The following is full program:

# we first use the function mp.cartesian_to_lattice to transform the coordinates

import math

import meep as mp
from meep import mpb
import numpy as np
# A triangular lattice of dielectric rods in air.  (This structure has
# a band_gap for TM fields.)  This file is used in the "Data Analysis
# Tutorial" section of the MPB manual.

num_bands = 8

nslab = 2.48
slab = mp.Medium(index=nslab)

# # Lattice geometry I
# geometry_lattice = mp.Lattice(
#     size=mp.Vector3(1, 1),
#     basis2=mp.Vector3(0.5,math.sqrt(3) / 2),
#     basis1=mp.Vector3(1, 0),
# )

# Lattice geometry II
geometry_lattice = mp.Lattice(
    size=mp.Vector3(1, 1),
    basis2=mp.Vector3(0,1),
    basis1=mp.Vector3(1, 0),
)

# (1) For squares in cartesian coordinates
# s=0.125
# vertices1 = [mp.Vector3(-1*s,-1*s),
#              mp.Vector3(-1*s,1*s),
#              mp.Vector3(s*1,s*1),
#              mp.Vector3(1*s,-1*s)]
# geometry=[mp.Prism(vertices1, height=mp.inf, center=mp.Vector3(0,0), material=slab)]

#(2) For squares in Lattice coordinates method 1
# s=0.125
# vertices1 = [mp.cartesian_to_lattice(mp.Vector3(-1*s,-1*s),geometry_lattice),
#              mp.cartesian_to_lattice(mp.Vector3(-1*s,1*s),geometry_lattice),
#              mp.cartesian_to_lattice(mp.Vector3(s*1,s*1),geometry_lattice),
#              mp.cartesian_to_lattice(mp.Vector3(1*s,-1*s),geometry_lattice)]
# geometry=[mp.Prism(vertices1, height=mp.inf, center=mp.Vector3(0,0), material=slab)]

# # (3) For squares in Lattice coordinates method 2
# s=0.125
# geometry=[mp.Block(mp.Vector3(0.25,0.25),center=mp.Vector3(0,0), material=slab)]

# #(4) For squares in Lattice coordinates method 2
# s=0.125
# geometry=[mp.Block(mp.Vector3(0.25,0.25),center=mp.Vector3(0,0), material=slab,
#                   e1 = mp.cartesian_to_lattice(mp.Vector3(1,0,0), geometry_lattice),
#                   e2 = mp.cartesian_to_lattice(mp.Vector3(0,1,0), geometry_lattice))]

# # #(5) For squares in Lattice coordinates method 3
# s=0.2
# vertices1 = [mp.Vector3(0*s,0*s),
#              mp.Vector3(1*s,0*s),
#              mp.Vector3(s*3/2,s*np.sqrt(3)/2),
#              mp.Vector3(s*1/2,s*np.sqrt(3)/2),]
# geometry=[mp.Prism(vertices1, height=mp.inf, center=mp.Vector3(0,0), material=slab,axis=mp.Vector3(0,0,1))]

# # #(5) For triangle in Lattice coordinates
s1=0.2
vertices1 = [mp.Vector3(-1*s1,0),
            mp.Vector3(0*s1,math.sqrt(3)/2*s1),
            mp.Vector3(1*s1,0),]
geometry=[mp.Prism(vertices1, height=mp.inf, center=mp.Vector3(0,0), material=slab,axis=mp.Vector3(0,0,1))]

# 注意倒格矢空间
k_points = [
    mp.Vector3(),  # Gamma
    mp.Vector3(y=0.5),  # M
    mp.Vector3(1 / -3, 1 / 3),  # K
    mp.Vector3(),  # Gamma
]

k_points = mp.interpolate(4, k_points)

resolution = 32

ms = mpb.ModeSolver(
    geometry=geometry,
    geometry_lattice=geometry_lattice,
    k_points=k_points,
    resolution=resolution,
    num_bands=num_bands,
)

ms.run_tm()
tm_freqs = ms.all_freqs
tm_gaps = ms.gap_list

import matplotlib.pyplot as plt
md = mpb.MPBData(rectify=False, periods=6, resolution=64)
eps = ms.get_epsilon()
converted_eps = md.convert(eps)

plt.imshow(converted_eps.T, interpolation='spline36', cmap='binary')
plt.axis('off')
plt.show()

md = mpb.MPBData(rectify=True, periods=6, resolution=64)
eps = ms.get_epsilon()
converted_eps = md.convert(eps)

plt.imshow(converted_eps.T, interpolation='spline36', cmap='binary')
plt.axis('off')
plt.show()