TAGGED: plasmonics
-
-
March 2, 2026 at 5:20 pm
raano1
SubscriberHello,
I am simulating the effect of Ag nanoparticles (NPs) on light absorption in a Si solar cell structure using 2D FDTD in Lumerical. I am running two simulations — one reference (no NPs) and one with 12 Ag NPs of mixed diameters (100–400 nm) sitting on top of a SiO2/Si stack — and comparing the results.
My structure (bottom to top):
- Si layer: 8 µm
- SiO2 layer: 300 nm
- Ag NPs sitting on SiO2 surface (diameters: 100, 200, 300, 400 nm mixed)
- Air: 4 µm
My simulation settings:
- 2D FDTD
- Plane wave source, injection axis: y, direction: Backward (downward)
- Source position:
Air_y_max - 200e-9(near top of Air) - Reflection monitor:
Air_y_max - 300e-9(just below source) - Transmission monitor:
Si_y_max - 1e-6(1 µm inside Si from top) - Boundary conditions: PML on all 4 sides
- Wavelength: 200–1000 nm
- Simulation time: 10000e-15 s
- Auto shutoff min: 1e-5
- Mesh accuracy: 2
- Material: Ag (Johnson and Christy), Si (Palik), SiO2 (Palik)
Post-processing:
`T = transmission("transmission"); R = transmission("reflection"); A = 1 - T - R;`Problem I am getting:
- Transmittance is negative (down to -0.55)
- Reflectance is negative (down to -0.9)
- Absorption (1-T-R) is greater than 1 (up to 2.5)
- T+R+A is not equal to 1 — it oscillates wildly
My questions:
- What is the correct sign convention for
transmission()function when using a Backward directed plane wave source? Should I use-transmission("transmission")ortransmission("transmission")? - Is my reflection monitor placement correct — just below the source? Or should it be above the source?
- Is my transmission monitor placement correct — 1 µm inside Si from the top? Or should it be near the bottom of Si?
- Should I use Periodic boundary conditions on x instead of PML for a plane wave source?
- Is
auto shutoff min = 1e-5sufficient for plasmonic Ag NP simulations or should it be tighter (1e-7)?
Any guidance would be very helpful. Thank you
-
March 2, 2026 at 5:23 pm
raano1
SubscriberHello,
I am simulating the effect of Ag nanoparticles (NPs) on light absorption in a Si solar cell structure using 2D FDTD in Lumerical. I am running two simulations — one reference (no NPs) and one with 12 Ag NPs of mixed diameters (100–400 nm) sitting on top of a SiO2/Si stack — and comparing the results.
My structure (bottom to top):
- Si layer: 8 µm
- SiO2 layer: 300 nm
- Ag NPs sitting on SiO2 surface (diameters: 100, 200, 300, 400 nm mixed)
- Air: 4 µm
My simulation settings:
- 2D FDTD
- Plane wave source, injection axis: y, direction: Backward (downward)
- Source position:
Air_y_max - 200e-9(near top of Air) - Reflection monitor:
Air_y_max - 300e-9(just below source) - Transmission monitor:
Si_y_max - 1e-6(1 µm inside Si from top) - Boundary conditions: PML on all 4 sides
- Wavelength: 200–1000 nm
- Simulation time: 10000e-15 s
- Auto shutoff min: 1e-5
- Mesh accuracy: 2
- Material: Ag (Johnson and Christy), Si (Palik), SiO2 (Palik)
Post-processing:
`T = transmission("transmission"); R = transmission("reflection"); A = 1 - T - R;`Problem I am getting:
- Transmittance is negative (down to -0.55)
- Reflectance is negative (down to -0.9)
- Absorption (1-T-R) is greater than 1 (up to 2.5)
- T+R+A is not equal to 1 — it oscillates wildly
My questions:
- What is the correct sign convention for
transmission()function when using a Backward directed plane wave source? Should I use-transmission("transmission")ortransmission("transmission")? - Is my reflection monitor placement correct — just below the source? Or should it be above the source?
- Is my transmission monitor placement correct — 1 µm inside Si from the top? Or should it be near the bottom of Si?
- Should I use Periodic boundary conditions on x instead of PML for a plane wave source?
- Is
auto shutoff min = 1e-5sufficient for plasmonic Ag NP simulations or should it be tighter (1e-7)?
Any guidance would be very helpful. Thank you
And here is my code
clear;
####################################################
# COMBINED SCRIPT: Reference + AgNP in ONE code
# Run 1: Air + SiO2 + Si (no NPs)
# Run 2: Air + Ag NPs + SiO2 + Si
##################################################### Layer thicknesses
Si_thickness = 8e-6;
SiO2_thickness = 300e-9;
Air_thickness = 4e-6;# Wavelength
lambda_min = 200e-9;
lambda_max = 1000e-9;# Mesh
mesh_accuracy = 2;
sim_time = 10000e-15;# Cell size
cell_x = 6e-6;# NP parameters
edge_gap = 100e-9;# NP radii in random order (12 NPs)
np_r1 = 50e-9;
np_r2 = 100e-9;
np_r3 = 200e-9;
np_r4 = 50e-9;
np_r5 = 150e-9;
np_r6 = 100e-9;
np_r7 = 50e-9;
np_r8 = 200e-9;
np_r9 = 150e-9;
np_r10 = 100e-9;
np_r11 = 50e-9;
np_r12 = 150e-9;# NP x positions
x1 = 0;
x2 = x1 + np_r1 + edge_gap + np_r2;
x3 = x2 + np_r2 + edge_gap + np_r3;
x4 = x3 + np_r3 + edge_gap + np_r4;
x5 = x4 + np_r4 + edge_gap + np_r5;
x6 = x5 + np_r5 + edge_gap + np_r6;
x7 = x6 + np_r6 + edge_gap + np_r7;
x8 = x7 + np_r7 + edge_gap + np_r8;
x9 = x8 + np_r8 + edge_gap + np_r9;
x10 = x9 + np_r9 + edge_gap + np_r10;
x11 = x10 + np_r10 + edge_gap + np_r11;
x12 = x11 + np_r11 + edge_gap + np_r12;x_cen = (x1 + x12) / 2;
x1=x1-x_cen; x2=x2-x_cen; x3=x3-x_cen; x4=x4-x_cen;
x5=x5-x_cen; x6=x6-x_cen; x7=x7-x_cen; x8=x8-x_cen;
x9=x9-x_cen; x10=x10-x_cen; x11=x11-x_cen; x12=x12-x_cen;# Y positions
Si_y_min = 0;
Si_y_max = Si_thickness;
SiO2_y_min = Si_y_max;
SiO2_y_max = SiO2_y_min + SiO2_thickness;
Air_y_min = SiO2_y_max;
Air_y_max = SiO2_y_max + Air_thickness;r_max = 200e-9;
margin_y = 500e-9;
sim_y_min = Si_y_min – margin_y;
sim_y_max = Air_y_max + margin_y;
sim_y_center = (sim_y_min + sim_y_max) / 2;
sim_y_span = sim_y_max – sim_y_min;source_y = Air_y_max – 200e-9;
refl_y = Air_y_max – 300e-9;
trans_y = Si_y_max – 1e-6;####################################################
# LOOP: sim=1 (reference), sim=2 (with NPs)
####################################################for (sim = 1:2) {
newproject;
############################################
# STRUCTURES (common)
############################################addrect;
set(“name”, “Si_film”);
set(“material”, “Si (Silicon) – Palik”);
set(“x”, 0);
set(“x span”, cell_x);
set(“y min”, Si_y_min);
set(“y max”, Si_y_max);addrect;
set(“name”, “SiO2_layer”);
set(“material”, “SiO2 (Glass) – Palik”);
set(“x”, 0);
set(“x span”, cell_x);
set(“y min”, SiO2_y_min);
set(“y max”, SiO2_y_max);############################################
# ADD NPs ONLY FOR sim=2
############################################if (sim == 2) {
addcircle;
set(“name”, “Ag_NP_01_d100”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x1); set(“y”, SiO2_y_max + np_r1); set(“radius”, np_r1);addcircle;
set(“name”, “Ag_NP_02_d200”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x2); set(“y”, SiO2_y_max + np_r2); set(“radius”, np_r2);addcircle;
set(“name”, “Ag_NP_03_d400”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x3); set(“y”, SiO2_y_max + np_r3); set(“radius”, np_r3);addcircle;
set(“name”, “Ag_NP_04_d100”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x4); set(“y”, SiO2_y_max + np_r4); set(“radius”, np_r4);addcircle;
set(“name”, “Ag_NP_05_d300”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x5); set(“y”, SiO2_y_max + np_r5); set(“radius”, np_r5);addcircle;
set(“name”, “Ag_NP_06_d200”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x6); set(“y”, SiO2_y_max + np_r6); set(“radius”, np_r6);addcircle;
set(“name”, “Ag_NP_07_d100”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x7); set(“y”, SiO2_y_max + np_r7); set(“radius”, np_r7);addcircle;
set(“name”, “Ag_NP_08_d400”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x8); set(“y”, SiO2_y_max + np_r8); set(“radius”, np_r8);addcircle;
set(“name”, “Ag_NP_09_d300”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x9); set(“y”, SiO2_y_max + np_r9); set(“radius”, np_r9);addcircle;
set(“name”, “Ag_NP_10_d200”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x10); set(“y”, SiO2_y_max + np_r10); set(“radius”, np_r10);addcircle;
set(“name”, “Ag_NP_11_d100”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x11); set(“y”, SiO2_y_max + np_r11); set(“radius”, np_r11);addcircle;
set(“name”, “Ag_NP_12_d300”); set(“material”, “Ag (Silver) – Johnson and Christy”);
set(“x”, x12); set(“y”, SiO2_y_max + np_r12); set(“radius”, np_r12);
}############################################
# FDTD (2D)
############################################addfdtd;
set(“dimension”, “2D”);
set(“x”, 0);
set(“x span”, cell_x);
set(“y”, sim_y_center);
set(“y span”, sim_y_span);
set(“x min bc”, “PML”);
set(“x max bc”, “PML”);
set(“y min bc”, “PML”);
set(“y max bc”, “PML”);
set(“mesh accuracy”, mesh_accuracy);
set(“simulation time”, sim_time);
set(“auto shutoff min”, 1e-5);############################################
# SOURCE
############################################addplane;
set(“name”, “source”);
set(“injection axis”, “y-axis”);
set(“direction”, “Backward”);
set(“x”, 0);
set(“x span”, cell_x);
set(“y”, source_y);
set(“wavelength start”, lambda_min);
set(“wavelength stop”, lambda_max);############################################
# MONITORS
############################################addpower;
set(“name”, “reflection”);
set(“monitor type”, “Linear X”);
set(“override global monitor settings”, 1);
set(“use source limits”, 1);
set(“frequency points”, 100);
set(“x”, 0);
set(“x span”, cell_x);
set(“y”, refl_y);addpower;
set(“name”, “transmission”);
set(“monitor type”, “Linear X”);
set(“override global monitor settings”, 1);
set(“use source limits”, 1);
set(“frequency points”, 100);
set(“x”, 0);
set(“x span”, cell_x);
set(“y”, trans_y);addprofile;
set(“name”, “field_xy”);
set(“override global monitor settings”, 1);
set(“use source limits”, 1);
set(“frequency points”, 10);
set(“x”, 0);
set(“x span”, cell_x);
set(“y”, sim_y_center);
set(“y span”, sim_y_span – 100e-9);############################################
# MESH OVERRIDE
############################################if (sim == 2) {
addmesh;
set(“name”, “mesh_NPs”);
set(“x”, 0);
set(“x span”, cell_x);
set(“y”, SiO2_y_max + r_max);
set(“y span”, 2*r_max + 40e-9);
set(“dx”, 10e-9);
set(“dy”, 10e-9);
}addmesh;
set(“name”, “mesh_SiO2”);
set(“x”, 0);
set(“x span”, cell_x);
set(“y”, SiO2_y_min + SiO2_thickness/2);
set(“y span”, SiO2_thickness + 40e-9);
set(“dy”, 10e-9);############################################
# SAVE AND RUN
############################################if (sim == 1) {
save(“Combined_Reference.fsp”);
?””;
?”=== RUNNING SIMULATION 1: REFERENCE (no NPs) ===”;
} else {
save(“Combined_WithAgNP.fsp”);
?””;
?”=== RUNNING SIMULATION 2: WITH 12 Ag NPs ===”;
}run;
}
?””;
?”=== BOTH SIMULATIONS COMPLETE ===”;
?”Open Combined_Reference.fsp and Combined_WithAgNP.fsp to view results.”;
also result post processing codeclear;
####################################################
# POST-PROCESSING SCRIPT
# Load Reference and AgNP simulation results
# Compute T, R, A and plot comparisons
####################################################?”=== LOADING REFERENCE SIMULATION ===”;
load(“Combined_Reference.fsp”);
run;f = getdata(“transmission”, “f”);
lam = c / f;T_ref = transmission(“transmission”);
R_ref = transmission(“reflection”);
A_ref = 1 – T_ref – R_ref;?”Reference loaded. T, R, A extracted.”;
####################################################
?”=== LOADING AgNP SIMULATION ===”;
load(“Combined_WithAgNP.fsp”);
run;T_np = transmission(“transmission”);
R_np = transmission(“reflection”);
A_np = 1 – T_np – R_np;?”AgNP loaded. T, R, A extracted.”;
####################################################
# COMPARISON PLOTS
####################################################?””;
?”=== GENERATING COMPARISON PLOTS ===”;# — Transmittance Comparison —
plot(lam*1e9, T_ref, T_np, “Wavelength (nm)”, “Transmittance”, “Transmittance Comparison”);
legend(“Reference (no NPs)”, “With Ag NPs”);
exportfigure(“Compare_Transmittance.png”, 800, 600);# — Reflectance Comparison —
plot(lam*1e9, R_ref, R_np, “Wavelength (nm)”, “Reflectance”, “Reflectance Comparison”);
legend(“Reference (no NPs)”, “With Ag NPs”);
exportfigure(“Compare_Reflectance.png”, 800, 600);# — Absorption Comparison —
plot(lam*1e9, A_ref, A_np, “Wavelength (nm)”, “Absorption (1-T-R)”, “Absorption Comparison”);
legend(“Reference (no NPs)”, “With Ag NPs”);
exportfigure(“Compare_Absorption.png”, 800, 600);# — T+R+A = 1 Check (should be flat line at 1) —
plot(lam*1e9, T_ref+R_ref+A_ref, T_np+R_np+A_np, “Wavelength (nm)”, “T+R+A”, “Energy Conservation Check”);
legend(“Reference”, “With Ag NPs”);
exportfigure(“EnergyConservation_Check.png”, 800, 600);# — Transmittance Enhancement (T_NP / T_ref) —
T_Enhancement = T_np / T_ref;
plot(lam*1e9, T_Enhancement, “Wavelength (nm)”, “T_NP / T_ref”, “Transmittance Enhancement”);
exportfigure(“Transmittance_Enhancement.png”, 800, 600);# — Absorption Enhancement (A_NP / A_ref) —
A_Enhancement = A_np / A_ref;
plot(lam*1e9, A_Enhancement, “Wavelength (nm)”, “A_NP / A_ref”, “Absorption Enhancement”);
exportfigure(“Absorption_Enhancement.png”, 800, 600);# — Absorption Difference (Delta A) —
Delta_A = A_np – A_ref;
plot(lam*1e9, Delta_A, “Wavelength (nm)”, “Delta A = A_NP – A_ref”, “Absorption Increase due to Ag NPs”);
exportfigure(“Absorption_Difference.png”, 800, 600);# — Complete Comparison (T, R, A together) —
plot(lam*1e9, T_ref, T_np, R_ref, R_np, A_ref, A_np, “Wavelength (nm)”, “Value”, “Complete T R A Comparison”);
legend(“T (ref)”, “T (NP)”, “R (ref)”, “R (NP)”, “A (ref)”, “A (NP)”);
exportfigure(“Complete_Comparison.png”, 800, 600);####################################################
# RESULTS SUMMARY
####################################################?””;
?”=== RESULTS SUMMARY ===”;
?””;
?”— Transmittance —“;
?”Avg T (ref) : ” + num2str(mean(T_ref));
?”Avg T (NP) : ” + num2str(mean(T_np));
?”Avg T Enhancement : ” + num2str(mean(T_Enhancement));
?”Max T Enhancement : ” + num2str(max(T_Enhancement));
?”Min T Enhancement : ” + num2str(min(T_Enhancement));
?””;
?”— Reflectance —“;
?”Avg R (ref) : ” + num2str(mean(R_ref));
?”Avg R (NP) : ” + num2str(mean(R_np));
?””;
?”— Absorption (1-T-R) —“;
?”Avg A (ref) : ” + num2str(mean(A_ref));
?”Avg A (NP) : ” + num2str(mean(A_np));
?”Avg A Enhancement : ” + num2str(mean(A_Enhancement));
?”Max A Enhancement : ” + num2str(max(A_Enhancement));
?”Avg Delta A : ” + num2str(mean(Delta_A));
?”Max Delta A : ” + num2str(max(Delta_A));
?””;
?”=== ALL DONE! 8 plots saved ===”; -
March 2, 2026 at 11:39 pm
Kirill
Forum ModeratorHello @raano1,
Thank for the detailed explanation.
1. Negative values indicate that the power is flowing in the negative direction of the axis (see the transmission - Script command). Please adjust the sign based on the expected direction of the flux.
2. The DFT monitor captures all fields, and when placed below the source, it will also record the source field. There are ways to address this, but placing the monitor above the source is often a simpler and cleaner approach. Please also keep in mind that the PML boundaries will absorb energy.
3. There is no single correct answer here; it depends on where you want to measure the transmission. As the field propagates deeper into the film, it may be absorbed by the material itself as well as by the PML boundaries.
4. Again, this depends on what you want to achieve. If your structure assumes periodicity, consider using Periodic or Bloch Boundary Conditions. See, for example, Periodic boundary conditions in FDTD and MODE.
5. 1e-05 is the default autoshutoff value and may provide sufficient accuracy without requiring the simulation to run for the full simulation time, if it converges early. The key point is whether the simulation converges.
Please check the FDTD simulation status:
0 – simulation in layout mode
1 – ran to full simulation time
2 – ran to autoshutoff
3 – divergedsee FDTD solver - Simulation Object.
Ideally, you want to see a status of 2. For resonant or layered structures, convergence may require longer simulation times, improved material fits, finer mesh, etc., see Convergence testing process for FDTD simulations. You can also use a time monitor or movie monitor to verify that the fields have completely decayed by the end of the simulation; otherwise, the frequency-domain results may not be reliable.
Best regards,
Kirill
-
- You must be logged in to reply to this topic.
-
6660
-
1906
-
1469
-
1313
-
1022
© 2026 Copyright ANSYS, Inc. All rights reserved.