NanoComp / meep

free finite-difference time-domain (FDTD) software for electromagnetic simulations
GNU General Public License v2.0
1.16k stars 596 forks source link

Simulation of a layer of a substance absorbing at a certain frequency #2735

Closed leSemaleon closed 3 months ago

leSemaleon commented 7 months ago

Hello,

I have material that is not among the standard ones. I wrote an approximation for it using functions. But the transmission spectrum does not correspond to reality. The transmission spectrum is as if there is a transparent material in the path of the radiation, that is, it is equal to 100 percent everywhere in the tested frequency range. But this shouldn't happen. The pictures show the imaginary and real parts of epsilon for the material and the transmission spectrum Figure_1 Figure_2 The real and imaginary parts of epsilon are obtained using the method Medium.epsilon using my material function Layer thickness is 100 microns. The transmission spectrum does not depend on thickness for some reason. I tried with resolution 1, 10, and 100, the result is the same.

smartalecH commented 7 months ago

How did you add your materials and geometry to your meep simulation? Some definitions, ie those involving material functions, require you to additionally pass the materials into the extra_materials field of the simulation constructor.

leSemaleon commented 7 months ago

I created a class for my material, or rather susceptibility, which inherits from the class in the geom. It also contains all the methods found in susceptibilities like Drude. Using this susceptibility, I set the material using mp.Meidum(epsilon=1, E_Susceptibility = [mySusceptibility])

smartalecH commented 7 months ago

Right but how did you assign it to your geometry? It's usually easier if you just include your code.

leSemaleon commented 7 months ago

Ok. There is a code. 0 Iteration without geometry nd 1 iteration with

def main(iteration=0, refer_refl_data=[]):

    # meep unit = 1 μm
    dpml = 1000
    dAirIn = 200
    dAirOut = 200
    dFilm = 500

    accuracityOfDecay = 1e-9

    sx = 0
    sy = 0 
    sz = dpml + dAirIn + dFilm + dAirOut + dpml

    field_component = mp.Ex

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

    gridstep = 0.1
    resolution = 1/gridstep

    lmin = 100         # source min wavelength
    lmax = 1000         # source max wavelength
    fmin = 1/lmax       # source min frequency
    fmax = 1/lmin       # source max frequency
    fcen = 0.5*(fmin+fmax)
    df = fmax-fmin

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

    sources = [
        mp.Source(
            mp.GaussianSource(fcen, fwidth=df),
            component=field_component,
            center=mp.Vector3(0, 0, -0.5*sz+dpml+0.2*dAirIn),
            size=mp.Vector3(sx,sy,0),
        )
    ]

    boundary_layers = [mp.PML(thickness=dpml,direction=mp.Z,side=mp.Low),
                      mp.PML(thickness=dpml,direction=mp.Z,side=mp.High)]

    geometry = []
    if iteration:
        film = mp.Block(
                    size = mp.Vector3(sx, sy, dFilm),
                    center = mp.Vector3(0, 0, -0.5*sz+dpml+dAirIn+0.5*dFilm),
                    material = usrmp.RDX
                )
        geometry.append(film)

    sim = mp.Simulation(
        cell_size = cell_size,
        boundary_layers = boundary_layers,
        sources = sources,
        geometry = geometry,
        resolution = resolution,
        dimensions = 1,
    )

    refl_fr = mp.FluxRegion(
        center=mp.Vector3(0,0,-sz/2+dpml+0.5*dAirIn), 
        size=mp.Vector3(sx,sy,0)
    )

    refl = sim.add_flux(fcen, df, nfreq, refl_fr)

    tran_fr = mp.FluxRegion(
        center=mp.Vector3(0,0,sz/2-dpml-0.5*dAirOut), 
        size=mp.Vector3(sx,sy,0)
    )

    tran = sim.add_flux(fcen, df, nfreq, tran_fr)

    if iteration:
        sim.load_minus_flux_data(refl, refer_refl_data)

    sim.run(until_after_sources=mp.stop_when_fields_decayed(30, field_component, 
                                                            mp.Vector3(0,0,sz/2-dpml-0.5*dAirOut), 
                                                            accuracityOfDecay))

    refl_data = sim.get_flux_data(refl)
    refl_flux = mp.get_fluxes(refl)
    tran_flux = mp.get_fluxes(tran)
    flux_freqs = mp.get_flux_freqs(refl)

    sim.reset_meep()
    data = [resolution, dFilm]
    return refl_data, refl_flux, tran_flux, flux_freqs, data
leSemaleon commented 7 months ago

I do everything as in the example, except to shorten it by denoting the simulation as a function and calling it twice. I dont know why it doesnt work/

leSemaleon commented 6 months ago

any ideas on how to fix this?

WeiKuoLi commented 3 months ago

Your dipole fields are not updated accordingly. Meep thus think the whole medium is vacuum and gives you 100% transmission. Without knowing your custom code it would not be possible knowing what went wrong.