Merge branch 'develop' into more-clang-tidy-refactoring

# Conflicts:
#	src/MANIFOLD/manifold_thylakoid.cpp
This commit is contained in:
Axel Kohlmeyer
2021-10-27 15:23:57 -04:00
43 changed files with 228 additions and 268 deletions

View File

@ -81,9 +81,9 @@ check_for_autogen_files(${LAMMPS_SOURCE_DIR})
include(CheckIncludeFileCXX)
# set required compiler flags and compiler/CPU arch specific optimizations
if((CMAKE_CXX_COMPILER_ID STREQUAL "Intel") OR (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM"))
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Qrestrict")
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.3 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.4)

View File

@ -85,7 +85,7 @@ endfunction(GenerateBinaryHeader)
# fetch missing potential files
function(FetchPotentials pkgfolder potfolder)
if (EXISTS "${pkgfolder}/potentials.txt")
if(EXISTS "${pkgfolder}/potentials.txt")
file(STRINGS "${pkgfolder}/potentials.txt" linelist REGEX "^[^#].")
foreach(line ${linelist})
string(FIND ${line} " " blank)

View File

@ -321,9 +321,7 @@ following settings:
.. code-block:: make
LMP_INC = -DLAMMPS_JPEG
LMP_INC = -DLAMMPS_PNG
LMP_INC = -DLAMMPS_FFMPEG
LMP_INC = -DLAMMPS_JPEG -DLAMMPS_PNG -DLAMMPS_FFMPEG <other LMP_INC settings>
JPG_INC = -I/usr/local/include # path to jpeglib.h, png.h, zlib.h header files if make cannot find them
JPG_PATH = -L/usr/lib # paths to libjpeg.a, libpng.a, libz.a (.so) files if make cannot find them
@ -372,7 +370,7 @@ including :doc:`read_data <read_data>`, :doc:`rerun <rerun>`, and
.. code-block:: make
LMP_INC = -DLAMMPS_GZIP
LMP_INC = -DLAMMPS_GZIP <other LMP_INC settings>
This option requires that your operating system fully supports the
"popen()" function in the standard runtime library and that a ``gzip``
@ -454,7 +452,7 @@ those systems:
.. code-block:: make
LMP_INC = -DLAMMPS_LONGLONG_TO_LONG
LMP_INC = -DLAMMPS_LONGLONG_TO_LONG <other LMP_INC settings>
----------
@ -481,7 +479,7 @@ e.g. to Python. Of course, the calling code has to be set up to
.. code-block:: make
LMP_INC = -DLAMMPS_EXCEPTIONS
LMP_INC = -DLAMMPS_EXCEPTIONS <other LMP_INC settings>
.. note::
@ -522,7 +520,7 @@ executable, not the library.
.. code-block:: make
LMP_INC = -DLAMMPS_TRAP_FPE
LMP_INC = -DLAMMPS_TRAP_FPE <other LMP_INC settings>
After compilation with this flag set, the LAMMPS executable will stop
and produce a core dump when a division by zero, overflow, illegal math

View File

@ -42,6 +42,9 @@ Platform information functions
.. doxygenfunction:: mpi_info
:project: progguide
.. doxygenfunction:: compress_info
:project: progguide
File and path functions and global constants
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -41,7 +41,7 @@ set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Need -restrict with Intel compilers
if((CMAKE_CXX_COMPILER_ID STREQUAL "Intel") OR (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM"))
if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -restrict")
endif()

View File

@ -18,7 +18,7 @@
#endif
__kernel void kernel_cast_x(__global numtyp4 *restrict x_type,
const __global double *restrict x,
const __global numtyp *restrict x,
const __global int *restrict type,
const int nall) {
int ii=GLOBAL_ID_X;

View File

@ -475,7 +475,7 @@ class Atom {
UCL_Vector<numtyp,numtyp> v;
#ifdef GPU_CAST
UCL_Vector<double,double> x_cast;
UCL_Vector<numtyp,numtyp> x_cast;
UCL_Vector<int,int> type_cast;
#endif

View File

@ -82,9 +82,9 @@ __kernel void k_zbl(const __global numtyp4 *restrict x_,
const __global numtyp4 *restrict coeff1,
const __global numtyp4 *restrict coeff2,
const __global numtyp4 *restrict coeff3,
const double cut_globalsq,
const double cut_innersq,
const double cut_inner,
const numtyp cut_globalsq,
const numtyp cut_innersq,
const numtyp cut_inner,
const int lj_types,
const __global int *dev_nbor,
const __global int *dev_packed,
@ -174,9 +174,9 @@ __kernel void k_zbl_fast(const __global numtyp4 *restrict x_,
const __global numtyp4 *restrict coeff1_in,
const __global numtyp4 *restrict coeff2_in,
const __global numtyp4 *restrict coeff3_in,
const double cut_globalsq,
const double cut_innersq,
const double cut_inner,
const numtyp cut_globalsq,
const numtyp cut_innersq,
const numtyp cut_inner,
const __global int *dev_nbor,
const __global int *dev_packed,
__global acctyp4 *restrict ans,

View File

@ -67,9 +67,9 @@ class ZBL : public BaseAtomic<numtyp, acctyp> {
/// If atom type constants fit in shared memory, use fast kernels
bool shared_types;
double _cut_globalsq;
double _cut_innersq;
double _cut_inner;
numtyp _cut_globalsq;
numtyp _cut_innersq;
numtyp _cut_inner;
/// Number of atom types
int _lj_types;

View File

@ -62,7 +62,6 @@ if me == 0:
plt.show(block=False)
# run nfreq steps at a time w/out pre/post, query compute, refresh plot
import time
while ntimestep < nsteps:
lmp.command("run %d pre no post no" % nfreq)

View File

@ -13,7 +13,6 @@
from __future__ import print_function
import sys
import numpy as np
import ctypes
# parse command line

View File

@ -99,7 +99,7 @@ class lammps(object):
# load a shared object.
try:
if ptr: self.lib = CDLL("",RTLD_GLOBAL)
if ptr is not None: self.lib = CDLL("",RTLD_GLOBAL)
except OSError:
self.lib = None
@ -329,7 +329,7 @@ class lammps(object):
# ptr is the desired instance of LAMMPS
# just convert it to ctypes ptr and store in self.lmp
if not ptr:
if ptr is None:
# with mpi4py v2+, we can pass MPI communicators to LAMMPS
# need to adjust for type of MPI communicator object
@ -338,7 +338,7 @@ class lammps(object):
from mpi4py import MPI
self.MPI = MPI
if comm:
if comm is not None:
if not self.has_mpi_support:
raise Exception('LAMMPS not compiled with real MPI library')
if not self.has_mpi4py:
@ -354,7 +354,7 @@ class lammps(object):
narg = 0
cargs = None
if cmdargs:
if cmdargs is not None:
cmdargs.insert(0,"lammps")
narg = len(cmdargs)
for i in range(narg):
@ -376,7 +376,7 @@ class lammps(object):
if self.has_mpi4py and self.has_mpi_support:
self.comm = self.MPI.COMM_WORLD
self.opened = 1
if cmdargs:
if cmdargs is not None:
cmdargs.insert(0,"lammps")
narg = len(cmdargs)
for i in range(narg):
@ -1361,7 +1361,7 @@ class lammps(object):
This function is a wrapper around the :cpp:func:`lammps_create_atoms`
function of the C-library interface, and the behavior is similar except
that the *v*, *image*, and *shrinkexceed* arguments are optional and
default to *None*, *None*, and *False*, respectively. With none being
default to *None*, *None*, and *False*, respectively. With *None* being
equivalent to a ``NULL`` pointer in C.
The lists of coordinates, types, atom IDs, velocities, image flags can
@ -1389,7 +1389,7 @@ class lammps(object):
:return: number of atoms created. 0 if insufficient or invalid data
:rtype: int
"""
if id:
if id is not None:
id_lmp = (self.c_tagint*n)()
try:
id_lmp[:] = id[0:n]
@ -1411,7 +1411,7 @@ class lammps(object):
except ValueError:
return 0
if v:
if v is not None:
v_lmp = (c_double*(three_n))()
try:
v_lmp[:] = v[0:three_n]
@ -1420,7 +1420,7 @@ class lammps(object):
else:
v_lmp = None
if image:
if image is not None:
img_lmp = (self.c_imageint*n)()
try:
img_lmp[:] = image[0:n]

View File

@ -854,30 +854,30 @@ class IPyLammps(PyLammps):
"""
cmd_args = [group, "image", filename, color, diameter]
if size:
if size is not None:
width = size[0]
height = size[1]
cmd_args += ["size", width, height]
if view:
if view is not None:
theta = view[0]
phi = view[1]
cmd_args += ["view", theta, phi]
if center:
if center is not None:
flag = center[0]
Cx = center[1]
Cy = center[2]
Cz = center[3]
cmd_args += ["center", flag, Cx, Cy, Cz]
if up:
if up is not None:
Ux = up[0]
Uy = up[1]
Uz = up[2]
cmd_args += ["up", Ux, Uy, Uz]
if zoom:
if zoom is not None:
cmd_args += ["zoom", zoom]
cmd_args.append("modify backcolor " + background_color)

View File

@ -28,7 +28,6 @@
#include "random_mars.h"
#include "respa.h"
#include "potential_file_reader.h"
#include "tokenizer.h"
#include "update.h"
#include <cmath>
@ -491,10 +490,10 @@ void FixTTM::read_electron_temperatures(const std::string &filename)
// check correctness of input data
if ((ix < 0) || (ix >= nxgrid) || (iy < 0) || (iy >= nygrid) || (iz < 0) || (iz >= nzgrid))
throw parser_error("Fix ttm invalid grid index in fix ttm grid file");
throw TokenizerException("Fix ttm invalid grid index in fix ttm grid file","");
if (T_tmp < 0.0)
throw parser_error("Fix ttm electron temperatures must be > 0.0");
throw TokenizerException("Fix ttm electron temperatures must be > 0.0","");
T_electron[iz][iy][ix] = T_tmp;
T_initial_set[iz][iy][ix] = 1;

View File

@ -77,14 +77,6 @@ class FixTTM : public Fix {
virtual void deallocate_grid();
virtual void read_electron_temperatures(const std::string &);
virtual void write_electron_temperatures(const std::string &);
class parser_error : public std::exception {
std::string message;
public:
parser_error(const std::string &mesg) { message = mesg; }
const char *what() const noexcept { return message.c_str(); }
};
};
} // namespace LAMMPS_NS

View File

@ -306,7 +306,7 @@ void FixTTMGrid::read_electron_temperatures(const std::string &filename)
int iz = values.next_int();
if (ix < 0 || ix >= nxgrid || iy < 0 || iy >= nygrid || iz < 0 || iz >= nzgrid)
throw parser_error("Fix ttm/grid invalid grid index in input");
throw TokenizerException("Fix ttm/grid invalid grid index in input","");
if (ix >= nxlo_in && ix <= nxhi_in && iy >= nylo_in && iy <= nyhi_in
&& iz >= nzlo_in && iz <= nzhi_in) {
@ -314,7 +314,7 @@ void FixTTMGrid::read_electron_temperatures(const std::string &filename)
T_initial_set[iz][iy][ix] = 1;
}
} else {
throw parser_error("Incorrect format in fix ttm electron grid file");
throw TokenizerException("Incorrect format in fix ttm electron grid file","");
}
} catch (std::exception &e) {
error->one(FLERR,e.what());

View File

@ -584,10 +584,10 @@ void FixTTMMod::read_electron_temperatures(const std::string &filename)
// check correctness of input data
if ((ix < 0) || (ix >= nxgrid) || (iy < 0) || (iy >= nygrid) || (iz < 0) || (iz >= nzgrid))
throw parser_error("Fix ttm invalid grid index in fix ttm/mod grid file");
throw TokenizerException("Fix ttm invalid grid index in fix ttm/mod grid file","");
if (T_tmp < 0.0)
throw parser_error("Fix ttm electron temperatures must be > 0.0");
throw TokenizerException("Fix ttm electron temperatures must be > 0.0","");
T_electron[iz][iy][ix] = T_tmp;
T_initial_set[iz][iy][ix] = 1;

View File

@ -87,14 +87,6 @@ class FixTTMMod : public Fix {
void read_parameters(const std::string &);
void read_electron_temperatures(const std::string &);
void write_electron_temperatures(const std::string &);
class parser_error : public std::exception {
std::string message;
public:
parser_error(const std::string &mesg) { message = mesg; }
const char *what() const noexcept { return message.c_str(); }
};
};
} // namespace LAMMPS_NS

View File

@ -1966,7 +1966,7 @@ void FixACKS2ReaxFFKokkos<DeviceType>::get_chi_field()
namespace LAMMPS_NS {
template class FixACKS2ReaxFFKokkos<LMPDeviceType>;
#ifdef KOKKOS_ENABLE_CUDA
#ifdef LMP_KOKKOS_GPU
template class FixACKS2ReaxFFKokkos<LMPHostType>;
#endif
}

View File

@ -299,7 +299,7 @@ struct FixACKS2ReaxFFKokkosComputeHFunctor {
c.template compute_h_team<NEIGHFLAG>(team, atoms_per_team, vector_length);
}
size_t team_shmem_size(int team_size) const {
size_t team_shmem_size(int /*team_size*/) const {
size_t shmem_size =
Kokkos::View<int *, scratch_space, Kokkos::MemoryUnmanaged>::shmem_size(
atoms_per_team) + // s_ilist
@ -347,7 +347,7 @@ struct FixACKS2ReaxFFKokkosComputeXFunctor {
c.template compute_x_team<NEIGHFLAG>(team, atoms_per_team, vector_length);
}
size_t team_shmem_size(int team_size) const {
size_t team_shmem_size(int /*team_size*/) const {
size_t shmem_size =
Kokkos::View<int *, scratch_space, Kokkos::MemoryUnmanaged>::shmem_size(
atoms_per_team) + // s_ilist

View File

@ -30,7 +30,6 @@ FixStyle(qeq/reax/kk/host,FixQEqReaxFFKokkos<LMPHostType>);
#include "kokkos_type.h"
#include "neigh_list.h"
#include "neigh_list_kokkos.h"
#include "kokkos_base.h"
namespace LAMMPS_NS {
@ -42,7 +41,7 @@ struct TagFixQEqReaxFFPackForwardComm {};
struct TagFixQEqReaxFFUnpackForwardComm {};
template<class DeviceType>
class FixQEqReaxFFKokkos : public FixQEqReaxFF, public KokkosBase {
class FixQEqReaxFFKokkos : public FixQEqReaxFF {
public:
typedef DeviceType device_type;
typedef ArrayTypes<DeviceType> AT;

View File

@ -44,7 +44,7 @@
#define GPU_AWARE_UNKNOWN static int have_gpu_aware = -1;
// TODO HIP: implement HIP-aware MPI support (UCX) detection
#if defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL)
#if defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL) || defined(KOKKOS_ENABLE_OPENMPTARGET)
GPU_AWARE_UNKNOWN
#elif defined(KOKKOS_ENABLE_CUDA)
@ -121,7 +121,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
} else if (strcmp(arg[iarg],"g") == 0 ||
strcmp(arg[iarg],"gpus") == 0) {
#ifndef LMP_KOKKOS_GPU
error->all(FLERR,"GPUs are requested but Kokkos has not been compiled for CUDA, HIP, or SYCL");
error->all(FLERR,"GPUs are requested but Kokkos has not been compiled using a GPU-enabled backend");
#endif
if (iarg+2 > narg) error->all(FLERR,"Invalid Kokkos command-line args");
ngpus = atoi(arg[iarg+1]);
@ -162,7 +162,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
if (ngpus > 1 && !set_flag)
error->all(FLERR,"Could not determine local MPI rank for multiple "
"GPUs with Kokkos CUDA, HIP, or SYCL because MPI library not recognized");
"GPUs with Kokkos because MPI library not recognized");
} else if (strcmp(arg[iarg],"t") == 0 ||
strcmp(arg[iarg],"threads") == 0) {
@ -204,7 +204,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
#ifdef LMP_KOKKOS_GPU
if (ngpus <= 0)
error->all(FLERR,"Kokkos has been compiled for CUDA, HIP, or SYCL but no GPUs are requested");
error->all(FLERR,"Kokkos has been compiled with GPU-enabled backend but no GPUs are requested");
#endif
#ifndef KOKKOS_ENABLE_SERIAL
@ -311,7 +311,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
error->warning(FLERR,"Detected MPICH. Disabling GPU-aware MPI");
#else
if (me == 0)
error->warning(FLERR,"Kokkos with CUDA, HIP, or SYCL assumes CUDA-aware MPI is available,"
error->warning(FLERR,"Kokkos with GPU-enabled backend assumes GPU-aware MPI is available,"
" but cannot determine if this is the case\n try"
" '-pk kokkos gpu/aware off' if getting segmentation faults");

View File

@ -87,7 +87,7 @@ E: Invalid Kokkos command-line args
Self-explanatory. See Section 2.7 of the manual for details.
E: Could not determine local MPI rank for multiple GPUs with Kokkos CUDA
E: Could not determine local MPI rank for multiple GPUs with Kokkos
because MPI library not recognized
The local MPI rank was not found in one of four supported environment variables.
@ -96,13 +96,13 @@ E: Invalid number of threads requested for Kokkos: must be 1 or greater
Self-explanatory.
E: GPUs are requested but Kokkos has not been compiled for CUDA
E: GPUs are requested but Kokkos has not been compiled using GPU-enabled backend
Recompile Kokkos with CUDA support to use GPUs.
Recompile Kokkos with GPU-enabled backend to use GPUs.
E: Kokkos has been compiled for CUDA, HIP, or SYCL but no GPUs are requested
E: Kokkos has been compiled with GPU-enabled backend but no GPUs are requested
One or more GPUs must be used when Kokkos is compiled for CUDA/HIP/SYCL.
One or more GPUs must be used when Kokkos is compiled for CUDA/HIP/SYCL/OpenMPTarget.
W: Kokkos package already initalized, cannot reinitialize with different parameters

View File

@ -20,7 +20,7 @@
#include <Kokkos_Core.hpp>
#include <Kokkos_DualView.hpp>
#include <impl/Kokkos_Timer.hpp>
#include <Kokkos_Timer.hpp>
#include <Kokkos_Vectorization.hpp>
#include <Kokkos_ScatterView.hpp>
#include <Kokkos_UnorderedMap.hpp>
@ -34,7 +34,7 @@ constexpr int HALF = 4;
#define ISFINITE(x) std::isfinite(x)
#endif
#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL)
#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) || defined(KOKKOS_ENABLE_SYCL) || defined(KOKKOS_ENABLE_OPENMPTARGET)
#define LMP_KOKKOS_GPU
#endif
@ -223,6 +223,11 @@ template<>
struct ExecutionSpaceFromDevice<Kokkos::Experimental::SYCL> {
static const LAMMPS_NS::ExecutionSpace space = LAMMPS_NS::Device;
};
#elif defined(KOKKOS_ENABLE_OPENMPTARGET)
template<>
struct ExecutionSpaceFromDevice<Kokkos::Experimental::OpenMPTarget> {
static const LAMMPS_NS::ExecutionSpace space = LAMMPS_NS::Device;
};
#endif
// set host pinned space
@ -232,6 +237,8 @@ typedef Kokkos::CudaHostPinnedSpace LMPPinnedHostType;
typedef Kokkos::Experimental::HIPHostPinnedSpace LMPPinnedHostType;
#elif defined(KOKKOS_ENABLE_SYCL)
typedef Kokkos::Experimental::SYCLSharedUSMSpace LMPPinnedHostType;
#elif defined(KOKKOS_ENABLE_OPENMPTARGET)
typedef Kokkos::Serial LMPPinnedHostType;
#endif
// create simple LMPDeviceSpace typedef for non CUDA-, HIP-, or SYCL-specific
@ -242,6 +249,8 @@ typedef Kokkos::Cuda LMPDeviceSpace;
typedef Kokkos::Experimental::HIP LMPDeviceSpace;
#elif defined(KOKKOS_ENABLE_SYCL)
typedef Kokkos::Experimental::SYCL LMPDeviceSpace;
#elif defined(KOKKOS_ENABLE_OPENMPTARGET)
typedef Kokkos::Experimental::OpenMPTarget LMPDeviceSpace;
#endif
@ -280,6 +289,11 @@ template<>
struct AtomicDup<HALFTHREAD,Kokkos::Experimental::SYCL> {
using value = Kokkos::Experimental::ScatterAtomic;
};
#elif defined(KOKKOS_ENABLE_OPENMPTARGET)
template<>
struct AtomicDup<HALFTHREAD,Kokkos::Experimental::OpenMPTarget> {
using value = Kokkos::Experimental::ScatterAtomic;
};
#endif
#ifdef LMP_KOKKOS_USE_ATOMICS

View File

@ -226,7 +226,8 @@ void NPairKokkos<DeviceType,HALF_NEIGH,GHOST,TRI,SIZE>::build(NeighList *list_)
data.h_resize() = 0;
Kokkos::deep_copy(d_scalars, h_scalars);
#ifdef LMP_KOKKOS_GPU
#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP)
#define BINS_PER_BLOCK 2
const int factor = atoms_per_bin<64?2:1;
#else
@ -605,14 +606,15 @@ void NeighborKokkosExecute<DeviceType>::build_ItemGPU(typename Kokkos::TeamPolic
other_x[MY_II + 3 * atoms_per_bin] = itype;
}
other_id[MY_II] = i;
#ifndef KOKKOS_ENABLE_SYCL
#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP)
int test = (__syncthreads_count(i >= 0 && i <= nlocal) == 0);
if (test) return;
#else
#elif defined(KOKKOS_ENABLE_SYCL)
int not_done = (i >= 0 && i <= nlocal);
dev.team_reduce(Kokkos::Max<int>(not_done));
if(not_done == 0) return;
#elif defined(KOKKOS_ENABLE_OPENMPTARGET)
dev.team_barrier();
#endif
if (i >= 0 && i < nlocal) {
@ -1055,14 +1057,15 @@ void NeighborKokkosExecute<DeviceType>::build_ItemSizeGPU(typename Kokkos::TeamP
other_x[MY_II + 4 * atoms_per_bin] = radi;
}
other_id[MY_II] = i;
#ifndef KOKKOS_ENABLE_SYCL
#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP)
int test = (__syncthreads_count(i >= 0 && i <= nlocal) == 0);
if (test) return;
#else
#elif defined(KOKKOS_ENABLE_SYCL)
int not_done = (i >= 0 && i <= nlocal);
dev.team_reduce(Kokkos::Max<int>(not_done));
if(not_done == 0) return;
#elif defined(KOKKOS_ENABLE_OPENMPTARGET)
dev.team_barrier();
#endif
if (i >= 0 && i < nlocal) {

View File

@ -283,7 +283,7 @@ void VerletKokkos::run(int n)
atomKK->sync(Device,ALL_MASK);
//static double time = 0.0;
//Kokkos::Impl::Timer ktimer;
//Kokkos::Timer ktimer;
timer->init_timeout();
for (int i = 0; i < n; i++) {
@ -445,7 +445,7 @@ void VerletKokkos::run(int n)
if (pair_compute_flag) {
atomKK->sync(force->pair->execution_space,force->pair->datamask_read);
atomKK->sync(force->pair->execution_space,~(~force->pair->datamask_read|(F_MASK | ENERGY_MASK | VIRIAL_MASK)));
Kokkos::Impl::Timer ktimer;
Kokkos::Timer ktimer;
force->pair->compute(eflag,vflag);
atomKK->modified(force->pair->execution_space,force->pair->datamask_modify);
atomKK->modified(force->pair->execution_space,~(~force->pair->datamask_modify|(F_MASK | ENERGY_MASK | VIRIAL_MASK)));

View File

@ -140,10 +140,8 @@ FixNVEManifoldRattle::FixNVEManifoldRattle( LAMMPS *lmp, int &narg, char **arg,
if (strcmp(arg[argi], "every") == 0) {
nevery = utils::inumeric(FLERR,arg[argi+1],false,lmp);
next_output = update->ntimestep + nevery;
if (comm->me == 0) {
fprintf(screen,"Outputting every %d steps, next is %d\n",
nevery, next_output);
}
if (comm->me == 0)
utils::logmesg(lmp,"Outputting every {} steps, next is {}\n",nevery, next_output);
argi += 2;
} else if (error_on_unknown_keyword) {
error->all(FLERR,"Error parsing arg \"{}\".\n",arg[argi]);
@ -211,11 +209,9 @@ void FixNVEManifoldRattle::print_stats( const char *header )
double inv_tdiff = 1.0/( static_cast<double>(ntimestep) - stats.last_out );
stats.last_out = ntimestep;
fprintf(screen, "%s stats for time step " BIGINT_FORMAT " on %d atoms:\n",
header, ntimestep, stats.natoms);
fprintf(screen, " iters/atom: x = %f, v = %f, dofs removed %d",
x_iters * inv_tdiff, v_iters * inv_tdiff, stats.dofs_removed);
fprintf(screen,"\n");
utils::logmesg(lmp, "{} stats for time step {} on {} atoms:\n", header, ntimestep, stats.natoms);
utils::logmesg(lmp, " iters/atom: x = {}, v = {}, dofs removed = {}\n",
x_iters * inv_tdiff, v_iters * inv_tdiff, stats.dofs_removed);
}
stats.x_iters_per_atom = 0;

View File

@ -32,21 +32,21 @@
------------------------------------------------------------------------- */
#include "fix_nvt_manifold_rattle.h"
#include <cstring>
#include <cmath>
#include "atom.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "group.h"
#include "citeme.h"
#include "modify.h"
#include "compute.h"
#include "error.h"
#include "force.h"
#include "group.h"
#include "modify.h"
#include "update.h"
#include "manifold.h"
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS;
using namespace FixConst;
@ -115,9 +115,7 @@ FixNVTManifoldRattle::FixNVTManifoldRattle(LAMMPS *lmp, int narg, char **arg,
mtchain = utils::inumeric(FLERR, arg[argi+1],false,lmp);
argi += 2;
} else if (error_on_unknown_keyword) {
char msg[2048];
sprintf(msg,"Error parsing arg \"%s\".\n", arg[argi]);
error->all(FLERR, msg);
error->all(FLERR, "Error parsing arg \"{}\".\n", arg[argi]);
} else {
argi += 1;
}
@ -271,12 +269,8 @@ void FixNVTManifoldRattle::nhc_temp_integrate()
factor_eta = exp(-dthalf*eta_dot[0]);
if (factor_eta == 0) {
char msg[2048];
sprintf(msg, "WTF, factor_eta is 0! dthalf = %f, eta_dot[0] = %f",
dthalf, eta_dot[0]);
error->all(FLERR,msg);
}
if (factor_eta == 0)
error->all(FLERR, "factor_eta is 0! dthalf = {}, eta_dot[0] = {}", dthalf, eta_dot[0]);
nh_v_temp();

View File

@ -67,9 +67,7 @@ public:
double get_t_from_x( double xx ) const
{
if (xx < x0 || xx > x1) {
char msg[2048];
sprintf(msg, "x ( %g ) out of bounds [%g, %g]", xx, x0, x1 );
err->one(FLERR, msg);
err->one(FLERR,"x ( {} ) out of bounds [{}, {}]", xx, x0, x1 );
}
// Newton iterate to get right t.
@ -271,8 +269,6 @@ void manifold_gaussian_bump::post_param_init()
make_lut();
// test_lut();
}
@ -360,31 +356,3 @@ void manifold_gaussian_bump::lut_get_z_and_zp( double rr, double &zz,
zz = zleft * fmin + zright * frac;
zzp = zpleft * fmin + zpright * frac;
}
void manifold_gaussian_bump::test_lut()
{
double x[3], nn[3];
if (comm->me != 0) return;
FILE *fp = fopen( "test_lut_gaussian.dat", "w" );
double dx = 0.1;
for (double xx = 0; xx < 20; xx += dx) {
x[0] = xx;
x[1] = 0.0;
x[2] = 0.0;
double gg = g( x );
n( x, nn );
double taper_z;
if (xx <= rc1) {
taper_z = gaussian_bump(xx);
} else if (xx < rc2) {
taper_z = lut_get_z( xx );
} else {
taper_z = 0.0;
}
fprintf( fp, "%g %g %g %g %g %g %g\n", xx, gaussian_bump(xx), taper_z,
gg, nn[0], nn[1], nn[2] );
}
fclose(fp);
}

View File

@ -86,8 +86,6 @@ namespace user_manifold {
double lut_get_zp(double rr) const;
void lut_get_z_and_zp(double rr, double &zz, double &zzp) const;
void test_lut();
double taper(double);
double taper_der(double);
};

View File

@ -34,8 +34,6 @@ manifold_thylakoid::manifold_thylakoid( LAMMPS *lmp, int /*narg*/, char ** /*arg
// fix should call post_param_init();
}
manifold_thylakoid::~manifold_thylakoid()
{
for (auto & part : parts) {
@ -43,8 +41,6 @@ manifold_thylakoid::~manifold_thylakoid()
}
}
void manifold_thylakoid::post_param_init()
{
// Set coefficients:
@ -59,52 +55,21 @@ void manifold_thylakoid::post_param_init()
LB = params[1];
lB = params[2];
if (comm->me == 0) {
fprintf(screen,"My params are now: lT = %f, LT = %f, pad = %f, "
"wB = %f, LB = %f, lB = %f\n", lT, LT, pad, wB, LB, lB );
fprintf(screen,"Calling init_domains() from post_param_init().\n");
}
init_domains();
checkup();
}
void manifold_thylakoid::checkup()
{
if (comm->me == 0) {
fprintf(screen,"This is checkup of thylakoid %p\n", this);
fprintf(screen,"I have %ld parts. They are:\n", parts.size());
for (auto & part : parts) {
fprintf(screen, "[%f, %f] x [%f, %f] x [%f, %f]\n",
part->xlo, part->xhi,
part->ylo, part->yhi,
part->zlo, part->zhi );
}
fprintf(screen,"My params are:\n");
for (int i = 0; i < NPARAMS; ++i) {
fprintf(screen,"%f\n", params[i]);
}
}
}
double manifold_thylakoid::g( const double *x )
{
int err = 0;
std::size_t idx;
thyla_part *p = get_thyla_part(x,&err,&idx);
if (err) {
char msg[2048];
sprintf(msg,"Error getting thyla_part for x = (%f, %f, %f)",x[0],x[1],x[2]);
error->one(FLERR,msg);
}
if (err) error->one(FLERR,"Error getting thyla_part for x = ({}, {}, {})",x[0],x[1],x[2]);
double con_val = p->g(x);
if (std::isfinite(con_val)) {
return con_val;
} else {
char msg[2048];
sprintf(msg,"Error, thyla_part of type %d returned %f as constraint val!",
p->type, con_val);
error->one(FLERR,msg);
error->one(FLERR,"Error, thyla_part of type {} returned {} as constraint val!", p->type, con_val);
return 0;
}
}
@ -114,20 +79,14 @@ void manifold_thylakoid::n( const double *x, double *n )
int err = 0;
std::size_t idx;
thyla_part *p = get_thyla_part(x,&err,&idx);
if (err) {
char msg[2048];
sprintf(msg,"Error getting thyla_part for x = (%f, %f, %f)",x[0],x[1],x[2]);
error->one(FLERR,msg);
}
if (err)
error->one(FLERR,"Error getting thyla_part for x = ({}, {}, {})",x[0],x[1],x[2]);
p->n(x,n);
if (std::isfinite(n[0]) && std::isfinite(n[1]) && std::isfinite(n[2])) {
return;
} else {
char msg[2048];
sprintf(msg,"Error, thyla_part of type %d returned (%f,%f,%f) as gradient!",
p->type, n[0], n[1], n[2]);
error->one(FLERR,msg);
}
} else
error->one(FLERR,"thyla_part of type {} returned ({},{},{}) as gradient!",
p->type, n[0], n[1], n[2]);
}
thyla_part *manifold_thylakoid::get_thyla_part( const double *x, int * /*err_flag*/, std::size_t *idx )
@ -140,9 +99,7 @@ thyla_part *manifold_thylakoid::get_thyla_part( const double *x, int * /*err_fla
return p;
}
}
char msg[2048];
sprintf(msg,"Could not find thyla_part for x = (%f,%f,%f)", x[0],x[1],x[2]);
error->one(FLERR,msg);
error->one(FLERR,"Could not find thyla_part for x = ({},{},{})", x[0],x[1],x[2]);
return nullptr;
}
@ -153,12 +110,9 @@ thyla_part *manifold_thylakoid::get_thyla_part( const double *x, int * /*err_fla
void manifold_thylakoid::init_domains()
{
if (wB + 2*lB > LT) {
char msg[2048];
sprintf(msg,"LT = %f not large enough to accommodate bridge with "
"wB = %f and lB = %f! %f > %f\n", LT, wB, lB, wB + 2*lB, LT);
error->one(FLERR,msg);
}
if (wB + 2*lB > LT)
error->one(FLERR,"LT = {} not large enough to accommodate bridge with "
"wB = {} and lB = {}! {} > {}\n", LT, wB, lB, wB + 2*lB, LT);
// Determine some constant coordinates:
x0 = -( 0.5*LB + lB + lT + LT + lT + pad);
@ -375,12 +329,9 @@ void manifold_thylakoid::init_domains()
parts.push_back(p);
// Check if this plane lines up with bl:
if (fabs(plr.pt[0] - bl.pt[0] + lB) > 1e-8) {
char msg[2048];
sprintf(msg,"Origins of plane left right and bridge left misaligned! %f != %f!\n",
plr.pt[0], bl.pt[0] - lB );
error->one(FLERR,msg);
}
if (fabs(plr.pt[0] - bl.pt[0] + lB) > 1e-8)
error->one(FLERR,"Origins of plane left right and bridge left misaligned! {} != {}!\n",
plr.pt[0], bl.pt[0] - lB );
// Now, for the right stack, you can mirror the other...
// To mirror them you need to invert lo[0] and hi[0] and flip their sign.
@ -428,12 +379,9 @@ void manifold_thylakoid::init_domains()
set_domain(p, prr.lo, prr.hi);
parts.push_back(p);
if (fabs(prr.pt[0] - br.pt[0] - lB) > 1e-8) {
char msg[2048];
sprintf(msg,"Origins of plane left right and bridge left misaligned! %f != %f!\n",
prr.pt[0], br.pt[0] + lB);
error->one(FLERR,msg);
}
if (fabs(prr.pt[0] - br.pt[0] - lB) > 1e-8)
error->one(FLERR,"Origins of plane left right and bridge left misaligned! {} != {}!\n",
prr.pt[0], br.pt[0] + lB);
}

View File

@ -37,7 +37,6 @@ namespace user_manifold {
virtual int nparams() { return NPARAMS; }
virtual void post_param_init();
virtual void checkup(); // Some diagnostics...
private:
void init_domains();

View File

@ -42,12 +42,14 @@ using namespace FixConst;
#define MAXLINE 1024
class parser_error : public std::exception {
std::string message;
public:
parser_error(const std::string &mesg) { message = mesg; }
const char *what() const noexcept { return message.c_str(); }
};
namespace {
class qeq_parser_error : public std::exception {
std::string message;
public:
explicit qeq_parser_error(const std::string &mesg) { message = mesg; }
const char *what() const noexcept { return message.c_str(); }
};
}
/* ---------------------------------------------------------------------- */
@ -759,8 +761,8 @@ void FixQEq::read_file(char *file)
FILE *fp = utils::open_potential(file,lmp,nullptr);
if (fp == nullptr)
throw parser_error(fmt::format("Cannot open fix qeq parameter file {}:"
" {}", file,utils::getsyserror()));
throw qeq_parser_error(fmt::format("Cannot open fix qeq parameter file {}: {}",
file,utils::getsyserror()));
TextFileReader reader(fp, "qeq parameter");
while (true) {
@ -768,12 +770,12 @@ void FixQEq::read_file(char *file)
if (values.count() == 0) continue;
if (values.count() < 6)
throw parser_error("Invalid qeq parameter file");
throw qeq_parser_error("Invalid qeq parameter file");
auto word = values.next_string();
utils::bounds(FLERR,word,1,ntypes,nlo,nhi,nullptr);
if ((nlo < 0) || (nhi < 0))
throw parser_error("Invalid atom type range");
throw qeq_parser_error(fmt::format("Invalid atom type range: {}",word));
val = values.next_double();
for (int n=nlo; n <= nhi; ++n) chi[n] = val;

View File

@ -43,13 +43,6 @@
using namespace LAMMPS_NS;
using namespace FixConst;
class parser_error : public std::exception {
std::string message;
public:
parser_error(const std::string &mesg) { message = mesg; }
const char *what() const noexcept { return message.c_str(); }
};
static const char cite_fix_acks2_reax[] =
"fix acks2/reaxff command:\n\n"
"@Article{O'Hearn2020,\n"
@ -173,26 +166,27 @@ void FixACKS2ReaxFF::pertype_parameters(char *arg)
const char *line = reader.next_line();
if (!line)
throw parser_error("Invalid parameter file for fix acks2/reaxff");
throw TokenizerException("Invalid parameter file for fix acks2/reaxff","");
ValueTokenizer values(line);
if (values.count() != 1)
throw parser_error("Fix acks2/reaxff: Incorrect format of parameter file");
throw TokenizerException("Fix acks2/reaxff: Incorrect parameter file format","");
bond_softness = values.next_double();
for (int i = 1; i <= ntypes; i++) {
const char *line = reader.next_line();
if (!line)
throw parser_error("Invalid parameter file for fix acks2/reaxff");
throw TokenizerException("Fix acks2/reaxff: Incorrect parameter file format","");
ValueTokenizer values(line);
if (values.count() != 5)
throw parser_error("Fix acks2/reaxff: Incorrect format of parameter file");
throw TokenizerException("Fix acks2/reaxff: Incorrect parameter file format","");
int itype = values.next_int();
if ((itype < 1) || (itype > ntypes))
throw parser_error("Fix acks2/reaxff: invalid atom type in parameter file");
throw TokenizerException("Fix acks2/reaxff: invalid atom type in parameter file",
std::to_string(itype));
chi[itype] = values.next_double();
eta[itype] = values.next_double();

View File

@ -45,17 +45,11 @@
#include <cmath>
#include <cstring>
#include <exception>
#include <string>
using namespace LAMMPS_NS;
using namespace FixConst;
class parser_error : public std::exception {
std::string message;
public:
parser_error(const std::string &mesg) { message = mesg; }
const char *what() const noexcept { return message.c_str(); }
};
static constexpr double EV_TO_KCAL_PER_MOL = 14.4;
static constexpr double SMALL = 1.0e-14;
@ -241,15 +235,16 @@ void FixQEqReaxFF::pertype_parameters(char *arg)
for (int i = 1; i <= ntypes; i++) {
const char *line = reader.next_line();
if (!line)
throw parser_error("Invalid param file for fix qeq/reaxff");
throw TokenizerException("Fix qeq/reaxff: Invalid param file format","");
ValueTokenizer values(line);
if (values.count() != 4)
throw parser_error("Fix qeq/reaxff: Incorrect format of param file");
throw TokenizerException("Fix qeq/reaxff: Incorrect format of param file","");
int itype = values.next_int();
if ((itype < 1) || (itype > ntypes))
throw parser_error("Fix qeq/reaxff: invalid atom type in param file");
throw TokenizerException("Fix qeq/reaxff: invalid atom type in param file",
std::to_string(itype));
chi[itype] = values.next_double();
eta[itype] = values.next_double();

View File

@ -54,10 +54,12 @@ namespace ReaxFF {
"energy_update_freq", "atom_info", "atom_velocities", "atom_forces",
"bond_info", "angle_info" };
class parser_error : public std::exception {
class control_parser_error : public std::exception {
std::string message;
public:
parser_error(const std::string &mesg) { message = mesg; }
explicit control_parser_error(const std::string &format, const std::string &keyword) {
message = fmt::format(format, keyword);
}
const char *what() const noexcept { return message.c_str(); }
};
@ -90,7 +92,7 @@ namespace ReaxFF {
auto keyword = values.next_string();
if (!values.has_next())
throw parser_error(fmt::format("No value(s) for control parameter: {}\n",keyword));
throw control_parser_error("No value(s) for control parameter: {}\n", keyword);
if (inactive_keywords.find(keyword) != inactive_keywords.end()) {
error->warning(FLERR,fmt::format("Ignoring inactive control "
@ -112,8 +114,7 @@ namespace ReaxFF {
error->warning(FLERR,"Support for writing native trajectories has "
"been removed after LAMMPS version 8 April 2021");
} else {
throw parser_error(fmt::format("Unknown parameter {} in "
"control file", keyword));
throw control_parser_error("Unknown parameter {} in control file", keyword);
}
}
} catch (LAMMPS_NS::EOFException &) {

View File

@ -43,10 +43,10 @@ using LAMMPS_NS::utils::uppercase;
namespace ReaxFF {
class parser_error : public std::exception {
class ffield_parser_error : public std::exception {
std::string message;
public:
parser_error(const std::string &mesg) { message = mesg; }
explicit ffield_parser_error(const std::string &mesg) { message = mesg; }
const char *what() const noexcept { return message.c_str(); }
};
@ -61,7 +61,7 @@ namespace ReaxFF {
// read and parse the force field only on rank 0
#define THROW_ERROR(txt) \
throw parser_error(fmt::format("{}:{}: {}",filename,lineno,txt))
throw ffield_parser_error(fmt::format("{}:{}: {}",filename,lineno,txt))
if (control->me == 0) {
FILE *fp = LAMMPS_NS::utils::open_potential(filename, lmp, nullptr);
@ -163,7 +163,7 @@ namespace ReaxFF {
// copy element symbol in uppercase and truncate stored element symbol if necessary
auto element = uppercase(values.next_string());
strncpy(sbp[i].name,element.c_str(),4);
strncpy(sbp[i].name,element.c_str(),3);
sbp[i].name[3] = '\0';
sbp[i].r_s = values.next_double();

View File

@ -309,6 +309,7 @@ void Info::command(int narg, char **arg)
#else // defined(LAMMPS_SMALLSMALL)
fputs("-DLAMMPS_SMALLSMALL\n",out);
#endif
if (has_gzip_support()) fmt::print(out,"\n{}\n",platform::compress_info());
int ncword, ncline = 0;
fputs("\nInstalled packages:\n\n",out);

View File

@ -1379,6 +1379,8 @@ void LAMMPS::print_config(FILE *fp)
sizeof(smallint)*8, sizeof(imageint)*8,
sizeof(tagint)*8, sizeof(bigint)*8);
if (Info::has_gzip_support()) fmt::print(fp,"\n{}\n",platform::compress_info());
fputs("\nInstalled packages:\n\n",fp);
for (int i = 0; nullptr != (pkg = installed_packages[i]); ++i) {
ncword = strlen(pkg);

View File

@ -418,6 +418,24 @@ std::string platform::mpi_info(int &major, int &minor)
return {version};
}
/* ----------------------------------------------------------------------
collect available compression tool info
------------------------------------------------------------------------- */
std::string platform::compress_info()
{
std::string buf = "Available compression formats:\n\n";
bool none_found = true;
for (const auto &cmpi : compress_styles) {
if (cmpi.style == ::compress_info::NONE) continue;
if (find_exe_path(cmpi.command).size()) {
none_found = false;
buf += fmt::format("Extension: .{:6} Command: {}\n", cmpi.extension, cmpi.command);
}
}
if (none_found) buf += "None\n";
return buf;
}
/* ----------------------------------------------------------------------
set environment variable
------------------------------------------------------------------------- */
@ -930,7 +948,7 @@ bool platform::file_is_readable(const std::string &path)
bool platform::has_compress_extension(const std::string &file)
{
return find_compress_type(file).style != compress_info::NONE;
return find_compress_type(file).style != ::compress_info::NONE;
}
/* ----------------------------------------------------------------------
@ -943,7 +961,7 @@ FILE *platform::compressed_read(const std::string &file)
#if defined(LAMMPS_GZIP)
auto compress = find_compress_type(file);
if (compress.style == compress_info::NONE) return nullptr;
if (compress.style == ::compress_info::NONE) return nullptr;
if (find_exe_path(compress.command).size())
// put quotes around file name so that they may contain blanks
@ -962,7 +980,7 @@ FILE *platform::compressed_write(const std::string &file)
#if defined(LAMMPS_GZIP)
auto compress = find_compress_type(file);
if (compress.style == compress_info::NONE) return nullptr;
if (compress.style == ::compress_info::NONE) return nullptr;
if (find_exe_path(compress.command).size())
// put quotes around file name so that they may contain blanks

View File

@ -109,6 +109,15 @@ namespace platform {
std::string mpi_info(int &major, int &minor);
/*! Return string with list of available compression types and executables
*
* This function tests which of the supported compression executables
* are available for reading or writing compressed files where supported.
*
* \return string with list of available compression tools */
std::string compress_info();
/*! Add variable to the environment
*
* \param vardef variable name or variable definition (NAME=value)

View File

@ -60,7 +60,7 @@ class TokenizerException : public std::exception {
*
* \param msg String with error message
* \param token String of the token/word that caused the error */
TokenizerException(const std::string &msg, const std::string &token);
explicit TokenizerException(const std::string &msg, const std::string &token);
~TokenizerException() noexcept {}
@ -74,7 +74,7 @@ class InvalidIntegerException : public TokenizerException {
/** Thrown during converting string to integer number
*
* \param token String of the token/word that caused the error */
InvalidIntegerException(const std::string &token) :
explicit InvalidIntegerException(const std::string &token) :
TokenizerException("Not a valid integer number", token)
{
}
@ -85,7 +85,7 @@ class InvalidFloatException : public TokenizerException {
/** Thrown during converting string to floating point number
*
* \param token String of the token/word that caused the error */
InvalidFloatException(const std::string &token) :
explicit InvalidFloatException(const std::string &token) :
TokenizerException("Not a valid floating-point number", token)
{
}

View File

@ -1,6 +1,6 @@
import sys,os,unittest
from lammps import lammps, LMP_VAR_ATOM, LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR
import sys,os,unittest,ctypes
from lammps import lammps, LMP_VAR_ATOM, LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, LAMMPS_DOUBLE_2D, LAMMPS_AUTODETECT
has_manybody=False
try:
@ -494,6 +494,43 @@ create_atoms 1 single &
self.assertEqual(self.lmp.extract_global("sublo_lambda"), [0.0, 0.0, 0.0])
self.assertEqual(self.lmp.extract_global("subhi_lambda"), [1.0, 1.0, 1.0])
def test_create_atoms(self):
self.lmp.command("boundary f p m")
self.lmp.command("region box block 0 10 0 10 0 10")
self.lmp.command("create_box 2 box")
# second atom is outside the box -> dropped
self.lmp.create_atoms(2, [1,2], [1,1], [1.0, 1.0, 3.0, 5.0, 8.0, 12.0])
self.assertEqual(self.lmp.get_natoms(),1)
# non-zero velocities
self.lmp.create_atoms(2, None, [2,2], [2.0, 2.0, 1.0, 3.0, 4.0, 6.0], v=[0.1, 0.2, 0.3, -0.1, -0.2, -0.3])
self.assertEqual(self.lmp.get_natoms(),3)
# first atom is dropped, extend shrinkwrapped box for second atom, third atoms is wrapped around PBC.
self.lmp.create_atoms(3, [5,8,10], [1,2,1], [-1.0, 1.0, 3.0, 5.0, 8.0, 12.0, 1.0, -1.0, 1.0], shrinkexceed=True)
self.assertEqual(self.lmp.get_natoms(),5)
# set image flags
self.lmp.create_atoms(1, None, [2], [5.0, 8.0, 1.0], image=[self.lmp.encode_image_flags(1,0,-1)])
self.assertEqual(self.lmp.get_natoms(),6)
tag = self.lmp.extract_atom("id")
typ = self.lmp.extract_atom("type")
pos = self.lmp.extract_atom("x",LAMMPS_DOUBLE_2D)
vel = self.lmp.extract_atom("v",LAMMPS_DOUBLE_2D)
img = self.lmp.extract_atom("image",LAMMPS_AUTODETECT)
# expected results: tag, type, x, v, image
result = [ [ 1, 1, [1.0, 1.0, 3.0], [ 0.0, 0.0, 0.0], [0, 0, 0]],\
[ 2, 2, [2.0, 2.0, 1.0], [ 0.1, 0.2, 0.3], [0, 0, 0]],\
[ 3, 2, [3.0, 4.0, 6.0], [-0.1, -0.2, -0.3], [0, 0, 0]],\
[ 8, 2, [5.0, 8.0, 12.0], [ 0.0, 0.0, 0.0], [0, 0, 0]],\
[10, 1, [1.0, 9.0, 1.0], [ 0.0, 0.0, 0.0], [0, 0, 0]],\
[11, 2, [5.0, 8.0, 1.0], [ 0.0, 0.0, 0.0], [1, 0, -1]] ]
for i in range(len(result)):
self.assertEqual(tag[i],result[i][0])
self.assertEqual(typ[i],result[i][1])
for j in range(3):
self.assertEqual(pos[i][0:3],result[i][2])
self.assertEqual(vel[i][0:3],result[i][3])
self.assertEqual(self.lmp.decode_image_flags(img[i]), result[i][4])
##############################
if __name__ == "__main__":
unittest.main()