Getting Started

Installation

Pkg.add("CoupledDipole")

Example

A typical simulation requires two inputs: a Cluster, describing the configuration of particles, and a Material, describing the wavelength-dependent dielectric functions of all media.

using CoupledDipole
using DataFrames
using VegaLite

## cluster geometry
cl1 = cluster_helix(8, 20, 20, 50, 200, 300, π/2, 0)
cl0 = cluster_single(20, 20, 50) # reference: single-particle

## materials
wavelengths = collect(400:2:800.0)
media = Dict([("Au", epsilon_Au), ("medium", x -> 1.33)])
mat = Material(wavelengths, media)
Material{Float64}([400.0, 402.0, 404.0, 406.0, 408.0, 410.0, 412.0, 414.0, 416.0, 418.0  …  782.0, 784.0, 786.0, 788.0, 790.0, 792.0, 794.0, 796.0, 798.0, 800.0], Dict{String, Function}("medium" => Main.var"#1#2"(), "Au" => CoupledDipole.epsilon_Au))

From these two objects we can simply call a high-level function to simulate optical properties. The following lines simulate the orientation-averaged optical response,

oa0 = spectrum_oa(cl0, mat) # reference: just one particle
oa1 = spectrum_oa(cl1, mat)
(average = CoupledDipole.CrossSections{Float64}([4387.633028737657, 4371.63866777103, 4355.322552627075, 4338.715394874172, 4321.850963980979, 4304.7659524427545, 4287.499879511219, 4270.095029956412, 4252.596422985535, 4235.051805491644  …  1957.233118612199, 1888.5631143990202, 1823.445525382679, 1761.645392438214, 1702.946305502441, 1647.14873278153, 1594.0685156670404, 1543.5355118709126, 1495.3923711712307, 1449.4934298513103], [3707.221601757346, 3700.54565883708, 3693.5168513531767, 3686.1628909870287, 3678.5136781484543, 3670.601184296725, 3662.4593654528667, 3654.1241046760715, 3645.6331800472376, 3637.0262537439808  …  732.9205850586217, 707.6120715654375, 683.6482688927981, 660.9370207896972, 639.3937153096438, 618.9405795317374, 599.5060471215155, 581.0241906653474, 563.4342116377019, 546.6799816817696], [732.2898611510353, 721.3320779909536, 710.4498730419359, 699.6445824168403, 688.9186660033251, 678.2756579517159, 667.720127864306, 657.2576510902118, 646.8947864402633, 636.6390596385498  …  1223.9420434440804, 1180.4831510791896, 1139.2429568974183, 1100.0775579076233, 1062.8541722952505, 1027.4501605618432, 993.7521411794474, 961.6551911216746, 931.062122618018, 901.8828283727416]), dichroism = CoupledDipole.CrossSections{Float64}([-0.2971138228695815, -0.25409671837063486, -0.21297450958912473, -0.17403476259399125, -0.13750456051987345, -0.1035515555224668, -0.07228645673676234, -0.04376673910292983, -0.018001331127425527, 0.005043973243254964  …  0.09910740227758091, 0.10308635724964882, 0.10658256356712176, 0.10963056446587599, 0.11226305211990902, 0.11451086304724853, 0.11640300283788618, 0.11796669202799605, 0.11922742679152169, 0.12020904958181451], [-1.2892696667168608, -1.2053249284153082, -1.1214440573482627, -1.0382445182154718, -0.9562870354987348, -0.876071709596657, -0.7980357664292245, -0.7225528279354135, -0.6499335532088442, -0.5804274727865738  …  0.03380753871721477, 0.03280816405470811, 0.0318497676076817, 0.030930239217509408, 0.03004757918430274, 0.02919989525771467, 0.02838539899998367, 0.027602401714821756, 0.02684931009754739, 0.0261246217256656], [-0.7538701968963515, -0.8138738386292631, -0.861737754101411, -0.8981690701390771, -0.923890141633683, -0.9396325366037639, -0.9461315501352062, -0.9441211825217531, -0.9343295212753653, -0.9174744739720789  …  0.1093013779365435, 0.11186796857567338, 0.11405078562434601, 0.11587700403759393, 0.11737256942880525, 0.11856213621781189, 0.11946904051684315, 0.12011529909982632, 0.12052162768090732, 0.12070747321760517]))

From there we combine the cross-sections in long-format dataframes for plotting,

d0 = oa_df(oa0, mat.wavelengths)
d1 = oa_df(oa1, mat.wavelengths)

d2 = [insertcols!(d1, :cluster => "helix");
      insertcols!(d0, :cluster => "single")]

d2 |> @vlplot(
 width= 200,
 height =  150,
     mark = {:line, clip = true},
     row = "type", column="variable",
     resolve={scale={y="independent"}},
     encoding = {x = "wavelength:q", y = "value:q",
      strokeDash = "cluster:n", color = "cluster:n"}
 )