Welcome to pyGDM¶
pyGDM is an open source python toolkit for electro-dynamical simulations. It is written in pure python and implements the Green dyadic method (GDM), a volume discretization technique, suited for single particle nano-optics simulations. pyGDM is based on simulation codes and theoretical models developed over the past 20 years by Christian Girard at CEMES (see e.g. Ch. Girard 2005 Rep. Prog. Phys. 68 1883), with contributions from G. Colas des Francs, A. Arbouet, R. Marty, P.R. Wiecha and C. Majorel. In contrast to most other coupled-dipole codes, pyGDM uses a generalized propagator, which allows to cost-efficiently treat large monochromatic problems such as angle-of-incidence scans or raster-scan simulations.
pyGDM includes tools to easily derive several physical quantities such as extinction, scattering and absorption cross-sections, far-field patterns, the electric and magnetic near-field or the the decay-rate / LDOS inside and in the vicinity of a structure, or the heat dissipated by a nanoparticle. pyGDM furthermore offers a toolkit for evolutionary optimization of nanoparticle geometries: The EO module allows to automatically design nanostructures which optimize optical properties such as a certain resonance wavelength, strong field enhancement or the direction of scattering.
Please send comments, suggestions and report bugs by mail or via the gitlab issue tracker
Easy to install and easy to use. Since v1.1: pure python. Fully relying on freely available open-source python libraries (numpy, numba, scipy, matplotlib)
Enables electro-dynamical simulations including a substrate
Different illumination sources such as plane wave, tightly focused gaussian beam or local dipolar emitter sources. Easy to implement own light sources in python
Efficient calculation of large monochromatic problems (raster-scan simulations, multiple polarizations / multiple angles of incidence)
Fast electron simulations (EELS, cathodoluminescence)
Provide tools to rapidly post-process the simulations and derive physical quantities such as
optical chirality of the near-field
decay-rate modification of dipole emitters / LDOS
Many easy to use visualization tools, including animations of the electro-magnetic fields
Evolutionary optimization of the nano-particle geometry with regards to specific optical properties
About the above animation¶
The animation at the top of this page was generated from the image
with the below script.
In the script the pyGDM function structures.image_to_struct is used to convert the bitmap pixel by pixel into a planar nano-structure: Every pixel darker than a specific threshold will be considered material (gold in the below example), all brighter pixels are part of the environment. The planar structure is then discretized on a cubic mesh using a pre-defined scaling and structure height. The time-harmonic electric field inside the gold-letter structure resulting from plane wave illumination is then calculated using pyGDM’s core.scatter and finally converted into a movie with visu.animate_vectorfield.
The structure is approximately 1100nm long, 300nm wide and 8nm high (one layer of meshpoints). It is made of gold, placed in vacuum and illuminated from your position towards the computer screen by a plane wave of 700nm wavelength, linearly polarized along 45°.
All other videos in this documentation are showing planar aluminum structures using a discretization of 5nm under 700nm wavelength plane wave illumination with -45° linear polarization. Aluminum has a far higher imaginary part of the dielectric function, which causes high losses due to absorption inside the metal. Due to these losses, the fields decay very quickly which looks “smoother”, which is why we use it in the here shown videos.
## --- load pyGDM from pyGDM2 import structures from pyGDM2 import materials from pyGDM2 import fields from pyGDM2 import core from pyGDM2 import propagators from pyGDM2 import tools from pyGDM2 import visu import matplotlib.pyplot as plt #=============================================================== # Setup the simulation #=============================================================== ## --- structure step = 8.0 geometry = structures.image_to_struct("pyGDM_logo_static.png", useDarkPixel=1, threshold=100, H=1, nm_per_pixel=1.*step, stepsize=step) material = materials.gold() struct = structures.struct(step, geometry, material) ## --- incident field field_generator = fields.plane_wave kwargs = dict(theta=45.0) wavelengths =  efield = fields.efield(field_generator, wavelengths=wavelengths, kwargs=kwargs) ## --- vacuum environment dyads = propagators.DyadsQuasistatic123(n1=1) ## --- simulation object sim = core.simulation(struct, efield, dyads) #=============================================================== # Run the simulation #=============================================================== E = core.scatter(sim) NF = tools.get_field_as_list_by_fieldindex(sim, 0) #=============================================================== # create the field-animation #=============================================================== ## setup figure / axes plt.figure(figsize=(6.0,2.5)) ax = plt.subplot(aspect='equal') plt.axis('off') plt.subplots_adjust(left=0, right=1, bottom=0,top=1) ## geometry s = visu.structure(sim, scale=0.1, color='.75', show=0) ## field-animation config_vectorfield = dict(cmin=0.5, cmap=plt.cm.Blues, borders=5, vecwidth=0.8) ani = visu.animate_vectorfield(NF, Nframes=100, scale=12, kwargs=config_vectorfield, ax=ax, show=False) ## save video to file ani.save('pyGDM_logo.mp4', writer="ffmpeg", codec='h264', bitrate=1500)
Similarly, 3D visualizations of the fields can be animated using:
from pyGDM2 import visu3d from mayavi import mlab fig = mlab.figure( size=(600, 300), bgcolor=(1.0, 1.0, 1.0), fgcolor=(0.,0.,0.) ) ## structure visu3d.structure(sim, axis_labels=False, draw_substrate=False, opacity=0.1, show=False) ## 3D field-animation ani2 = visu3d.animate_vectorfield(NF, Nframes=100, scale=8, draw_struct=False, draw_substrate=False, substrate_size=1.1, colormap='Blues', clim=[0.0, 0.5], fig=fig, view=(85, -45, 350, (0,0,-15)), ffmpeg_args="-b:v 1.5M -c:v libx264", mov_file="3D.mp4", save_anim=True, opacity=0.5)
which (depending on the model of course) will result in something like: