Skip to content

Commit 8285994

Browse files
cortnerChristoph Ortner
and
Christoph Ortner
authored
Fix #117 (#118)
* fix #117; better tests * cleanup * addres mfh's comments --------- Co-authored-by: Christoph Ortner <[email protected]>
1 parent 16c52c1 commit 8285994

File tree

5 files changed

+106
-36
lines changed

5 files changed

+106
-36
lines changed

src/implementation/fast_system.jl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ struct FastSystem{D, TCELL, L <: Unitful.Length, M <: Unitful.Mass, S} <: Abstra
1616
end
1717

1818
# Constructor to fetch the types
19-
function FastSystem(box::NTuple{D, <: AbstractVector}, pbc::NTuple{D, Bool},
20-
positions, species, masses) where {D}
19+
function FastSystem(box::AUTOBOX,
20+
pbc::AUTOPBC,
21+
positions, species, masses)
2122
cϵll = PeriodicCell(; cell_vectors = box, periodicity = pbc)
2223
FastSystem(cϵll, positions, species, masses)
2324
end
@@ -39,18 +40,20 @@ function FastSystem(system::AbstractSystem)
3940
end
4041

4142
# Convenience constructor where we don't have to preconstruct all the static stuff...
42-
function FastSystem(particles, box, pbc)
43-
D = length(box)
44-
if !all(length.(box) .== D)
43+
function FastSystem(particles, box::AUTOBOX, pbc::AUTOPBC)
44+
box1 = _auto_cell_vectors(box)
45+
pbc1 = _auto_pbc(pbc, box1)
46+
D = length(box1)
47+
if !all(length.(box1) .== D)
4548
throw(ArgumentError("Box must have D vectors of length D=$D."))
4649
end
47-
if length(pbc) != D
50+
if length(pbc1) != D
4851
throw(ArgumentError("Boundary conditions should be of length D=$D."))
4952
end
5053
if !all(n_dimensions.(particles) .== D)
5154
throw(ArgumentError("Particles must have positions of length D=$D."))
5255
end
53-
FastSystem(box, pbc, position.(particles), species.(particles), mass.(particles))
56+
FastSystem(box1, pbc1, position.(particles), species.(particles), mass.(particles))
5457
end
5558

5659
Base.length(sys::FastSystem) = length(sys.position)

src/implementation/flexible_system.jl

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,12 @@ Construct a flexible system, a versatile data structure for atomistic systems,
4949
which puts an emphasis on flexibility rather than speed.
5050
"""
5151
function FlexibleSystem(
52-
particles::AbstractVector{S},
53-
box::NTuple{D, <: AbstractVector{L}},
54-
periodicity::Union{Bool, NTuple{D, Bool}, AbstractVector{<: Bool}};
55-
kwargs...
56-
) where {L<:Unitful.Length, S, D}
57-
if periodicity isa Bool
58-
periodicity = ntuple(_ -> periodicity, D)
59-
else
60-
periodicity = tuple(periodicity...)
61-
end
62-
if !all(length.(box) .== D)
63-
throw(ArgumentError("Box must have D vectors of length D"))
64-
end
65-
cϵll = PeriodicCell(; cell_vectors = box, periodicity = periodicity)
52+
particles::AbstractVector{S},
53+
box::AUTOBOX{D},
54+
pbc::AUTOPBC{D};
55+
kwargs...
56+
) where {S, D}
57+
cϵll = PeriodicCell(; cell_vectors = box, periodicity = pbc)
6658
FlexibleSystem{D, S, typeof(cϵll)}(particles, cϵll, Dict(kwargs...))
6759
end
6860

src/implementation/utils.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ julia> bounding_box = [[10.0, 0.0, 0.0], [0.0, 10.0, 0.0], [0.0, 0.0, 10.0]]u"Å
1919
julia> pbcs = (true, true, false)
2020
julia> hydrogen = atomic_system([:H => [0, 0, 1.]u"bohr",
2121
:H => [0, 0, 3.]u"bohr"],
22-
bounding_box, pubcs)
22+
bounding_box, pbcs)
2323
```
2424
"""
2525
atomic_system(atoms::AbstractVector{<:Atom}, box, bcs; kwargs...) =
@@ -53,9 +53,9 @@ isolated_system(atoms::AbstractVector; kwargs...) =
5353

5454

5555
"""
56-
periodic_system(atoms::AbstractVector, bounding_box; fractional=false, kwargs...)
56+
periodic_system(atoms::AbstractVector, box; fractional=false, kwargs...)
5757
58-
Construct a [`FlexibleSystem`](@ref) with all boundaries of the `bounding_box` periodic
58+
Construct a [`FlexibleSystem`](@ref) with all boundaries of the `box` periodic
5959
(standard setup for modelling solid-state systems). If `fractional` is true, atom coordinates
6060
are given in fractional (and not in Cartesian) coordinates.
6161
Extra `kwargs` are stored as custom system properties.
@@ -71,24 +71,24 @@ julia> hydrogen = periodic_system([:H => [0, 0, 1.]u"bohr",
7171
7272
Setup a silicon unit cell using fractional positions
7373
```julia-repl
74-
julia> bounding_box = 10.26 / 2 * [[0, 0, 1], [1, 0, 1], [1, 1, 0]]u"bohr"
74+
julia> box = 10.26 / 2 * [[0, 0, 1], [1, 0, 1], [1, 1, 0]]u"bohr"
7575
julia> silicon = periodic_system([:Si => ones(3)/8,
7676
:Si => -ones(3)/8],
77-
bounding_box, fractional=true)
77+
box, fractional=true)
7878
```
7979
"""
8080
function periodic_system(atoms::AbstractVector,
81-
box::Union{Tuple, AbstractVector};
81+
box::AUTOBOX;
8282
fractional=false, kwargs...)
83-
pbcs = fill(true, length(box))
84-
lattice = tuple(box...)
85-
!fractional && return atomic_system(atoms, box, pbcs; kwargs...)
83+
lattice = _auto_cell_vectors(box)
84+
pbcs = fill(true, length(lattice))
85+
!fractional && return atomic_system(atoms, lattice, pbcs; kwargs...)
8686

8787
parse_fractional(atom::Atom) = atom
8888
function parse_fractional(atom::Pair)::Atom
8989
id, pos_fractional = atom
9090
Atom(id, sum(lattice .* pos_fractional))
9191
end
92-
atomic_system(parse_fractional.(atoms), box, pbcs; kwargs...)
92+
atomic_system(parse_fractional.(atoms), lattice, pbcs; kwargs...)
9393
end
9494

src/utils/cells.jl

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ Implementation of a computational cell for particle systems
3939
"""
4040
struct PeriodicCell{D, T}
4141
cell_vectors::NTuple{D, SVector{D, T}}
42-
pbc::NTuple{D, Bool}
42+
periodicity::NTuple{D, Bool}
4343
end
4444

4545
bounding_box(cell::PeriodicCell) = cell.cell_vectors
4646

47-
periodicity(cell::PeriodicCell) = cell.pbc
47+
periodicity(cell::PeriodicCell) = cell.periodicity
4848

4949
n_dimensions(::PeriodicCell{D}) where {D} = D
5050

@@ -62,7 +62,7 @@ PeriodicCell(cl::Union{AbstractSystem, PeriodicCell}) =
6262

6363
function Base.show(io::IO, cϵll::PeriodicCell{D}) where {D}
6464
u = unit(first(cϵll.cell_vectors[1][1]))
65-
print(io, "PeriodicCell(", prod(p -> p ? "T" : "F", cϵll.pbc), ", ")
65+
print(io, "PeriodicCell(", prod(p -> p ? "T" : "F", periodicity(cϵll)), ", ")
6666
for d = 1:D
6767
print(io, ustrip.(cϵll.cell_vectors[d]), u)
6868
if d < D; print(io, ", "); end
@@ -75,6 +75,16 @@ end
7575
# ---------------------------------------------
7676
# Utilities
7777

78+
# allowed input types that convert automatically to the
79+
# intended format for cell vectors, NTuple{D, SVector{D, T}}
80+
const AUTOBOX = Union{NTuple{D, <: AbstractVector},
81+
AbstractVector{<: AbstractVector}} where {D}
82+
83+
# allowed input types that convert automatically to the
84+
# intended format for pbc, NTuple{D, Bool}
85+
const AUTOPBC = Union{Bool,
86+
NTuple{D, Bool},
87+
AbstractVector{<: Bool}} where {D}
7888

7989
# different ways to construct cell vectors
8090

@@ -86,7 +96,7 @@ function _auto_cell_vectors(vecs::Tuple)
8696
return ntuple(i -> SVector{D}(vecs[i]), D)
8797
end
8898

89-
_auto_cell_vectors(vecs::AbstractVector) =
99+
_auto_cell_vectors(vecs::AbstractVector{<: AbstractVector}) =
90100
_auto_cell_vectors(tuple(vecs...))
91101

92102
# .... could consider allowing construction from a matrix but
@@ -95,7 +105,7 @@ _auto_cell_vectors(vecs::AbstractVector) =
95105

96106
# different ways to construct PBC
97107

98-
_auto_pbc1(bc::Bool) = bc
108+
_auto_pbc1(pbc::Bool) = pbc
99109
_auto_pbc1(::Nothing) = false
100110

101111
_auto_pbc(bc::Tuple, cell_vectors = nothing) =

test/test_docstrings.jl

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
# this set of tests is intended to confirm that docstrings throughout the
3+
# codebase actually run. Currently, this is just a rough draft that includes
4+
# specific doc strings that have been reported to fail. There should be a more
5+
# natural and automated way to test this.
6+
7+
using Unitful
8+
using UnitfulAtomic
9+
using AtomsBase
10+
using Test
11+
12+
##
13+
# atomic_system docstring
14+
15+
try
16+
bounding_box = [[10.0, 0.0, 0.0], [0.0, 10.0, 0.0], [0.0, 0.0, 10.0]]u"Å"
17+
pbcs = (true, true, false)
18+
hydrogen = atomic_system([:H => [0, 0, 1.]u"bohr",
19+
:H => [0, 0, 3.]u"bohr"],
20+
bounding_box, pbcs)
21+
@test true
22+
catch
23+
@error("atomic_system docstring failed to run")
24+
@test false
25+
end
26+
27+
28+
##
29+
# isolated_system docstring
30+
31+
try
32+
isolated_system([:H => [0, 0, 1.]u"bohr", :H => [0, 0, 3.]u"bohr"])
33+
@test true
34+
catch
35+
@error("isolated_system docstring failed to run")
36+
@test false
37+
end
38+
39+
##
40+
# periodic_system docstring 1
41+
42+
try
43+
bounding_box = ([10.0, 0.0, 0.0]u"Å", [0.0, 10.0, 0.0]u"Å", [0.0, 0.0, 10.0]u"Å")
44+
hydrogen = periodic_system([:H => [0, 0, 1.]u"bohr",
45+
:H => [0, 0, 3.]u"bohr"],
46+
bounding_box)
47+
@test true
48+
catch e
49+
@error("periodic_system docstring 1 failed to run")
50+
@test false
51+
end
52+
53+
##
54+
# periodic
55+
56+
try
57+
box = 10.26 / 2 * [[0, 0, 1], [1, 0, 1], [1, 1, 0]]u"bohr"
58+
silicon = periodic_system([:Si => ones(3)/8,
59+
:Si => -ones(3)/8],
60+
box, fractional=true)
61+
@test true
62+
catch e
63+
@error("periodic_system docstring 2 failed to run")
64+
@test false
65+
end

0 commit comments

Comments
 (0)