Creating Atoms

Default distributions

Currently, the package only supports 3D objects, namely Sphere, Cube, and Cylinder. However, the source code allows to extend functionalities to 1D and 2D in future developments - please, collaborate with a pull request.

To create atoms, use the Atom constructor, the base syntax is the following

using CoupledDipoles, Random
Random.seed!(2354)
nAtoms = 5000

# `CoupledDipoles` and `CairoMakie` expoerts 'Sphere()', 
# therefore I had to be specific and write `CoupledDipoles.Sphere()`
sphere_radius = 1.5
sphere_cloud = Atom(CoupledDipoles.Sphere(), nAtoms, sphere_radius)

cube_side = 1.0
cube_cloud = Atom(Cube(), nAtoms, cube_side)

cylinder_radius = 0.5
cylinder_height = 2.0
cylinder_cloud = Atom(Cylinder(), nAtoms, cylinder_radius, cylinder_height)

You just created a matrix with the atoms. The atoms positions are in Cartesian Coordinates, and stored in column-major (each column correspond to an atom).

To see your atoms you need have to plot them with some external package

using CairoMakie
fig = Figure(size = (800, 300))
ax_sphere = Axis3(fig[1:2, 1:2], aspect = (1, 1, 1))
ax_cube = Axis3(fig[1:2, 3:4], aspect = (1, 1, 1))
ax_cylinder = Axis3(fig[1:2, 5:6], aspect = (1, 1, 1))

sx, sy, sz = sphere_cloud.r[1, :], sphere_cloud.r[2, :], sphere_cloud.r[3, :]
scatter!(ax_sphere, sx, sy, sz, color = sz)

cx, cy, cz = cube_cloud.r[1, :], cube_cloud.r[2, :], cube_cloud.r[3, :]
scatter!(ax_cube, cx, cy, cz, color = cz)

cyx, cyy, cyz = cylinder_cloud.r[1, :], cylinder_cloud.r[2, :], cylinder_cloud.r[3, :]
scatter!(ax_cylinder, cyx, cyy, cyz, color = cyz)

hidedecorations!(ax_sphere)
hidedecorations!(ax_cube)
hidedecorations!(ax_cylinder)
fig

save("geometries.png", fig)

3D examples

User defined geometry

The Atom constructor holds the shape used for multiple-dispatch on the right physical equation, r is the matrix containg the atomic positions, N is the number of atom, and sizes is a generic radius for the system.

struct Atom{T<:Dimension}
    shape::T
    r::Matrix{Float64}
    N::Int64
    sizes::Any
end

If a user wants to create their own atomic configuration, there are two constraints to consider:

  1. The shape field can be handled easily by choosing one of the available options: Sphere, Cube, or Cylinder.
  2. The matrix containing the atom positions must have each Cartesian dimension represented by a row.

Here's an example code snippet demonstrating the creation of a custom atomic configuration:

# Define atom positions as separate arrays
atom_1 = [1, 1, 1]
atom_2 = [2, 2, 2]
atom_3 = [3, 3, 3]
atom_4 = [4, 4, 4]

# Combine atom positions into a single matrix
r = transpose(vcat(atom_1, atom_2, atom_3, atom_4))
# Note: The `transpose` function is used to fulfill the matrix constraint.

# Convert the transposed result to an actual matrix using `Array`
r = Array(r)
# Note: The `transpose` operation returns a non-matrix object, so we use `Array` to materialize it.

# Create the `Atom` object with the chosen shape and custom positions
dummy_dimension = 5
atoms = Atom(Cube(), r, dummy_dimension)

The usage of transpose, followed by Array, is necessary to adhere to the package internals expectations.

Another example on how to concatenate vectors.

# (...)
nAtoms = 5000
x = 0.5randn(nAtoms)
y = 0.5randn(nAtoms)
z = 2rand(nAtoms)
r  = hcat(x,y,z) |> transpose |> Array


dummy_radius = 0.5
dummy_height = 2.0
atoms = Atom(Cylinder(), r, dummy_radius, dummy_height)

fig = Figure(size = (450, 450))
ax_sphere = Axis3(fig[1, 1])
sx, sy, sz = atoms.r[1, :], atoms.r[2, :], atoms.r[3, :]
scatter!(ax_sphere, sx, sy, sz, color = sz)    
hidedecorations!(ax_sphere)
fig

Gaussian Cylinder


CoupledDipoles.SphereType
    Sphere(; gaussian=false)

If gaussian=true, produces a Gaussian Sphere with μ = 0 (mean = 0) and variance = kR (σ^2 = kR)

source
CoupledDipoles.AtomType
Atom(geometry::Cube, N::Int64, kL::Union{Real,Integer}; r_min)

Arguments

  • geometry::Cube: The geometry of the atom object, which should be a Cube.
  • N::Int64: The number of atoms.
  • kL::Union{Real,Integer}: Cube's side length.

Keyword Arguments

  • :r_min: Optional keyword argument specifying the minimum distance between atoms.

By default it is computed with the radius_of_exclusion() method

Example

atom = Atom(Cube(), 100, 5.0; r_min = 0.1)
source
Atom(geometry::Cylinder, N::Int64, R::Union{Real,Integer}, h::Union{Real,Integer}; r_min)

Arguments

  • geometry::Cylinder: The geometry of the atom object, which should be a Cylinder.
  • N::Int64: The number of atoms.
  • R::Union{Real,Integer}: The radius of the cylinder.
  • h::Union{Real,Integer}: The height of the cylinder.

Keyword Arguments

  • :r_min: Optional keyword argument specifying the minimum distance between atoms.

By default it is computed with the radius_of_exclusion() method

Example

atom = Atom(Cylinder(), 100, 5.0, 10.0; r_min = 0.1)
source
Atom(geometry::Sphere, N::Int64, kR::Union{Real,Integer}; kwargs...)

Arguments

  • geometry::Sphere: The geometry of the atom object, which should be a Sphere.
    • for Gaussian distribution, set gaussian=true
  • N::Int64: The number of atoms.
  • kR::Union{Real,Integer}: The radius for the sphere.

Keyword Arguments

  • :r_min: Optional keyword argument specifying the minimum distance between atoms.

By default it is computed with the radius_of_exclusion() method

Example

atom_homogenous = Atom(Sphere(), 100, 5.0; r_min = 0.1)
atom_gaussian = Atom(Sphere(gaussian=true), 100, 5.0; r_min = 0.1)
source