victorliu / S4

Stanford Stratified Structure Solver - Electromagnetic simulator for layered periodic structures
http://www.stanford.edu/group/fan/S4/
GNU General Public License v2.0
131 stars 149 forks source link

Transmission through silver nano array is not converging #70

Open dorianherle opened 6 years ago

dorianherle commented 6 years ago

Hi !

I am trying to replicate the transmission spectra of a nanoarray in silver which I found in this paper.

The setup is the following:

image

From Top to Bottom:

  1. Layer: Air
  2. Silver Nanoholes: Hole Dimaeter: 250nm Silver Thickness: 400nm Rectangular Period (like chess): P = 500nm
  3. Bottom: Air

This is how the transmission should look like:

image

...and this is what I get with S4:

image

It looks better if you let it run for half a day (numG = 400) image

... but it is still far from the truth.

Therefore, I need your help ! I have already tryed to parallize the code, but there was no substancial speed inprovement.

Here is my code:


-- all dimension are in micro meter (um)
-- starting simulation
S = S4.NewSimulation()

-- Set the unitary cell size. Basically the geometry repeats itself each 0.500 um
S:SetLattice({0.500,0}, {0,0.500})

-- Set maximum number of Fourier orders.
-- Basically if this number is big the result is more accurate but takes much more times to compute

S:SetNumG(160)

--Creation of the silver and air material
-- S:AddMaterial(name, {real epsilon, imag epsilon})
S:AddMaterial("silver", {1, 0}) -- real and imag parts -> Just to initialize
S:AddMaterial("air", {1,0}) -- real and imag parts -> Just to initialize
`

`
------------------------------------------------------------------------
--                      Creation of the geometry                      --
------------------------------------------------------------------------
--S:AddLayer(Name of the layer, thickness, name of the material)
--S:SetLayerPatternRectangle(Name of the layer that will be affected, material of the pattern created, center of the rectangle (relatively to the unitary cell), angle of the rectangle, halfwidth of the rectangle)
--
--Define the incident medium (thickness not relevant)
S:AddLayer('incidentMedium', 0 , 'air')
-- Geometry:
--
--  Incident Medium (air)
--
S:AddLayer('holes', 0.400, 'silver')
-- Geometry:
--
--  Incident Medium (air)
--  ________________________
--                  
--  holes (silver) 
--  ________________________
--

diameter = 0.250
S:SetLayerPatternCircle('holes', 'air', {0,0}, diameter/2)

-- Geometry:
--
--  Incident Medium (air)
--  ________________________
--         |      | 
--  Silver | Air  | Silver 
--  ______ |______|________
--

S:AddLayerCopy('base',0,'incidentMedium')
-- Geometry:
--
--  Incident Medium (air)
--  ________________________
--          |      | 
--  Silver  | Air  | Silver
--  ________|______|________
--
--      base(air)
--

-- To visualize with POVRay
S:OutputStructurePOVRay('visual.pov')
------------------------------------------------------------------------
--                           Incident wave                            --
------------------------------------------------------------------------

--Setting of the incident plane wave
--No polarization 
S:SetExcitationPlanewave(
    {0,0}, -- incidence angles
    {1,0}, -- s-polarization amplitude and phase (in degrees)
    {0,0}) -- p-polarization amplitude and phase

-- Definitions of the wavelength with respective value of epsilon:
-- {wavelength in um, n, k}
silverfreqData = {
   {0.4, {0.045729, 2.12294}}, 
   {0.41, {0.0445195,2.24183}}, 
   {0.42, {0.0432874,2.35715}}, 
   {0.43, {0.0419927,2.46531}}, 
   {0.44, {0.0411015,2.57326}}, 
   {0.45, {0.0409323,2.67576}}, 
   {0.46, {0.0409567,2.77695}}, 
   {0.47, {0.0407272,2.87375}}, 
   {0.48, {0.0407815,2.97218}}, 
   {0.49, {0.0412496,3.06633}}, 
   {0.5,  {0.0413734,3.1594}}, 
   {0.51, {0.0416027,3.25111}}, 
   {0.52, {0.0423728,3.34212}}, 
   {0.53, {0.0422042,3.43319}}, 
   {0.54, {0.0434033,3.5222}}, 
   {0.55, {0.0438172,3.61011}}, 
   {0.56, {0.0445074,3.69702}}, 
   {0.57, {0.0459734,3.78393}}, 
   {0.58, {0.0468199,3.87068}}, 
   {0.59, {0.0468403,3.95717}}, 
   {0.6,  {0.0474104,4.04194}}, 
   {0.61, {0.0489857,4.12631}}, 
   {0.62, {0.0496178,4.20897}}, 
   {0.63, {0.0511019,4.29309}}, 
   {0.64, {0.0516469,4.37683}}, 
   {0.65, {0.0509134,4.46022}}, 
   {0.66, {0.0533885,4.54311}}, 
   {0.67, {0.0524751,4.62372}}, 
   {0.68, {0.0542186,4.70595}}, 
   {0.69, {0.0544292,4.78842}}, 
   {0.7,  {0.0548604,4.86909}}, 
   {0.71, {0.0565386,4.95078}}, 
   {0.72, {0.0574012,5.03421}}
  }

interpolator = S4.NewInterpolator('linear', silverfreqData)
-- S: UseNormalVectorBasis(use)
S: UseSubpixelSmoothing(use)
-- S: UsePolarizationDecomposition(use)
-- S: SetResolution(8)

-- Initialize other simulation objects to be run in parallel
Sb = S:Clone()

    -- Every simulation object computes a transmission curve on its own 
    -- The transmission curves have an offset of delta

delta = 0.001
w=0.7

while w > 0.4 do
    -- Initialize the wavelength for each simulation object
    wa = w
    wb = wa - delta

    -- Set running parameter w to the last highest -> wd
    w=wb - delta

    -- Set frequency for all simulation objects
    S:SetFrequency(1/wa)
    Sb:SetFrequency(1/wb)

    -- Get all complex refractive indexes for all simulation objects
    na, ka = interpolator:Get(wa)
    nb, kb = interpolator:Get(wb)

    -- Set the new epsilon value for the silver (dispersive refractive index)
    S:SetMaterial("silver",{na^2-ka^2, 2*na*ka})
    Sb:SetMaterial("silver",{nb^2-kb^2, 2*nb*kb})

    -- Solve in parallel the incidentMedium and the base layer
    S4.SolveInParallel('incidentMedium', S, Sb);
    S4.SolveInParallel('base', S, Sb);

    -- Get the transmission for all simulation objects
    forwardAirAbove,backwardAirAbove=S:GetPowerFlux('incidentMedium')
    aforwardBottom,abackwardBottom=S:GetPowerFlux('base')

    bforwardBottom,bbackwardBottom=Sb:GetPowerFlux('base')

    ya = (aforwardBottom/forwardAirAbove) -- compute the desired result
    yb = (bforwardBottom/forwardAirAbove) -- compute the desired result

    -- Print the results
    print(wa, ya)
    print(wb, yb)

end
`
kwrobert commented 6 years ago

Metals, and in general layers which have a high refractive index contrast between shapes within a layer (as is the case with your voids surrounded in silver), are notorious difficult to simulate with RCWA. Try plotting the real and imaginary parts of the permittivity to get a sense for how large the contrast is.

dorianherle commented 6 years ago

@kwrobert

thank you very much for your answer. Please excuse my late reply. I did not think that anyone would answer, and therefore I reduce the number of times that I checked my question on GitHub. I fully agree with you. High refractive index contrasts are difficult with RCWA. However I have used professional software: https://mcgrating.com/ and it was able to deliver a good result in 20min.

silver nanoholes mc grating simulation