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)
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:
- The shape field can be handled easily by choosing one of the available options:
Sphere
,Cube
, orCylinder
. - 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
CoupledDipoles.Sphere
— Type Sphere(; gaussian=false)
If gaussian=true
, produces a Gaussian Sphere with μ = 0 (mean = 0) and variance = kR (σ^2 = kR)
CoupledDipoles.Cube
— Type Cube()
CoupledDipoles.Cylinder
— Type Cylinder()
CoupledDipoles.Atom
— TypeAtom(geometry::Cube, N::Int64, kL::Union{Real,Integer}; r_min)
Arguments
geometry::Cube
: The geometry of the atom object, which should be aCube
.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)
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 aCylinder
.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)
Atom(geometry::Sphere, N::Int64, kR::Union{Real,Integer}; kwargs...)
Arguments
geometry::Sphere
: The geometry of the atom object, which should be aSphere
.- for Gaussian distribution, set
gaussian=true
- for Gaussian distribution, set
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)