Types
Core data structures for problem definition and state management.
Problem Definition
DistributedEmitterOpt.FieldConfig — Type
FieldConfigConfiguration for a single field solve (frequency, angle, polarization).
DistributedEmitterOpt.Environment — Type
Environment(; mat_design, mat_substrate=mat_design, mat_fluid=1.33)Fields
mat_design— Design region material (typically metal)mat_substrate— Substrate material (defaults to mat_design)mat_fluid— Fluid/background material (default 1.33 for water)
DistributedEmitterOpt.MaxwellProblem — Type
MaxwellProblemPDE definition for Maxwell curl-curl equation. Specifies the physical environment, input/output field configurations, and solver parameters.
This type describes WHAT to solve (environment + configs), not HOW to solve (that's in simulation + caches).
ObjectiveFunction Interface
DistributedEmitterOpt.ObjectiveFunction — Type
ObjectiveFunctionAbstract type for optimization objectives. Implementations define how to compute the objective value and gradients from field solutions.
Required interface
compute_objective(obj, pde, fields, pt, sim)— Objective value gcompute_adjoint_sources(obj, pde, fields, pt, sim)— ∂g/∂E for each fieldexplicit_sensitivity(obj, pde, fields, pf, pt, sim, control)— Explicit ∂g/∂pf
Fields is a Dict{CacheKey, CellField} mapping (λ, θ, pol) → E. pde provides the input/output FieldConfig lists and weights.
DistributedEmitterOpt.compute_objective — Function
compute_objective(obj::SERSObjective, pde, fields, pt, sim) → Float64Compute SERS objective using trace formula. Sums over all input/output combinations with their weights.
DistributedEmitterOpt.compute_adjoint_sources — Function
compute_adjoint_sources(obj::SERSObjective, pde, fields, pt, sim) → Dict{CacheKey, Vector}Compute adjoint RHS vectors ∂g/∂E for each field. Sums contributions over all input/output combinations with weights.
DistributedEmitterOpt.explicit_sensitivity — Function
Default: no explicit sensitivity term.
explicit_sensitivity(obj::SERSObjective, pde, fields, pf, pt, sim, control; space=sim.Pf) → VectorExplicit ∂g/∂pf term from objective's direct dependence on pt. Sums contributions over all input/output combinations with weights.
Optimization Problem
The main entry point. Use the meshfile-based constructor for most cases:
prob = OptimizationProblem(pde, objective, meshfile, solver; per_x, per_y, foundry_mode, control)This automatically creates a SimulationBundle with simulations for both x and y polarizations.
DistributedEmitterOpt.OptimizationProblem — Type
OptimizationProblemMain container for topology optimization. Holds the PDE config, objective, FEM infrastructure, solver caches, and current optimization state.
DistributedEmitterOpt.init_uniform! — Function
Set all design parameters to value.
DistributedEmitterOpt.init_random! — Function
Randomize design parameters.
DistributedEmitterOpt.init_from_file! — Function
Load design parameters from a file.
Simulation Infrastructure
A Simulation holds the FEM infrastructure (spaces, measures, mesh). A SimulationBundle groups simulations by polarization for mixed-polarization problems.
DistributedEmitterOpt.Simulation — Type
SimulationContainer for all FEM infrastructure: discrete model, function spaces, integration measures, and FoundryGrid for 2D DOF mode.
FE Spaces
V,U— Nédélec spaces for E-fieldP— Piecewise constant (raw design on mesh)Pf— Continuous Lagrange (filtered design)
Integration Measures
dΩ— Full domaindΩ_design— Design regiondΩ_raman— Raman/target regiondS_top,dS_bottom— ABC boundariesdΓ_source— Source plane
DistributedEmitterOpt.build_simulation — Function
build_simulation(meshfile; kwargs...) -> SimulationBuild Simulation from mesh file.
Arguments
meshfile— Path to .msh fileorder— Nédélec element order (default 0)degree— Quadrature degree (default 4)dir_x,dir_y— Dirichlet boundaries for PEC symmetrysource_y— Source polarization (true=y, false=x)foundry_mode— Use 2D DOF gridsizes— Manual (xlo, xhi, ylo, yhi, zlo, zhi) for grid
DistributedEmitterOpt.SimulationBundle — Type
SimulationBundleContainer for multiple Simulation objects (per polarization), sharing the same underlying discrete model.
Fields
default::Simulation: The primary simulation (usually y-polarized)by_pol::Dict{Symbol,Simulation}: Sims keyed by polarization (:x, :y)
DistributedEmitterOpt.build_simulation_bundle — Function
build_simulation_bundle(meshfile; per_x=false, per_y=false, kwargs...)Build a polarization-aware SimulationBundle with shared discrete model.
DistributedEmitterOpt.default_sim — Function
default_sim(sim_or_bundle)Get the default Simulation from a Simulation or SimulationBundle.
DistributedEmitterOpt.sim_for — Function
sim_for(sim_or_bundle, fc::FieldConfig)Get the appropriate Simulation for a given FieldConfig (based on polarization).
Solver Caches
Caches for LU factorizations, keyed by wavelength. SolverPoolBundle mirrors SimulationBundle for polarization-aware caching.
DistributedEmitterOpt.AbstractSolver — Type
AbstractSolverInterface for sparse direct solvers. Concrete implementations wrap Pardiso, UMFPACK, etc.
Required interface
lu!(cache, A)— Factorize matrix Asolve!(cache, b)— Solve Ax = b (forward)solve_adjoint!(cache, b)— Solve A'x = b (adjoint)
DistributedEmitterOpt.UmfpackSolver — Type
UMFPACK-based solver.
DistributedEmitterOpt.SolverCache — Type
SolverCache{S<:AbstractSolver}Caches LU factorizations for reuse across optimization iterations. Separate caches for:
- Maxwell system (complex, A_factor)
- Eigen shift system (complex, Afactor in eigencache)
- Filter PDE (real, F_factor)
Fields
A_factor— Maxwell LU factorizationF_factor— Filter Helmholtz LU factorizationE2_factor— E² regularization LU factorization (optional)x— Solution vector cacheam_head— True if this process performs solves (MPI compatibility)solver— Solver backend
DistributedEmitterOpt.SolverCachePool — Type
SolverCachePool{S<:AbstractSolver}Pool of solver caches, one per unique (λ, θ, polarization) configuration. Deduplicates caches so identical configs share the same LU factorization.
Also holds a shared filter cache and a shared eigen cache for shift-invert solves.
DistributedEmitterOpt.SolverPoolBundle — Type
SolverPoolBundleContainer for multiple SolverCachePool objects (per polarization), corresponding to the Simulation objects in a bundle.
Fields
default::SolverCachePool: The primary poolby_pol::Dict{Symbol,SolverCachePool}: Pools keyed by polarization (:x, :y)
DistributedEmitterOpt.get_cache! — Function
Get or create cache for a field config.
Get cache by key directly.
DistributedEmitterOpt.clear_maxwell_factors! — Function
Clear all Maxwell factorizations (call when pt changes).
clear_maxwell_factors!(pool)Clear LU factors for single or bundled pools.
DistributedEmitterOpt.default_pool — Function
default_pool(pool_or_bundle)Get the default SolverCachePool from a pool or bundle.
DistributedEmitterOpt.pool_for — Function
pool_for(pool_or_bundle, fc::FieldConfig)Get the appropriate SolverCachePool for a given FieldConfig.
Foundry Grid (2D DOF Mode)
DistributedEmitterOpt.FoundryGrid — Type
FoundryGrid2D rectilinear grid for lithography-compatible topology optimization. Design parameters live on a regular (x, y) grid and are interpolated to the 3D FEM mesh via bilinear interpolation.
Fields
x— Grid x-coordinates (monotonic)y— Grid y-coordinates (monotonic)params— Design parameter matrix (nx × ny)nodes— Mesh node coordinates for Jacobian computationjacobian— Cached ∂(mesh node values)/∂(grid param) mappingadj_idx— Cached grid indices for adjoint scatter (4 × nnodes)adj_w— Cached weights for adjoint scatter (4 × nnodes)adj_ready— Whether adjoint cache is initialized
DistributedEmitterOpt.getgrid — Function
getgrid(labels, Ω, np, nodes; sizes=nothing) -> FoundryGridBuild a FoundryGrid from mesh topology. The grid covers the x-y extent of the design region with approximately √np points per side.
DistributedEmitterOpt.pf_grid — Function
pf_grid(r, params, gridx, gridy) -> RealBilinear interpolation of grid parameters at point r = (x, y, z).
Convenience method using FoundryGrid.
Control Parameters
DistributedEmitterOpt.Control — Type
ControlHyperparameters for the topology optimization pipeline: filtering, projection, and linewidth constraints.
Filtering
use_filter— Enable filtering stepR_filter— Filter radius (rx, ry, rz) in nmuse_dct— Use DCT convolution (true) or Helmholtz PDE (false)
Projection / SSP
- SSP on the FEM mesh is always used (pf → pt).
β— Projection steepness (higher = sharper, use continuation)η— Threshold point (typically 0.5)R_ssp— SSP smoothing radius
Linewidth Constraints
use_constraints— Enable erosion/dilation constraintsη_erosion— Erosion threshold (typically 0.75)η_dilation— Dilation threshold (typically 0.25)b1— Constraint tolerancec0— Indicator function steepness
DistributedEmitterOpt.tanh_projection — Function
tanh_projection(x, η, β) -> RealHeaviside-ish projection: smooth step from 0 to 1 centered at η. As β → ∞, approaches true Heaviside function.
Vectorized tanh projection for arrays.
Convenience with Control struct.
DistributedEmitterOpt.Threshold — Function
Threshold(pf; control) -> RealTanh projection for lazy composition with Gridap's ∘ operator. This is the function form used in ComposedFunctions.
Reference: Old codebase Controls.jl:Threshold