Skip to content

Wrong size of Block in simulation #3250

Description

@leSemaleon

I want to obtain a set of spectra from a cross-shaped metasurface. I've encountered a problem: the geometry displayed by get_array doesn't match my expectations.

Crosses have three parameters: period, arm length, and arm width, P, L, W.

I'm constructing the geometry based on these values, but get_array shows that the crosses are always symmetrical about 0,0, but the point 0,0 itself isn't in the eps array. In my opinion, for a grid size that's a multiple of two, 00 shouldn't be included, but for a grid size that's not a multiple of two, 00 should be included.

Currently, all dimensions are padded so that 00 doesn't appear, and accordingly, I don't get the size I expect. Instead of 5 µm, the step becomes 10, and the 60 µm I specify becomes 70 µm on the get_array

In the figures below, you can see that increasing the period from 300 to 305, that is, by one grid step, does not change anything. The grid size remains at 62 pixels, which is equal to 310 µm.

A similar situation occurs with other parameters.

The code is hidden under the spoiler

Image Image
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from datetime import datetime
import matplotlib.pyplot as plt
import meep as mp
import numpy as np
import materials
from tqdm import tqdm
from matplotlib.ticker import MultipleLocator


NFREQ = 2000


def plot_epsdata(sim: mp.Simulation, pos, title):
    sim.init_sim()
    eps_data = sim.get_array(
        center=mp.Vector3(0, 0, pos),
        size=mp.Vector3(sim.cell_size.x, sim.cell_size.y, 0),
        component=mp.Dielectric,
    )
    eps_data1 = sim.get_array(
        center=mp.Vector3(0, 0, 0),
        size=mp.Vector3(sim.cell_size.x, 0, sim.cell_size.z),
        component=mp.Dielectric,
    )
    eps_data2 = sim.get_array(
        center=mp.Vector3(0, 0, 0),
        size=mp.Vector3(0, sim.cell_size.y, sim.cell_size.z),
        component=mp.Dielectric,
    )
    # plt.ion()
    _, ax = plt.subplots()
    ax.pcolormesh(eps_data, edgecolor="gray", linewidth=0.5)
    ax.set_aspect("equal")
    ax.set_title(title)
   
    plt.savefig("eps_" + datetime.now().strftime("%H:%M:%S") + ".svg")
    plt.show()

    plt.pause(0.5)


def simulation(period, widthCross, widthShouder, iteration):
    f_min_thz = 0.21  # source min frequency THz
    f_max_thz = 1.2  # source max frequency THz
    f_min = f_min_thz / 300
    f_max = f_max_thz / 300
    f_cen = 0.5 * (f_min + f_max)
    df = f_max - f_min

    gridstep = 5

    dpml = int((1 / f_min) * 0.6 / gridstep + 0.5) * gridstep
    dAirIn = 500
    dMetal = 10
    dAirOut = 500

    layers = [
        dpml,
        dAirIn,
        dMetal,
        dAirOut,
        dpml,
    ]

    accuracityOfDecay = 1e-7

    sx = period
    sy = period
    sz = sum(layers)

    field_component = mp.Ey

    cell_size = mp.Vector3(sx, sy, sz)

    resolution = 1 / gridstep

    nfreq = NFREQ  # number of frequencies at which to compute flux

    sources = [
        mp.Source(
            mp.GaussianSource(f_cen, fwidth=df, is_integrated=True),
            component=field_component,
            center=mp.Vector3(0, 0, -0.5 * sz + dpml),
            size=mp.Vector3(sx, sy, 0),
            # amplitude=100,
        )
    ]

    boundary_layers = [
        mp.PML(
            thickness=dpml, direction=mp.Z, side=mp.Low, pml_profile=lambda u: u * u * u
        ),
        mp.PML(
            thickness=dpml,
            direction=mp.Z,
            side=mp.High,
            pml_profile=lambda u: u * u * u,
        ),
    ]

    # default_material = mp.Medium(epsilon=1, D_conductivity=1e-7)
    default_material = mp.air

    geometry = []
    rel_z = -0.5 * sz + dpml + dAirIn
    if iteration:
        meta = [
            mp.Block(
                size=mp.Vector3(sx, sy, dMetal),
                center=mp.Vector3(0, 0, rel_z + 0.5 * dMetal),
                # material=mp.metal,
                material=materials.Copper(),
            ),
            mp.Block(
                size=mp.Vector3(widthCross, widthShouder, dMetal),
                center=mp.Vector3(
                    0,
                    0,
                    rel_z + 0.5 * dMetal,
                ),
                material=default_material,
            ),
            mp.Block(
                size=mp.Vector3(widthShouder, widthCross, dMetal),
                center=mp.Vector3(
                    0,
                    0,
                    rel_z + 0.5 * dMetal,
                ),
                material=default_material,
            ),
        ]
        posMetal = rel_z + 0.5 * dMetal
        rel_z += dMetal
        geometry.extend(meta)

    sim = mp.Simulation(
        cell_size=cell_size,
        boundary_layers=boundary_layers,
        sources=sources,
        geometry=geometry,
        default_material=default_material,
        k_point=mp.Vector3(),
        resolution=resolution,
        eps_averaging=False,
    )

    if iteration and 1:
        plot_epsdata(
            sim, posMetal, title=f"P: {period}, L: {widthCross}, W: {widthShouder}"
        )


def main():
    P = [305]
    L = [130]
    W = [65]

    for i in tqdm(range(len(P)), ncols=50, disable=True):
        for j in tqdm(range(len(L)), ncols=50, disable=True):
            for k in tqdm(range(len(W)), ncols=50, disable=True):
                simulation(P[i], L[j], W[k], 1)
                continue


if __name__ == "__main__":
    main()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions