diff --git a/src/implementation_aos.jl b/src/implementation_aos.jl index 1a7b3a1..e3d370c 100644 --- a/src/implementation_aos.jl +++ b/src/implementation_aos.jl @@ -5,7 +5,7 @@ using StaticArrays export FlexibleSystem # TODO Switch order of type arguments? -struct FlexibleSystem{D,ET,L,AT} <: AbstractSystem{D,ET} +struct FlexibleSystem{D,ET,L,AT} box::SVector{D,<:SVector{D,L}} boundary_conditions::SVector{D,<:BoundaryCondition} particles::Vector{AT} @@ -34,3 +34,6 @@ end Base.size(sys::FlexibleSystem) = size(sys.particles) Base.length(sys::FlexibleSystem) = length(sys.particles) Base.getindex(sys::FlexibleSystem, i::Int) = getindex(sys.particles, i) +Base.firstindex(::FlexibleSystem) = 1 +Base.lastindex(s::FlexibleSystem) = length(s.elements) +Base.iterate(s::FlexibleSystem, i=1) = (1 <= i <= length(s)) ? (@inbounds s[i], i+1) : nothing diff --git a/src/implementation_soa.jl b/src/implementation_soa.jl index 1109878..121dd4f 100644 --- a/src/implementation_soa.jl +++ b/src/implementation_soa.jl @@ -4,8 +4,7 @@ using StaticArrays export FastSystem -struct FastSystem{D,ET,L<:Unitful.Length} <: - AbstractSystem{D,ET} +struct FastSystem{D,ET,L<:Unitful.Length} box::SVector{D,SVector{D,L}} boundary_conditions::SVector{D,BoundaryCondition} positions::Vector{SVector{D,L}} @@ -53,9 +52,9 @@ end bounding_box(sys::FastSystem) = sys.box boundary_conditions(sys::FastSystem) = sys.boundary_conditions -# Base.size(sys::FastSystem) = size(sys.particles) -Base.length(sys::FastSystem{D,ET}) where {D,ET} = length(sys.elements) - -# first piece of trickiness: can't do a totally abstract dispatch here because we need to know the signature of the constructor for AT Base.getindex(sys::FastSystem{D,ET}, i::Int) where {D,ET} = SimpleAtom{D}(sys.positions[i], sys.elements[i]) +Base.length(sys::FastSystem{D,ET}) where {D,ET} = length(sys.elements) +Base.firstindex(::FastSystem) = 1 +Base.lastindex(s::FastSystem) = length(s.elements) +Base.iterate(s::FastSystem, i=1) = (1 <= i <= length(s)) ? (@inbounds s[i], i+1) : nothing \ No newline at end of file diff --git a/src/interface.jl b/src/interface.jl index 27ed31f..f992b89 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -4,8 +4,7 @@ using PeriodicTable using StaticArrays import Base.position -export AbstractSystem, AbstractAtomicSystem -export ChemicalElement, SimpleAtom +export SimpleAtom export BoundaryCondition, DirichletZero, Periodic export atomic_mass, atomic_number, @@ -19,8 +18,6 @@ export atomic_mass, export atomic_property, has_atomic_property, atomic_propertynames export n_dimensions -velocity(p)::AbstractVector{<:Unitful.Velocity} = missing -position(p)::AbstractVector{<:Unitful.Length} = error("Implement me") # # Identifier for boundary conditions per dimension @@ -30,57 +27,22 @@ struct DirichletZero <: BoundaryCondition end # Dirichlet zero boundary (i.e. m struct Periodic <: BoundaryCondition end # Periodic BCs -# -# The system type -# Again readonly. -# - -abstract type AbstractSystem{D,ET} end -(bounding_box(::AbstractSystem{D})::SVector{D,SVector{D,<:Unitful.Length}}) where {D} = +# now the interface is just functions! +(bounding_box(sys)::SVector{D,SVector{D,<:Unitful.Length}}) where {D<:Signed} = error("Implement me") -(boundary_conditions(::AbstractSystem{D})::SVector{D,BoundaryCondition}) where {D} = +(boundary_conditions(sys)::SVector{D,BoundaryCondition}) where {D<:Signed} = error("Implement me") - -get_periodic(sys::AbstractSystem) = +get_periodic(sys) = [isa(bc, Periodic) for bc in get_boundary_conditions(sys)] -# Note: Can't use ndims, because that is ndims(sys) == 1 (because of AbstractVector interface) -n_dimensions(::AbstractSystem{D}) where {D} = D - - -# indexing interface -Base.getindex(::AbstractSystem, ::Int) = error("Implement me") -Base.size(::AbstractSystem) = error("Implement me") -Base.length(::AbstractSystem) = error("Implement me") -Base.setindex!(::AbstractSystem, ::Int) = error("AbstractSystem objects are not mutable.") -Base.firstindex(::AbstractSystem) = 1 -Base.lastindex(s::AbstractSystem) = length(s) -Base.iterate(S::AbstractSystem, i::Int=1) = (1 <= i <= length(S)) ? (@inbounds S[i], i+1) : nothing - -# iteration interface, needed for default broadcast dispatches below to work -Base.iterate(sys::AbstractSystem{D,ET}, state = firstindex(sys)) where {D,ET} = - state > length(sys) ? nothing : (sys[state], state + 1) -# TODO Support similar, push, ... - -# Some implementations might prefer to store data in the System as a flat list and -# expose Atoms as a view. Therefore these functions are needed. Of course this code -# should be autogenerated later on ... -position(sys::AbstractSystem) = position.(sys) # in Cartesian coordinates! -velocity(sys::AbstractSystem) = velocity.(sys) # in Cartesian coordinates! -element(sys::AbstractSystem) = element.(sys) - -# -# Extra stuff only for Systems composed of atoms -# -const AbstractAtomicSystem{D} = AbstractSystem{D,Element} -atomic_symbol(sys::AbstractAtomicSystem) = atomic_symbol.(sys) -atomic_number(sys::AbstractAtomicSystem) = atomic_number.(sys) -atomic_mass(sys::AbstractAtomicSystem) = atomic_mass.(sys) -atomic_property(sys::AbstractAtomicSystem, property::Symbol)::Vector{Any} = - atomic_property.(sys, property) -atomic_propertiesnames(sys::AbstractAtomicSystem) = unique(sort(atomic_propertynames.(sys))) +# indexing and iteration interface: need to dispatch getindex, size, length, firstindex, lastindex, iterate in order for these dispatches to work +# may be a good idea also to dispatch ndims? +position(sys) = position.(sys) # in Cartesian coordinates! +velocity(sys) = velocity.(sys) # in Cartesian coordinates! +element(sys) = element.(sys) +# this is a concrete type, assuming we keep it should probably get moved to another file struct SimpleAtom{D} position::SVector{D,<:Unitful.Length} element::Element @@ -92,15 +54,3 @@ element(atom::SimpleAtom) = atom.element function SimpleAtom(position, symbol::Union{Integer,AbstractString,Symbol,AbstractVector}) SimpleAtom(position, elements[symbol]) end - -# Just to make testing a little easier for now -function Base.show(io::IO, mime::MIME"text/plain", sys::AbstractSystem) - println(io, "System:") - println(io, " BCs: ", boundary_conditions(sys)) - println(io, " Box: ", bounding_box(sys)) - println(io, " Particles: ") - for particle in sys - Base.show(io, mime, particle) - println(io) - end -end