Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add create_atoms function to LAMMPS.jl #60

Merged
merged 14 commits into from
Aug 14, 2024
56 changes: 53 additions & 3 deletions src/LAMMPS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module LAMMPS
import MPI
include("api.jl")

export LMP, command, get_natoms, extract_atom, extract_compute, extract_global,
export LMP, command, create_atoms, get_natoms, extract_atom, extract_compute, extract_global,
extract_setting, gather, gather_bonds, gather_angles, gather_dihedrals, gather_impropers,
scatter!, group_to_atom_ids, get_category_ids, extract_variable,

Expand Down Expand Up @@ -33,8 +33,12 @@ export LMP, command, get_natoms, extract_atom, extract_compute, extract_global,
# _LMP_STYLE_CONST
STYLE_GLOBAL,
STYLE_ATOM,
STYLE_LOCAL
STYLE_LOCAL,

# LAMMPS to Julia types
BIGINT,
TAGINT,
IMAGEINT

using Preferences

Expand Down Expand Up @@ -75,6 +79,10 @@ const STYLE_GLOBAL = API.LMP_STYLE_GLOBAL
const STYLE_ATOM = API.LMP_STYLE_ATOM
const STYLE_LOCAL = API.LMP_STYLE_LOCAL

const BIGINT = API.lammps_extract_setting(C_NULL, "bigint") == 4 ? Int32 : Int64
const TAGINT = API.lammps_extract_setting(C_NULL, "tagint") == 4 ? Int32 : Int64
const IMAGEINT = API.lammps_extract_setting(C_NULL, "imageint") == 4 ? Int32 : Int64
jmeziere marked this conversation as resolved.
Show resolved Hide resolved

"""
locate()

Expand Down Expand Up @@ -233,6 +241,48 @@ function command(lmp::LMP, cmd::Union{String, Array{String}})
check(lmp)
end

"""
create_atoms(
lmp::LMP, x::Matrix{Float64}, id::Vector{Int32}, types::Vector{Int32};
v::Union{Ptr{Float64},Matrix{Float64}}=Ptr{Float64}(C_NULL),
image::Union{Ptr{IMAGEINT},Vector{IMAGEINT}}=Ptr{IMAGEINT}(C_NULL),
bexpand::Bool=false
)
Joroks marked this conversation as resolved.
Show resolved Hide resolved

Create atoms for a LAMMPS instance.
x contains the atom positions and should be a 3 by Matrix{Float64}, where n is the number of atoms.
id contains the id of each atom and should all be Vector{Int32} with length n.
types contains the atomic type (LAMMPS number) of each atom and should all be a Vector{Int32} with length n.
v contains the associated velocities and should be a 3 by Matrix{Float64}.
image contains the image flags for each atom and should be Vector{IMAGEINT} with length n.
bexpand is a Bool that defines whether or not the box should be expanded to fit the input atoms (default not).
vchuravy marked this conversation as resolved.
Show resolved Hide resolved
"""
function create_atoms(
lmp::LMP, x::Matrix{Float64}, id::Vector{Int32}, types::Vector{Int32};
v::Union{Ptr{Float64},Matrix{Float64}}=Ptr{Float64}(C_NULL),
jmeziere marked this conversation as resolved.
Show resolved Hide resolved
image::Union{Ptr{IMAGEINT},Vector{IMAGEINT}}=Ptr{IMAGEINT}(C_NULL),
bexpand::Bool=false
)
numAtoms = size(x, 2)
if size(x, 1) != 3
throw(ArgumentError("x must be a n by 3 matrix, where n is the number of atoms"))
end
if numAtoms != length(id)
throw(ArgumentError("id must have the same length as the number of atoms"))
end
if numAtoms != length(types)
throw(ArgumentError("types must have the same length as the number of atoms"))
end
if typeof(v) != Ptr{Float64} && size(x) != size(v)
throw(ArgumentError("x and v must be the same size"))
end
if typeof(image) != Ptr{IMAGEINT} && numAtoms != length(image)
throw(ArgumentError("image must have the same length as the number of atoms"))
end

API.lammps_create_atoms(lmp.handle, numAtoms, id, types, x, v, image, bexpand ? 1 : 0)
jmeziere marked this conversation as resolved.
Show resolved Hide resolved
end

"""
get_natoms(lmp::LMP)::Int64

Expand Down Expand Up @@ -339,7 +389,7 @@ Extract a global property from a LAMMPS instance.
| `LAMMPS_DOUBLE_2D` | `Matrix{Float64}` |
| `LAMMPS_INT64` | `Vector{Int64}` |
| `LAMMPS_INT64_2D` | `Matrix{Int64}` |
| `LAMMPS_STRING` | `String` (allways a copy) |
| `LAMMPS_STRING` | `String` (always a copy) |

Scalar values get returned as a vector with a single element. This way it's possible to
modify the internal state of the LAMMPS instance even if the data is scalar.
Expand Down
46 changes: 46 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,50 @@ end
end
end

@testset "Create Atoms" begin
LMP(["-screen", "none"]) do lmp
command(lmp, """
atom_modify map yes
region cell block 0 2 0 2 0 2
create_box 1 cell
lattice sc 1
""")
x = rand(3, 100)
id = Int32.(collect(1:100))
types = ones(Int32, 100)
image = ones(Int32, 100)
v = rand(3, 100)


create_atoms(lmp, x, id, types, v=v, image=image, bexpand=true)
jmeziere marked this conversation as resolved.
Show resolved Hide resolved
# Normally, you would have to sort by id, but we haven't done anything, so lammps
# will still have the same order
@test all(x .== extract_atom(
lmp, "x", LAMMPS_DOUBLE_2D
))
@test all(v .== extract_atom(
lmp, "v", LAMMPS_DOUBLE_2D
))

command(lmp, """
clear
atom_modify map yes
region cell block 0 2 0 2 0 2
create_box 1 cell
lattice sc 1
""")
create_atoms(lmp, x, id, types, bexpand=true)
@test all(zeros(3,100) .== extract_atom(
lmp, "v", LAMMPS_DOUBLE_2D
))

@test_throws ArgumentError create_atoms(lmp, x[1:2,:], id, types; v, image, bexpand=true)
@test_throws ArgumentError create_atoms(lmp, x, id[1:99], types, v=v, image=image, bexpand=true)
@test_throws ArgumentError create_atoms(lmp, x, id, types[1:99], v=v, image=image, bexpand=true)
@test_throws ArgumentError create_atoms(lmp, x, id, types, v=v[1:2,:], image=image, bexpand=true)
@test_throws ArgumentError create_atoms(lmp, x, id, types, v=v, image=image[1:99], bexpand=true)

end
end

@test success(pipeline(`$(MPI.mpiexec()) -n 2 $(Base.julia_cmd()) mpitest.jl`, stderr=stderr, stdout=stdout))