Metal 2D Foundry: Evaluate Objective from an Image
@meta EditURL = "https://github.com/ianmatthewhammond/DistributedEmitterOpt.jl/tree/main/docs/src/examples/metal2dimage_eval.jl"
This example evaluates the SERS objective for a fixed metal design specified by a grayscale image (metal = 1, void = 0). No optimization is performed.
using DistributedEmitterOpt
using LinearAlgebraOptional (if you want to load an image): using FileIO, ImageIO, ImageTransformations, ColorTypes
1. Mesh + simulation (foundry mode)
λ = 532.0
geo = SymmetricGeometry(λ; L=200.0, W=200.0, hd=120.0, hsub=60.0)
geo.l1 = 40.0
geo.l2 = 20.0
geo.l3 = 40.0
outdir = mktempdir()
meshfile = joinpath(outdir, "mesh.msh")
genmesh(geo, meshfile; per_x=true, per_y=true)
sim = build_simulation(meshfile; foundry_mode=true, dir_x=false, dir_y=false)2. Physics + objective (elastic, isotropic)
env = Environment(mat_design="Ag", mat_substrate="Ag", mat_fluid=1.33)
inputs = [FieldConfig(λ; θ=0.0, pol=:y)]Empty outputs => elastic scattering
pde = MaxwellProblem(env=env, inputs=inputs, outputs=FieldConfig[])
objective = SERSObjective(
αₚ=Matrix{ComplexF64}(I, 3, 3),
volume=true,
surface=false,
use_damage_model=false
)
control = Control(
use_filter=true,
R_filter=(20.0, 20.0, 20.0),
use_dct=true, # DCT filtering for 2D foundry mode
use_projection=true,
β=8.0,
η=0.5,
use_ssp=true
)
prob = OptimizationProblem(pde, objective, sim, UmfpackSolver();
foundry_mode=true,
control=control,
root=outdir
)3. Load design from image (grayscale)
The image should be normalized so 1.0 = metal, 0.0 = void.
img = load("design.png") imggray = channelview(colorview(Gray, img)) imgresized = imresize(imggray, (length(sim.grid.x), length(sim.grid.y))) pimg = clamp.(Float64.(img_resized), 0.0, 1.0)
If your image uses white=void, invert it: pimg = 1 .- pimg
If the pattern looks transposed or flipped, try: pimg = reverse(permutedims(pimg), dims=2)
Placeholder: simple radial pattern (replace with image data)
nx, ny = length(sim.grid.x), length(sim.grid.y)
x = range(-1.0, 1.0, length=nx)
y = range(-1.0, 1.0, length=ny)
p_img = [sqrt(xi^2 + yj^2) < 0.4 ? 1.0 : 0.0 for xi in x, yj in y]4. Evaluate objective (no optimization)
prob.p .= vec(p_img)Evaluate objective + gradient (If you only need g, pass an empty gradient vector to objectiveandgradient!)
g, ∇g = evaluate(prob, prob.p)
println("Objective value = ", g)This page was generated using Literate.jl.