Gold nano-sphere

01/2021: updated to pyGDM v1.1+

Comparing pyGDM to Mie theory for a gold nano-sphere (D=50nm).


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 linear
from pyGDM2 import visu

import numpy as np
import matplotlib.pyplot as plt

## --- load pre-calculated Mie-data
wl_mie, qext_mie, qsca_mie = np.loadtxt("scat_mie_Au_D50nm.txt").T
qabs_mie = qext_mie - qsca_mie

Simulation setup

## --- Setup incident field
field_generator = fields.planewave
## log-interval spectrum (denser at low lambda):
wavelengths = np.exp(np.linspace(np.log(300), np.log(1000), 30))
kwargs = dict(theta = [0.0])
efield = fields.efield(field_generator, wavelengths=wavelengths,

## --- Setup geometry (sphere D=50nm)
scale_factor = 1.38
step = 6.25/scale_factor
radius = 4.*scale_factor
geometry = structures.sphere(step, R=radius, mesh='hex', ORIENTATION=2)

material =

struct = structures.struct(step, geometry, material)

## --- Setup environment (vacuum)
n1, n2 = 1.0, 1.0     # vacuum env.
dyads = propagators.DyadsQuasistatic123(n1, n2)

sim = core.simulation(struct, efield, dyads)

print('(hex) ----- N_dipoles =', len(sim.struct.geometry), end='')
structure initialization - automatic mesh detection: hex
structure initialization - consistency check: 1111/1111 dipoles valid
/home/hans/.local/lib/python3.8/site-packages/pyGDM2/ UserWarning: 3D data. Falling back to XY projection...
  warnings.warn("3D data. Falling back to XY projection...")
(hex) ----- N_dipoles = 1111

Run the simulation

## main simulation

## extinction spectrum
field_kwargs = tools.get_possible_field_params_spectra(sim)[0]
wl, spec = tools.calculate_spectrum(sim, field_kwargs, linear.extinct)
a_ext, a_sca, a_abs = spec.T
a_geo = tools.get_geometric_cross_section(sim)
/home/hans/.local/lib/python3.8/site-packages/numba/core/ UserWarning: Numba extension module 'numba_scipy' failed to load due to 'ValueError(No function '__pyx_fuse_0pdtr' found in __pyx_capi__ of 'scipy.special.cython_special')'.
timing for wl=300.00nm - setup: EE 13284.4ms, inv.: 4527.5ms, repropa.: 1862.3ms (1 field configs), tot: 19674.8ms
timing for wl=312.72nm - setup: EE 911.8ms, inv.: 6771.9ms, repropa.: 15.1ms (1 field configs), tot: 7702.6ms
timing for wl=325.97nm - setup: EE 258.5ms, inv.: 2074.0ms, repropa.: 23.3ms (1 field configs), tot: 2359.3ms
timing for wl=339.79nm - setup: EE 336.9ms, inv.: 1916.8ms, repropa.: 13.3ms (1 field configs), tot: 2267.6ms
timing for wl=354.20nm - setup: EE 243.4ms, inv.: 1510.4ms, repropa.: 12.4ms (1 field configs), tot: 1768.6ms
timing for wl=369.21nm - setup: EE 224.8ms, inv.: 1598.5ms, repropa.: 12.5ms (1 field configs), tot: 1836.4ms
timing for wl=384.86nm - setup: EE 234.6ms, inv.: 4438.9ms, repropa.: 23.8ms (1 field configs), tot: 4703.9ms
timing for wl=401.17nm - setup: EE 794.2ms, inv.: 4267.2ms, repropa.: 28.9ms (1 field configs), tot: 5091.8ms
timing for wl=418.18nm - setup: EE 771.5ms, inv.: 4049.0ms, repropa.: 32.7ms (1 field configs), tot: 4860.3ms
timing for wl=435.91nm - setup: EE 628.8ms, inv.: 1935.9ms, repropa.: 12.3ms (1 field configs), tot: 2577.8ms
timing for wl=454.39nm - setup: EE 275.9ms, inv.: 1699.5ms, repropa.: 12.1ms (1 field configs), tot: 1989.5ms
timing for wl=473.65nm - setup: EE 246.3ms, inv.: 1721.3ms, repropa.: 17.1ms (1 field configs), tot: 1985.9ms
timing for wl=493.72nm - setup: EE 288.8ms, inv.: 1667.4ms, repropa.: 12.9ms (1 field configs), tot: 1970.6ms
timing for wl=514.65nm - setup: EE 234.8ms, inv.: 2055.5ms, repropa.: 25.0ms (1 field configs), tot: 2316.6ms
timing for wl=536.47nm - setup: EE 691.7ms, inv.: 4105.6ms, repropa.: 25.0ms (1 field configs), tot: 4823.9ms
timing for wl=559.21nm - setup: EE 723.7ms, inv.: 4432.8ms, repropa.: 28.3ms (1 field configs), tot: 5186.0ms
timing for wl=582.92nm - setup: EE 955.0ms, inv.: 3917.9ms, repropa.: 13.5ms (1 field configs), tot: 4887.4ms
timing for wl=607.63nm - setup: EE 316.0ms, inv.: 1781.6ms, repropa.: 12.4ms (1 field configs), tot: 2110.9ms
timing for wl=633.38nm - setup: EE 228.8ms, inv.: 1599.2ms, repropa.: 12.1ms (1 field configs), tot: 1840.9ms
timing for wl=660.23nm - setup: EE 204.5ms, inv.: 1638.7ms, repropa.: 14.1ms (1 field configs), tot: 1858.1ms
timing for wl=688.22nm - setup: EE 213.5ms, inv.: 1579.3ms, repropa.: 13.4ms (1 field configs), tot: 1806.9ms
timing for wl=717.39nm - setup: EE 211.7ms, inv.: 1607.6ms, repropa.: 14.2ms (1 field configs), tot: 1834.6ms
timing for wl=747.80nm - setup: EE 239.5ms, inv.: 4543.4ms, repropa.: 27.3ms (1 field configs), tot: 4811.8ms
timing for wl=779.50nm - setup: EE 638.9ms, inv.: 4769.9ms, repropa.: 24.7ms (1 field configs), tot: 5434.8ms
timing for wl=812.55nm - setup: EE 754.9ms, inv.: 4584.1ms, repropa.: 12.0ms (1 field configs), tot: 5352.1ms
timing for wl=846.99nm - setup: EE 214.8ms, inv.: 1681.3ms, repropa.: 12.3ms (1 field configs), tot: 1909.4ms
timing for wl=882.90nm - setup: EE 221.9ms, inv.: 1663.7ms, repropa.: 16.4ms (1 field configs), tot: 1902.8ms
timing for wl=920.32nm - setup: EE 234.0ms, inv.: 1581.0ms, repropa.: 14.0ms (1 field configs), tot: 1829.6ms
timing for wl=959.33nm - setup: EE 202.4ms, inv.: 1506.4ms, repropa.: 12.6ms (1 field configs), tot: 1722.2ms
timing for wl=1000.00nm - setup: EE 231.6ms, inv.: 1646.3ms, repropa.: 13.5ms (1 field configs), tot: 1892.0ms

Plot the spectrum

plt.title("gold sphere, D=50nm")

## --- Mie
plt.plot(wl_mie, qext_mie, 'b--', dashes=[2,1],label='ext.')
plt.plot(wl_mie, qabs_mie, 'g--', dashes=[2,1],label='abs.')
plt.plot(wl_mie, qsca_mie, 'r--', dashes=[2,1],label='scat.')

## --- pyGDM
plt.scatter(wl, a_ext/a_geo, marker='x', linewidth=1.5, color='b', label='')
plt.scatter(wl, a_abs/a_geo, marker='x', linewidth=1.5, color='g', label='')
plt.scatter(wl, a_sca/a_geo, marker='x', linewidth=1.5, color='r', label='')

## --- for legend only
plt.plot([0], [0], 'k--', dashes=[2,1], label='Mie')
plt.scatter([0], [0], marker='x', linewidth=1.5, color='k', label='pyGDM')
## -- legend
plt.legend(loc='best', fontsize=12)

plt.xlabel("wavelength (nm)")
plt.ylabel("ext. / scat. / abs. efficiency")
plt.xlim( [wl.min(), wl.max()] )
plt.ylim( [0, 2] )


Except a slight offset in the extinction/absorption sections, the agreement with Mie theory is pretty nice. In particular, the plasmon resonance wavelength is reproduced with very good agreement.