Package: fdfdpy
![](img/dipole_dielectric_field.png)# fdfdpyThis is a pure Python implementation of the finite difference frequency domain (FDFD) method. It makes use of scipy, numpy, matplotlib, and the MKL Pardiso solver. fdfdpy currently supports 2D geometries## Installationpython setup.py install## Structure### InitializationTheFdfdclass is initialized assimulation = Fdfd(omega, eps_r, dl, NPML, pol, L0)omega: the angular frequency in units of` 2 pi / seconds`eps_r: a numpy array specifying the relative permittivity distributiondl: the spatial grid size in units ofL0NPML: defines number of PML grids[# on x borders, # on y borders]pol: polarization, one of{‘Hz’,’Ez’}wherezis the transverse field.L0: simulation length scale, default is 1e-6 meters (one micron)Creating a new Fdfd object solves for:xrange: defines spatial domain in x [left-most position, right-most position] in units ofL0yrange: defines spatial domain in y [bottom-most position, top-most position] in units ofL0A: the Maxwell operator, which is used later to solve for the E&M fields.derivs: dictionary storing the derivative operators.It also creates a relative permeability,mu_r, asnumpy.ones(eps_r.shape)and a sourcesrcasnumpy.zeros(eps_r.shape).### Adding sources is exciting!Sources can be added to the simulation either by manually editing the 2D src array inside of the simulation object,simulation.src[10,20:30] = 1or by adding modal sources, which are defined as planes within the 2D domain which launch a mode in their normal direction. Modal source definitions can be added to the simulation bysimulation.add_mode(neff, direction, center, width)
simulation.setup_modes()neff: defines the effective index of the mode; this will be used as the eigenvalue guessdirection: defines the normal direction of the plane, should be either ‘x’ or ‘y’center: defines the center coordinates for the plane in cell coordinates [xc, yc]width: defines the width of the plane in number of cellsNote thatsimulation.setup_modes()must always be called after adding mode(s) in order to populatesimulation.src.### Solving for the electromagnetic fieldsNow, we have everything we need to solve the system for the electromagnetic fields, by runningfields = simulation.solve_fields(timing=False)simulation.srcis proportional to either theJzorMzsource term, depending on whetherpolis set to‘Ez’or‘Hz’, respectively.fieldsis a tuple containing(Ex, Ey, Hz)or(Hx, Hy, Ez)depending on the polarization.### Setting a new permittivityIf you want to change the permittivity distribution, you may runsimulation.reset_eps(new_eps)And this will reconstruct the system matrix and store it inFDFD. Note thatsimulation.setup_modes()should also be called if the permittivity changed within the plane of any of the modal sources.### PlottingPrimary fields (Hz/Ez) can be visualized using the included helper functions:simulation.plt_re(outline=True, cbar=True)
simulation.plt_abs(outline=True, cbar=True)These optionally outline the permittivity with contours and can be supplied with a matplotlib axis handle to plot into.### RequirementsnumpyscipymatplotlibTo load the MKL solver:git submodule update –init –recursive### To Do#### Whenever
- [x] Modal source.
- [x] More dope plotting methods.
- [ ] xrange, yrange labels on plots.
- [ ] set modal source amplitude (and normalization)
- [ ] Add ability to run local jupyter notebooks running FDFD on parallel from hera.
- [ ] Save the factorization ofAin theFdfdobject to be reused later if one has the sameAbut a differentb.
- [ ] Allow the source term to have(Jx, Jy, Jz, Mx, My, Mz), which would be useful for adjoint stuff where the source is not necessarily along thezdirection.
- [ ] Clean up imports (e.g.import numpy as nptofrom numpy import abs, zeros, …)