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.638667771031, 4355.322552627077, 4338.715394874173, 4321.850963980981, 4304.765952442755, 4287.49987951122, 4270.095029956413, 4252.596422985537, 4235.0518054916465  …  1957.2331186121999, 1888.5631143990208, 1823.44552538268, 1761.6453924382145, 1702.9463055024414, 1647.1487327815305, 1594.068515667041, 1543.535511870913, 1495.3923711712312, 1449.4934298513108], [3707.221601757347, 3700.5456588370807, 3693.5168513531785, 3686.16289098703, 3678.5136781484553, 3670.601184296726, 3662.4593654528685, 3654.124104676073, 3645.6331800472376, 3637.0262537439817  …  732.9205850586219, 707.6120715654378, 683.6482688927983, 660.9370207896974, 639.393715309644, 618.9405795317376, 599.5060471215157, 581.0241906653476, 563.4342116377021, 546.6799816817697], [732.2898611510357, 721.3320779909541, 710.4498730419361, 699.6445824168408, 688.9186660033256, 678.2756579517164, 667.7201278643065, 657.257651090212, 646.8947864402635, 636.6390596385503  …  1223.942043444081, 1180.4831510791905, 1139.242956897419, 1100.077557907624, 1062.8541722952511, 1027.4501605618439, 993.7521411794481, 961.6551911216752, 931.0621226180186, 901.8828283727421]), dichroism = CoupledDipole.CrossSections{Float64}([-0.29711382286979465, -0.2540967183708729, -0.21297450958916736, -0.1740347625940339, -0.13750456051998713, -0.10355155552243837, -0.07228645673671971, -0.04376673910294404, -0.01800133112739359, 0.005043973243169699  …  0.09910740227755249, 0.10308635724956977, 0.1065825635671502, 0.10963056446584137, 0.11226305211993391, 0.11451086304731248, 0.11640300283780092, 0.11796669202803248, 0.11922742679158564, 0.12020904958182162], [-1.2892696667169177, -1.2053249284154148, -1.1214440573483195, -1.0382445182153297, -0.9562870354988201, -0.876071709596586, -0.7980357664292529, -0.7225528279352998, -0.6499335532088583, -0.5804274727865028  …  0.033807538717204114, 0.032808164054685895, 0.031849767607624854, 0.03093023921752495, 0.03004757918433693, 0.02919989525774531, 0.028385398999994774, 0.027602401714799996, 0.026849310097497654, 0.026124621725660716], [-0.7538701968963288, -0.8138738386292773, -0.86173775410145, -0.8981690701390704, -0.9238901416337136, -0.9396325366037728, -0.9461315501352302, -0.9441211825217629, -0.9343295212753648, -0.9174744739720568  …  0.10930137793657813, 0.1118679685756938, 0.11405078562436376, 0.11587700403754594, 0.11737256942879412, 0.11856213621779634, 0.11946904051678807, 0.12011529909984185, 0.12052162768094861, 0.12070747321757362]))

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"}
 )