A Python + COMSOL skill for 2-D rectangular grating diffraction simulations, producing total R/T and per-order R_m/T_m efficiencies via the validated full-field + Periodic Port + Floquet + TE recipe.
comsol-skill/
├── README.md ← you are here
├── SKILL.md ← agent-facing usage spec
├── BUGS_AND_FIXES.md ← 9 known API gotchas with fixes
├── COMSOL_MATLAB_Pitfalls_Guide.md ← legacy notes (mostly superseded)
└── grating-skill/
├── comsol_grating_template.py ← the main script
├── example_config.json ← minimal example: edit and run
├── example_run.bat ← double-click to run on Windows
└── requirements.txt ← Python deps
-
Install dependencies (one-time):
pip install -r grating-skill/requirements.txt
You also need a licensed COMSOL Multiphysics 6.x with the Wave Optics module.
-
Copy
grating-skill/somewhere writable (it produces .mph and .mat next to itself). -
Edit
example_config.jsonto your simulation case:lambda_nm,theta_degperiod_nm,duty_cycle,d_groove_nm,n_toothlayer_stack: list of[thickness_nm, n, label]from substrate up
-
Run:
cd grating-skill python comsol_grating_template.py --config example_config.jsonOr on Windows: double-click
example_run.bat. -
Read results:
<prefix>_orders.csv— open in Excel for a quick per-order look<prefix>.mat— load in MATLAB or Python for further analysis<prefix>.mph— open in COMSOL GUI for field visualization
For one input config, three files. Example with out_prefix="grating",
N_teeth=1, theta_deg=0:
| File | Size | Purpose |
|---|---|---|
grating_N1_theta0.00.mph |
~10–25 MB | Solved COMSOL model |
grating_N1_theta0.00.mat |
~50 KB | Efficiencies + spectrum (R, T, R_m, T_m) |
grating_N1_theta0.00_orders.csv |
~1 KB | Plain-text per-order table |
Console output gives an immediate summary:
[INFO] === Grating: N_teeth=1, theta=0 deg, lambda=1053 nm, W=500 nm ===
[INFO] propagating orders: top air=3 (-1..1), bot substrate n=1.46: 5 (-2..2)
[INFO] total ports: 8
[INFO] mesh elements: 12384
[INFO] solving ...
[INFO] solved.
[RESULT] R=0.21345 T=0.78655 R+T=1.00000
[INFO] top-3 reflected orders:
m= 0 eta=0.21345 sin_t=+0.0000
m= +1 eta=...
[CHECK] Poynting net flux: top=-0.21344 W/m, bot=-0.78656 W/m
The R+T = 1.00000 line is your sanity check: for lossless materials it
must be 1.0 to ~5 digits. If it isn't, something is wrong — see
BUGS_AND_FIXES.md or rerun with finer mesh.
It corrects 9 distinct bugs documented in BUGS_AND_FIXES.md that affect
naive implementations of grating models in COMSOL via mph. Most importantly:
- It uses full-field + Periodic Port instead of scattered-field + SBC (the old route loses 5–25% of energy at large angles).
- It correctly switches the physics interface to TE via
ewfd.prop("components").set("components", "outofplane")(lowercase!) — a typicalewfd.property("Components", "OutofPlane")call silently fails on mph and runs TM instead. - It explicitly sets each Port's
E0 = [0, 0, 1]to force E along z. The defaultE0 = "t1x"puts E in-plane = TM.
This recipe was validated end-to-end on a 66-case sweep with R+T = 1.00000 to better than 1×10⁻⁵ in every case. See SKILL.md for the validation provenance.
SKILL.md— full agent-facing usage spec, with input fields, output schema, and three concrete config examples (RCWA single-period, anti-reflection grating, comb supercell).BUGS_AND_FIXES.md— every known API gotcha that the template defends against, with symptom / cause / fix triples.COMSOL_MATLAB_Pitfalls_Guide.md— older notes (predates v4_TE recipe). Sections 1, 2 (Box selection rules) are still correct; section 3 (scattered-field truncation) is wrong — see BUGS_AND_FIXES.md Bug-1.
See LICENSE if present, otherwise treat as project-internal.