Skip to content

Commit

Permalink
atomic_mass -> mass
Browse files Browse the repository at this point in the history
  • Loading branch information
Christoph Ortner committed Aug 13, 2024
1 parent ca88d97 commit b91ba47
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 70 deletions.
16 changes: 8 additions & 8 deletions src/implementation/atom.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ struct Atom{D, L<:Unitful.Length, V<:Unitful.Velocity, M<:Unitful.Mass}
position::SVector{D, L}
velocity::SVector{D, V}
species::ChemicalSpecies
atomic_mass::M
mass::M
data::Dict{Symbol, Any} # Store arbitrary data about the atom.
end

velocity(atom::Atom) = atom.velocity
position(atom::Atom) = atom.position
atomic_mass(atom::Atom) = atom.atomic_mass
mass(atom::Atom) = atom.mass
species(atom::Atom) = atom.species

n_dimensions(::Atom{D}) where {D} = D
Expand All @@ -33,7 +33,7 @@ function Base.get(at::Atom, x::Symbol, default)
hasfield(Atom, x) ? getfield(at, x) : get(at.data, x, default)
end
function Base.keys(at::Atom)
(:position, :velocity, :species, :atomic_mass, keys(at.data)...)
(:position, :velocity, :species, :mass, keys(at.data)...)
end
Base.pairs(at::Atom) = (k => at[k] for k in keys(at))

Expand All @@ -45,17 +45,17 @@ Base.pairs(at::Atom) = (k => at[k] for k in keys(at))
Construct an atomic located at the cartesian coordinates `position` with (optionally)
the given cartesian `velocity`. Note that `AtomId = Union{Symbol,AbstractString,Integer}`.
Supported `kwargs` include `atomic_symbol`, `atomic_number`, `atomic_mass`, `charge`,
Supported `kwargs` include `atomic_symbol`, `atomic_number`, `mass`, `charge`,
`multiplicity` as well as user-specific custom properties.
"""
function Atom(identifier::AtomId,
position::AbstractVector{L},
velocity::AbstractVector{V}=zeros(length(position))u"bohr/s";
species = ChemicalSpecies(identifier),
atomic_mass::M=element(species).atomic_mass,
mass::M=element(species).atomic_mass,
kwargs...) where {L <: Unitful.Length, V <: Unitful.Velocity, M <: Unitful.Mass}
Atom{length(position), L, V, M}(position, velocity, species,
atomic_mass, Dict(kwargs...))
mass, Dict(kwargs...))
end

# TODO: what about the default unit?
Expand All @@ -80,7 +80,7 @@ end
Update constructor. Construct a new `Atom`, by amending the data contained
in the passed `atom` object.
Supported `kwargs` include `atomic_symbol`, `atomic_number`, `atomic_mass`, `charge`,
Supported `kwargs` include `atomic_symbol`, `atomic_number`, `mass`, `charge`,
`multiplicity` as well as user-specific custom properties.
# Examples
Expand All @@ -90,7 +90,7 @@ julia> hydrogen = Atom(:H, zeros(3)u"Å")
```
and now amend its charge and atomic mass
```julia-repl
julia> Atom(atom; atomic_mass=1.0u"u", charge=-1.0u"e_au")
julia> Atom(atom; mass=1.0u"u", charge=-1.0u"e_au")
```
"""
Atom(atom::Atom; kwargs...) = Atom(; pairs(atom)..., kwargs...)
Expand Down
73 changes: 43 additions & 30 deletions src/implementation/fast_system.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,75 +3,88 @@
#
export FastSystem

struct FastSystem{D, L <: Unitful.Length, M <: Unitful.Mass} <: AbstractSystem{D}
bounding_box::SVector{D, SVector{D, L}}
boundary_conditions::SVector{D, BoundaryCondition}
struct FastSystem{D, TCELL, L <: Unitful.Length, M <: Unitful.Mass, S} <: SystemWithCell{D}
cell::TCELL
position::Vector{SVector{D, L}}
atomic_symbol::Vector{Symbol}
atomic_number::Vector{Int}
atomic_mass::Vector{M}
species::Vector{S}
mass::Vector{M}
end

# Constructor to fetch the types
function FastSystem(box, boundary_conditions, positions, atomic_symbols, atomic_numbers, atomic_masses)
FastSystem{length(box),eltype(eltype(positions)),eltype(atomic_masses)}(
box, boundary_conditions, positions, atomic_symbols, atomic_numbers, atomic_masses
)
function FastSystem(box::NTuple{D, <: AbstractVector}, pbc::NTuple{D, Bool},
positions, species, masses) where {D}
cell = PCell(box, pbc)
FastSystem(cell, positions, species, masses)
end

function FastSystem(cell::TCELL, positions::AbstractVector{<: SVector{D, L}},
species::AbstractVector{S}, masses) where {TCELL, D, L, S}
@assert D == n_dimensions(cell)
FastSystem{D, TCELL, L, typeof(masses), S}(
cell, positions, species, masses)
end

get_cell(sys::FastSystem) = sys.cell

# Constructor to take data from another system
function FastSystem(system::AbstractSystem)
FastSystem(bounding_box(system), boundary_conditions(system), position(system),
atomic_symbol(system), atomic_number(system), atomic_mass(system))
FastSystem(get_cell(system), position(system, :), species(system, :), mass(system, :))
end

# Convenience constructor where we don't have to preconstruct all the static stuff...
function FastSystem(particles, box, boundary_conditions)
function FastSystem(particles, box, pbc)
D = length(box)
if !all(length.(box) .== D)
throw(ArgumentError("Box must have D vectors of length D=$D."))
end
if length(boundary_conditions) != D
if length(pbc) != D
throw(ArgumentError("Boundary conditions should be of length D=$D."))
end
if !all(n_dimensions.(particles) .== D)
throw(ArgumentError("Particles must have positions of length D=$D."))
end
FastSystem(box, boundary_conditions, position.(particles), atomic_symbol.(particles),
atomic_number.(particles), atomic_mass.(particles))
FastSystem(box, pbc, position.(particles), species.(particles), mass.(particles))
end

bounding_box(sys::FastSystem) = sys.bounding_box
boundary_conditions(sys::FastSystem) = sys.boundary_conditions
Base.length(sys::FastSystem) = length(sys.position)
Base.size(sys::FastSystem) = size(sys.position)

species_type(::FS) where {FS <: FastSystem} = AtomView{FS}
Base.getindex(sys::FastSystem, i::Integer) = AtomView(sys, i)
# TODO
# species_type(::FS) where {FS <: FastSystem} = AtomView{FS}

position(s::FastSystem) = s.position
atomic_symbol(s::FastSystem) = s.atomic_symbol
atomic_number(s::FastSystem) = s.atomic_number
atomic_mass(s::FastSystem) = s.atomic_mass
velocity(::FastSystem) = missing
Base.getindex(sys::FastSystem, i::Integer) = AtomView(sys, i)

# System property access
function Base.getindex(system::FastSystem, x::Symbol)
if x === :bounding_box
bounding_box(system)
elseif x === :boundary_conditions
boundary_conditions(system)
elseif x === :periodicity
periodicity(system)
else
throw(KeyError(x))
end
end
Base.haskey(::FastSystem, x::Symbol) = x in (:bounding_box, :boundary_conditions)
Base.keys(::FastSystem) = (:bounding_box, :boundary_conditions)
Base.haskey(::FastSystem, x::Symbol) = x in (:bounding_box, :periodicity)
Base.keys(::FastSystem) = (:bounding_box, :periodicity)

# Atom and atom property access
atomkeys(::FastSystem) = (:position, :atomic_symbol, :atomic_number, :atomic_mass)
atomkeys(::FastSystem) = (:position, :species, :mass)

hasatomkey(system::FastSystem, x::Symbol) = x in atomkeys(system)

function Base.getindex(system::FastSystem, i::Union{Integer,AbstractVector}, x::Symbol)
getfield(system, x)[i]
end

Base.getindex(system::FastSystem, ::Colon, x::Symbol) = getfield(system, x)

position(s::FastSystem, ::Colon) = s.position
position(sys::FastSystem, i::Union{Integer, AbstractVector}) = sys.position[i]

velocity(::FastSystem, args...) = missing

mass(s::FastSystem, ::Colon) = s.mass
mass(sys::FastSystem, i::Union{Integer, AbstractVector}) = sys.mass[i]

species(s::FastSystem, ::Colon) = s.species
species(sys::FastSystem, i::Union{Integer, AbstractVector}) = sys.species[i]
8 changes: 4 additions & 4 deletions src/implementation/flexible_system.jl
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ velocity(sys::FlexibleSystem, i::Integer) =
velocity(sys::FlexibleSystem, i::Union{AbstractVector, Colon}) =
[ velocity(x) for x in sys.particles[i] ]

atomic_mass(sys::FlexibleSystem, i::Integer) =
atomic_mass(sys.particles[i])
mass(sys::FlexibleSystem, i::Integer) =
mass(sys.particles[i])

atomic_mass(sys::FlexibleSystem, i::Union{AbstractVector, Colon}) =
[ atomic_mass(x) for x in sys.particles[i] ]
mass(sys::FlexibleSystem, i::Union{AbstractVector, Colon}) =
[ mass(x) for x in sys.particles[i] ]

species(sys::FlexibleSystem, i::Integer) =
species(sys.particles[i])
Expand Down
4 changes: 2 additions & 2 deletions src/implementation/impl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import AtomsBase: AbstractSystem, SystemWithCell,
n_dimensions, species, position,
velocity, element,
atomic_number, atomic_symbol,
atomic_mass, element,
mass, element,
show_atom

import AtomsBase: ChemicalSpecies, PCell, OpenSystemCell

include("atom.jl")
include("flexible_system.jl")
# include("fast_system.jl")
include("fast_system.jl")

end
1 change: 1 addition & 0 deletions src/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export AbstractSystem,
element,
element_symbol,
atomic_mass,
mass,
atomic_number,
atomic_symbol,
atomkeys,
Expand Down
2 changes: 1 addition & 1 deletion src/utils/atomview.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ using `AtomView` as its species type.
julia> system = FastSystem(atoms, box, boundary_conditions);
julia> atom = system[2]
AtomView(C, atomic_number = 6, atomic_mass = 12.011 u):
AtomView(C, atomic_number = 6, mass = 12.011 u):
position : [0.75,0.75,0.75]u"Å"
julia> atom isa AtomView{typeof(system)}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/chemspecies.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Base.convert(::Type{Symbol}, element::ChemicalSpecies) = Symbol(element)

Base.Symbol(element::ChemicalSpecies) = _chem_el_info[element.atomic_number].symbol

atomic_mass(element::ChemicalSpecies) = _chem_el_info[element.atomic_number].atomic_mass
mass(element::ChemicalSpecies) = _chem_el_info[element.atomic_number].atomic_mass

rich_info(element::ChemicalSpecies) = PeriodicTable.elements[element.atomic_number]

Expand Down
6 changes: 3 additions & 3 deletions src/utils/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ end

function show_atom(io::IO, ::MIME"text/plain", at)
print(io, typeof(at).name.name, "(")
println(io, atomic_symbol(at), ", atomic_number = ", atomic_number(at),
", atomic_mass = ", atomic_mass(at), "):")
println(io, atomic_symbol(at), ", Z = ", atomic_number(at),
", m = ", mass(at), "):")

pos = [(@sprintf "%.8g" ustrip(p)) for p in position(at)]
posunit = unit(eltype(position(at)))
Expand All @@ -101,7 +101,7 @@ function show_atom(io::IO, ::MIME"text/plain", at)
@printf io " %-17s : [%s]u\"%s\"\n" "velocity" join(vel, ",") string(velunit)
end
for (k, v) in pairs(at)
k in (:atomic_number, :atomic_mass, :atomic_symbol, :position, :velocity) && continue
k in (:atomic_number, :mass, :atomic_symbol, :position, :velocity) && continue
@printf io " %-17s : %s\n" string(k) string(v)
end
end
4 changes: 2 additions & 2 deletions test/atom.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ using AtomsBase.Implementation: Atom
@test atomic_symbol(at) == :Si
@test atomic_number(at) == 14
@test species(at) == ChemicalSpecies(:Si)
@test haskey(at, :atomic_mass)
@test haskey(at, :mass)
@test haskey(at, :species)
@test haskey(at, :extradata)
@test at[:extradata] == 42

@test keys(at) == (:position, :velocity, :species,
:atomic_mass, :extradata)
:mass, :extradata)

# Test update constructor
newatom = Atom(at; extradata=43, atomic_number=15)
Expand Down
23 changes: 12 additions & 11 deletions test/fast_system.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ using Unitful
using PeriodicTable
using StaticArrays

using AtomsBase.Implementation: Atom, FastSystem

@testset "Fast system" begin
box = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]u"m"
bcs = [Periodic(), Periodic(), DirichletZero()]
box = ([1, 0, 0]u"m", [0, 1, 0]u"m", [0, 0, 1]u"m")
pbcs = (true, true, false)
atoms = Atom[:C => [0.25, 0.25, 0.25]u"m",
:C => [0.75, 0.75, 0.75]u"m"]
system = FastSystem(atoms, box, bcs)

@test length(system) == 2
@test size(system) == (2, )
@test atomic_mass(system) == [12.011, 12.011]u"u"
@test mass(system) == [12.011, 12.011]u"u"
@test boundary_conditions(system) == bcs
@test bounding_box(system) == box
@test system[:boundary_conditions] == bcs
Expand All @@ -23,16 +25,16 @@ using StaticArrays
@test keys(system) == (:bounding_box, :boundary_conditions)
@test haskey(system, :boundary_conditions)
@test system[:boundary_conditions][1] == Periodic()
@test atomkeys(system) == (:position, :atomic_symbol, :atomic_number, :atomic_mass)
@test keys(system[1]) == (:position, :atomic_symbol, :atomic_number, :atomic_mass)
@test hasatomkey(system, :atomic_symbol)
@test atomkeys(system) == (:position, :species, :mass)
@test keys(system[1]) == (:position, :species, :mass)
@test hasatomkey(system, :species)
@test system[1] == AtomView(system, 1)
@test system[1:2] == [system[1], system[2]]
@test system[[2, 1]] == [system[2], system[1]]
@test system[[1 2; 2 1]] == [system[1] system[2]; system[2] system[1]]
@test system[:] == [system[1], system[2]]
@test system[[false, true]] == [AtomView(system, 2)]
@test system[1, :atomic_number] == 6
@test atomic_number(system, 1) == 6
@test system[1:2, :atomic_symbol] == [:C, :C]
@test system[[1, 2], :atomic_symbol] == [:C, :C]
@test system[:, :atomic_symbol] == [:C, :C]
Expand All @@ -46,9 +48,8 @@ using StaticArrays
@test collect(pairs(system)) == [(:bounding_box => box), (:boundary_conditions => bcs)]
@test collect(pairs(system[1])) == [
:position => position(atoms[1]),
:atomic_symbol => :C,
:atomic_number => 6,
:atomic_mass => atomic_mass(atoms[1]),
:species => ChemicalSpecies(:C),
:mass => mass(atoms[1]),
]

# check type stability
Expand All @@ -58,7 +59,7 @@ using StaticArrays
@test ismissing(@inferred(velocity(system, 2)))

# Test AtomView
for method in (position, atomic_mass, atomic_symbol, atomic_number)
for method in (position, mass, species, atomic_number, atomic_symbol)
@test method(system[1]) == method(system, 1)
@test method(system[2]) == method(system, 2)
end
Expand Down
13 changes: 6 additions & 7 deletions test/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ using Unitful
using UnitfulAtomic
using PeriodicTable

using AtomsBase.Implementation: Atom, FlexibleSystem
using AtomsBase.Implementation: Atom, FlexibleSystem, FastSystem

@testset "Interface" begin
box = ([1, 0, 0]u"m", [0, 1, 0]u"m", [0, 0, 1]u"m")
Expand All @@ -18,15 +18,14 @@ using AtomsBase.Implementation: Atom, FlexibleSystem
@test velocity(atoms[1]) == [0.0, 0.0, 0.0]u"bohr/s"
@test atomic_symbol(atoms[1]) == :C
@test atomic_number(atoms[1]) == 6
@test atomic_mass(atoms[1]) == 12.011u"u"
@test mass(atoms[1]) == 12.011u"u"
@test element(atoms[1]) == element(:C)
@test keys(atoms[1]) == (:position, :velocity, :species, :atomic_mass)
@test keys(atoms[1]) == (:position, :velocity, :species, :mass)
@test get(atoms[1], :blubber, :adidi) == :adidi
end

@testset "System" begin
flexible = FlexibleSystem(atoms, box, pbcs)
# TODO
# fast = FastSystem(flexible)
@test length(flexible) == 2
@test size(flexible) == (2, )
Expand All @@ -38,16 +37,16 @@ using AtomsBase.Implementation: Atom, FlexibleSystem
@test position(flexible, 1) == [0.25, 0.25, 0.25]u"m"
@test velocity(flexible, :)[1] == [0.0, 0.0, 0.0]u"bohr/s"
@test velocity(flexible, 2) == [0.0, 0.0, 0.0]u"bohr/s"
@test atomic_mass(flexible, :) == [12.011, 12.011]u"u"
@test atomic_mass(flexible, 1) == 12.011u"u"
@test mass(flexible, :) == [12.011, 12.011]u"u"
@test mass(flexible, 1) == 12.011u"u"
@test atomic_number(flexible, :) == [6, 6]
# TODO fast
# @test atomic_number(fast, 1) == 6
# @test ismissing(velocity(fast, 2))
@test atomic_symbol(flexible, 2) == :C
@test atomic_number(flexible, 2) == 6

@test atomkeys(flexible) == (:position, :velocity, :species, :atomic_mass)
@test atomkeys(flexible) == (:position, :velocity, :species, :mass)
@test hasatomkey(flexible, :species)
@test atomic_symbol(flexible, 1) == :C
@test atomic_symbol(flexible, :,) == [:C, :C]
Expand Down
2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ if GROUP == "Core"
@testset "AtomsBase.jl" begin
include("interface.jl")
include("atom.jl")
# include("fast_system.jl")
include("fast_system.jl")
# include("properties.jl")
# include("printing.jl")
end
Expand Down

0 comments on commit b91ba47

Please sign in to comment.