torcwa icon indicating copy to clipboard operation
torcwa copied to clipboard

Absorption layer-by-layer and incoherent layers

Open GiuseppeELio opened this issue 11 months ago • 0 comments

Dear authors, I'm writing to you to ask your help to include, if possible, in the code the absorption layer by layer calculation for example in a multi-layered structures such as a metal- insulator- metal (MIM) one.

I wrote the following code that compute R,T and total absorption for all layer.

import numpy as np
import torch
import scipy.io
from matplotlib import pyplot as plt
import time
from tqdm import tqdm
import os
from pathlib import Path

import torcwa
import Materials
torch.backends.cuda.matmul.allow_tf32 = False
sim_dtype = torch.complex64
geo_dtype = torch.float32
device = torch.device('cuda')

inc_ang = 0.*(np.pi/180)    # radian
azi_ang = 0.*(np.pi/180)    # radian
# geometry
L = [1024.,1024.]            # nm / nm
torcwa.rcwa_geo.dtype = geo_dtype
torcwa.rcwa_geo.device = device
torcwa.rcwa_geo.Lx = L[0]
torcwa.rcwa_geo.Ly = L[1]
torcwa.rcwa_geo.nx = 1024
torcwa.rcwa_geo.ny = 1024
torcwa.rcwa_geo.grid()
torcwa.rcwa_geo.edge_sharpness = 1000.

x_axis = torcwa.rcwa_geo.x.cpu()
y_axis = torcwa.rcwa_geo.y.cpu()
z_axis = z.cpu()


#layers
layer_Ag=20
layer_ZnO = 90

order_NN = 5 
order = [order_NN,order_NN]
o = np.arange(-order_NN,order_NN+1)
all_orders=np.stack(np.meshgrid(o,o),-1).reshape(-1,2) # Here we consider all the diffracted orders


lam_min = 350.
lam_max = 900.
lam_step = 3.
DL=int((lam_max-lam_min)/lam_step)
lamb0 = torch.linspace(lam_min,lam_max,DL,dtype=geo_dtype,device=device)

# T1_sum = []
T_sum = torch.zeros(len(lamb0))
R_sum = torch.zeros(len(lamb0))
# T_out = []
for lamb0_ind in tqdm(range(len(lamb0))):
   lamb0_now = lamb0[lamb0_ind]
   sim = torcwa.rcwa(freq=1/lamb0_now,order=order,L=L,dtype=sim_dtype,device=device)
   
   Ag_eps = Materials.Ag.apply(lamb0_now/1000)**2
   ZnO_eps = Materials.ZnO.apply(lamb0_now)**2 
   substrate_esp=Materials.SodaLime.apply(lamb0_now/1000)**2

   sim.add_input_layer(eps=1)
   sim.add_output_layer(eps=substrate_esp)
   sim.set_incident_angle(inc_ang=inc_ang,azi_ang=azi_ang)
   
   sim.add_layer(thickness=layer_Ag, eps=Ag_eps)
   sim.add_layer(thickness=layer_ZnO, eps=ZnO_eps)
   sim.add_layer(thickness=layer_Ag, eps=Ag_eps)
   
   sim.solve_global_smatrix()
   
   rpp = sim.S_parameters(orders=all_orders, direction='f', port='r', polarization='pp')
   tpp = sim.S_parameters(orders=all_orders, direction='f', port='t', polarization='pp')
   rss = sim.S_parameters(orders=all_orders, direction='f', port='r', polarization='ss')
   tss = sim.S_parameters(orders=all_orders, direction='f', port='t', polarization='ss')
   rps = sim.S_parameters(orders=all_orders, direction='f', port='r', polarization='ps')
   tps = sim.S_parameters(orders=all_orders, direction='f', port='t', polarization='ps')
   rsp = sim.S_parameters(orders=all_orders, direction='f', port='r', polarization='sp')
   tsp = sim.S_parameters(orders=all_orders, direction='f', port='t', polarization='sp')

   T_sum[lamb0_ind] = ((torch.sum(torch.abs(tpp)**2) + torch.sum(torch.abs(tsp)**2)) + (torch.sum(torch.abs(tss)**2) + torch.sum(torch.abs(tps)**2)))/2
   R_sum[lamb0_ind] = ((torch.sum(torch.abs(rpp)**2) + torch.sum(torch.abs(rsp)**2)) + (torch.sum(torch.abs(rss)**2) + torch.sum(torch.abs(rps)**2)))/2

Lam=lamb0.cpu().numpy()
R=R_sum.cpu().numpy()
T = T_sum.cpu().numpy()
A_sum=1-R-T
Output=[Lam,R,T,A_sum]
Output=np.transpose(Output)
plt.plot(lamb0.cpu(),R)
plt.plot(lamb0.cpu(), A_sum)
plt.plot(lamb0.cpu(), T)
plt.title('Spectrum (order: '+str(order_NN)+')')
plt.xlabel('Wavelength (nm)')
plt.ylabel('Reflectance/ Absorbance (a.u.)')
plt.grid()

Did you have any suggestion to calculate the absorption layer by layer?

Another question that I have is related to the following task. Is it possible to include one or more than one incoherent layer? For example if I add on or below this MIM structure a thick polymer layer of tens micrometer?

Thanks in advance.

GiuseppeELio avatar Jul 10 '23 12:07 GiuseppeELio