diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 06297ca919..e0fca5bd9b 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -36,7 +36,11 @@ find_package(Git) # by default, install into $HOME/.local (not /usr/local), so that no root access (and sudo!!) is needed if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "Default install path" FORCE) + if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND (NOT CMAKE_CROSSCOMPILING)) + set(CMAKE_INSTALL_PREFIX "$ENV{USERPROFILE}/LAMMPS" CACHE PATH "Default install path" FORCE) + else() + set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "Default install path" FORCE) + endif() endif() # If enabled, no need to use LD_LIBRARY_PATH / DYLD_LIBRARY_PATH when installed @@ -90,6 +94,10 @@ endif() set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF CACHE BOOL "Use compiler extensions") +# ugly hack for MSVC which by default always reports an old C++ standard in the __cplusplus macro +if(MSVC) + add_compile_options(/Zc:__cplusplus) +endif() # export all symbols when building a .dll file on windows if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND BUILD_SHARED_LIBS) diff --git a/doc/lammps.1 b/doc/lammps.1 index 1483dffdfe..40d4295b7e 100644 --- a/doc/lammps.1 +++ b/doc/lammps.1 @@ -141,7 +141,7 @@ to the code that were used during the run. Available keywords for styles are "both", "none", "screen", or "log". Any other keyword will be considered a file name to write the detailed citation info to -instead of logfile or screen. Default is the "log" style where there +instead of logfile or screen. Default is the "log" style where there is a short summary in the screen output and detailed citations in BibTeX format in the logfile. The option "both" selects the detailed output for both, "none", the short output for both, and "screen" will @@ -234,7 +234,7 @@ the standard output. If is "none", (most) screen output will be suppressed. In multi-partition mode only some high-level all-partition information is written to the screen or "" file, the remainder is written in a -per-partition file "screen.N" or ".N" +per-partition file "screen.N" or ".N" with "N" being the respective partition number, and unless overridden by the \-pscreen flag (see above). .TP diff --git a/doc/src/Developer_utils.rst b/doc/src/Developer_utils.rst index e419520edd..54a21e5e44 100644 --- a/doc/src/Developer_utils.rst +++ b/doc/src/Developer_utils.rst @@ -206,6 +206,9 @@ Convenience functions Customized standard functions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. doxygenfunction:: binary_search + :project: progguide + .. doxygenfunction:: merge_sort :project: progguide diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index a89791a02e..a6e3578aef 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -508,11 +508,6 @@ class PyLammps(object): :py:attr:`PyLammps.last_run`. """ output = self.__getattr__('run')(*args, **kwargs) - - comm = self.lmp.get_mpi_comm() - if comm: - output = self.lmp.comm.bcast(output, root=0) - self.runs += get_thermo_data(output) return output @@ -643,7 +638,7 @@ class PyLammps(object): return [x.strip() for x in value.split('=')] def _parse_info_system(self, output): - lines = output[6:-2] + lines = output[5:-2] system = {} for line in lines: @@ -704,7 +699,7 @@ class PyLammps(object): return system def _parse_info_communication(self, output): - lines = output[6:-3] + lines = output[5:-3] comm = {} for line in lines: @@ -725,7 +720,7 @@ class PyLammps(object): return comm def _parse_element_list(self, output): - lines = output[6:-3] + lines = output[5:-3] elements = [] for line in lines: @@ -737,7 +732,7 @@ class PyLammps(object): return elements def _parse_groups(self, output): - lines = output[6:-3] + lines = output[5:-3] groups = [] group_pattern = re.compile(r"(?P.+) \((?P.+)\)") @@ -784,6 +779,10 @@ class PyLammps(object): self.command(cmd) output = capture.output + comm = self.lmp.get_mpi_comm() + if comm: + output = self.lmp.comm.bcast(output, root=0) + if 'verbose' in kwargs and kwargs['verbose']: print(output) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index e23dd11500..9d8674d0e8 100755 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -163,8 +163,8 @@ action fix_dpd_energy_kokkos.cpp fix_dpd_energy.cpp action fix_dpd_energy_kokkos.h fix_dpd_energy.h action fix_rx_kokkos.cpp fix_rx.cpp action fix_rx_kokkos.h fix_rx.h -action gridcomm_kokkos.cpp gridcomm.cpp -action gridcomm_kokkos.h gridcomm.h +action gridcomm_kokkos.cpp fft3d.h +action gridcomm_kokkos.h fft3d.h action improper_class2_kokkos.cpp improper_class2.cpp action improper_class2_kokkos.h improper_class2.h action improper_harmonic_kokkos.cpp improper_harmonic.cpp diff --git a/src/MC/fix_bond_create.cpp b/src/MC/fix_bond_create.cpp index 2a4ba5ad6c..9cd94834d0 100644 --- a/src/MC/fix_bond_create.cpp +++ b/src/MC/fix_bond_create.cpp @@ -51,6 +51,7 @@ FixBondCreate::FixBondCreate(LAMMPS *lmp, int narg, char **arg) : nevery = utils::inumeric(FLERR,arg[3],false,lmp); if (nevery <= 0) error->all(FLERR,"Illegal fix bond/create command"); + dynamic_group_allow = 1; force_reneighbor = 1; next_reneighbor = -1; vector_flag = 1; diff --git a/src/MISC/fix_ipi.cpp b/src/MISC/fix_ipi.cpp index 6fc3ec97b5..b56c5eebcb 100644 --- a/src/MISC/fix_ipi.cpp +++ b/src/MISC/fix_ipi.cpp @@ -47,13 +47,18 @@ using namespace FixConst; // socket interface #ifndef _WIN32 - #include #include #include #include #include #include +#else +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include #endif #define MSGLEN 12 diff --git a/src/balance.cpp b/src/balance.cpp index feb5eae708..c8d21f1ac6 100644 --- a/src/balance.cpp +++ b/src/balance.cpp @@ -1029,12 +1029,12 @@ void Balance::tally(int dim, int n, double *split) if (wtflag) { weight = fixstore->vstore; for (int i = 0; i < nlocal; i++) { - index = binary(x[i][dim],n,split); + index = utils::binary_search(x[i][dim],n,split); onecost[index] += weight[i]; } } else { for (int i = 0; i < nlocal; i++) { - index = binary(x[i][dim],n,split); + index = utils::binary_search(x[i][dim],n,split); onecost[index] += 1.0; } } @@ -1131,16 +1131,16 @@ double Balance::imbalance_splits() if (wtflag) { weight = fixstore->vstore; for (int i = 0; i < nlocal; i++) { - ix = binary(x[i][0],nx,xsplit); - iy = binary(x[i][1],ny,ysplit); - iz = binary(x[i][2],nz,zsplit); + ix = utils::binary_search(x[i][0],nx,xsplit); + iy = utils::binary_search(x[i][1],ny,ysplit); + iz = utils::binary_search(x[i][2],nz,zsplit); proccost[iz*nx*ny + iy*nx + ix] += weight[i]; } } else { for (int i = 0; i < nlocal; i++) { - ix = binary(x[i][0],nx,xsplit); - iy = binary(x[i][1],ny,ysplit); - iz = binary(x[i][2],nz,zsplit); + ix = utils::binary_search(x[i][0],nx,xsplit); + iy = utils::binary_search(x[i][1],ny,ysplit); + iz = utils::binary_search(x[i][2],nz,zsplit); proccost[iz*nx*ny + iy*nx + ix] += 1.0; } } @@ -1161,40 +1161,6 @@ double Balance::imbalance_splits() return imbalance; } -/* ---------------------------------------------------------------------- - binary search for where value falls in N-length vec - note that vec actually has N+1 values, but ignore last one - values in vec are monotonically increasing, but adjacent values can be ties - value may be outside range of vec limits - always return index from 0 to N-1 inclusive - return 0 if value < vec[0] - reutrn N-1 if value >= vec[N-1] - return index = 1 to N-2 inclusive if vec[index] <= value < vec[index+1] - note that for adjacent tie values, index of lower tie is not returned - since never satisfies 2nd condition that value < vec[index+1] -------------------------------------------------------------------------- */ - -int Balance::binary(double value, int n, double *vec) -{ - int lo = 0; - int hi = n-1; - - if (value < vec[lo]) return lo; - if (value >= vec[hi]) return hi; - - // insure vec[lo] <= value < vec[hi] at every iteration - // done when lo,hi are adjacent - - int index = (lo+hi)/2; - while (lo < hi-1) { - if (value < vec[index]) hi = index; - else if (value >= vec[index]) lo = index; - index = (lo+hi)/2; - } - - return index; -} - /* ---------------------------------------------------------------------- write dump snapshot of line segments in Pizza.py mdump mesh format write xy lines around each proc's sub-domain for 2d diff --git a/src/balance.h b/src/balance.h index 0f2df8c5ee..e427c8bd9b 100644 --- a/src/balance.h +++ b/src/balance.h @@ -84,7 +84,6 @@ class Balance : public Command { void shift_setup_static(char *); void tally(int, int, double *); int adjust(int, double *); - int binary(double, int, double *); #ifdef BALANCE_DEBUG void debug_shift_output(int, int, int, double *); #endif diff --git a/src/comm.cpp b/src/comm.cpp index 17175f9517..f79c48ace1 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -782,13 +782,13 @@ int Comm::coord2proc(double *x, int &igx, int &igy, int &igz) } else if (layout == Comm::LAYOUT_NONUNIFORM) { if (triclinic == 0) { - igx = binary((x[0]-boxlo[0])/prd[0],procgrid[0],xsplit); - igy = binary((x[1]-boxlo[1])/prd[1],procgrid[1],ysplit); - igz = binary((x[2]-boxlo[2])/prd[2],procgrid[2],zsplit); + igx = utils::binary_search((x[0]-boxlo[0])/prd[0],procgrid[0],xsplit); + igy = utils::binary_search((x[1]-boxlo[1])/prd[1],procgrid[1],ysplit); + igz = utils::binary_search((x[2]-boxlo[2])/prd[2],procgrid[2],zsplit); } else { - igx = binary(x[0],procgrid[0],xsplit); - igy = binary(x[1],procgrid[1],ysplit); - igz = binary(x[2],procgrid[2],zsplit); + igx = utils::binary_search(x[0],procgrid[0],xsplit); + igy = utils::binary_search(x[1],procgrid[1],ysplit); + igz = utils::binary_search(x[2],procgrid[2],zsplit); } } @@ -802,36 +802,6 @@ int Comm::coord2proc(double *x, int &igx, int &igy, int &igz) return grid2proc[igx][igy][igz]; } -/* ---------------------------------------------------------------------- - binary search for value in N-length ascending vec - value may be outside range of vec limits - always return index from 0 to N-1 inclusive - return 0 if value < vec[0] - reutrn N-1 if value >= vec[N-1] - return index = 1 to N-2 if vec[index] <= value < vec[index+1] -------------------------------------------------------------------------- */ - -int Comm::binary(double value, int n, double *vec) -{ - int lo = 0; - int hi = n-1; - - if (value < vec[lo]) return lo; - if (value >= vec[hi]) return hi; - - // insure vec[lo] <= value < vec[hi] at every iteration - // done when lo,hi are adjacent - - int index = (lo+hi)/2; - while (lo < hi-1) { - if (value < vec[index]) hi = index; - else if (value >= vec[index]) lo = index; - index = (lo+hi)/2; - } - - return index; -} - /* ---------------------------------------------------------------------- partition a global regular grid into one brick-shaped sub-grid per proc if grid point is inside my sub-domain I own it, diff --git a/src/comm.h b/src/comm.h index 817d1230a2..43a30675f3 100644 --- a/src/comm.h +++ b/src/comm.h @@ -98,7 +98,6 @@ class Comm : protected Pointers { virtual void forward_comm_array(int, double **) = 0; virtual int exchange_variable(int, double *, double *&) = 0; - int binary(double, int, double *); // map a point to a processor, based on current decomposition diff --git a/src/fix_store.cpp b/src/fix_store.cpp index e121cd8f08..c54e8b84be 100644 --- a/src/fix_store.cpp +++ b/src/fix_store.cpp @@ -64,7 +64,7 @@ vstore(nullptr), astore(nullptr), rbuf(nullptr) if (flavor == PERATOM) { restart_peratom = utils::inumeric(FLERR,arg[4],false,lmp); nvalues = utils::inumeric(FLERR,arg[5],false,lmp); - if (restart_peratom < 0 or restart_peratom > 1 || nvalues <= 0) + if ((restart_peratom < 0) || (restart_peratom > 1) || (nvalues <= 0)) error->all(FLERR,"Illegal fix store command"); vecflag = 0; if (nvalues == 1) vecflag = 1; diff --git a/src/info.cpp b/src/info.cpp index a936ed8bd3..c6bf2663f4 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -51,6 +51,9 @@ #include #ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif #define PSAPI_VERSION 1 #include #include diff --git a/src/lammps.cpp b/src/lammps.cpp index f01f4c8490..b00181452b 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -55,7 +55,9 @@ #include #include -#if !defined(_WIN32) +#if defined(_WIN32) +#include +#else #include // for isatty() #endif diff --git a/src/lmptype.h b/src/lmptype.h index 871bf5ff6c..f46956e7d2 100644 --- a/src/lmptype.h +++ b/src/lmptype.h @@ -288,12 +288,6 @@ union ubuf { #define _noopt #endif -// settings to enable LAMMPS to build under Windows - -#ifdef _WIN32 -#include "lmpwindows.h" -#endif - // suppress unused parameter warning #define LMP_UNUSED_PARAM(x) (void) (x) diff --git a/src/lmpwindows.h b/src/lmpwindows.h index f9812d3ec1..9568866eda 100644 --- a/src/lmpwindows.h +++ b/src/lmpwindows.h @@ -11,17 +11,8 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#include -#if !defined(__MINGW32__) -#include "erf.h" -#endif #include -#include #include -// LAMMPS uses usleep with 100 ms arguments, no microsecond precision needed -#if !defined(__MINGW32__) -#include "sleep.h" -#endif // some symbols have different names in Windows diff --git a/src/my_page.cpp b/src/my_page.cpp index efad82d3d6..b407e279a9 100644 --- a/src/my_page.cpp +++ b/src/my_page.cpp @@ -1,4 +1,3 @@ -// clang-format off /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -14,8 +13,6 @@ #include "my_page.h" -#include - #if defined(LMP_INTEL) && !defined(LAMMPS_MEMALIGN) && !defined(_WIN32) #define LAMMPS_MEMALIGN 64 #endif @@ -60,12 +57,12 @@ using namespace LAMMPS_NS; * Need to call init() before use to define allocation settings */ template -MyPage::MyPage() : ndatum(0), nchunk(0), pages(nullptr), page(nullptr), - npage(0), ipage(-1), index(-1), maxchunk(-1), - pagesize(-1), pagedelta(1), errorflag(0) {}; +MyPage::MyPage() : + ndatum(0), nchunk(0), pages(nullptr), page(nullptr), npage(0), ipage(-1), index(-1), + maxchunk(-1), pagesize(-1), pagedelta(1), errorflag(0){}; -template -MyPage::~MyPage() { +template MyPage::~MyPage() +{ deallocate(); } @@ -79,27 +76,26 @@ MyPage::~MyPage() { * \param user_pagedelta Number of pages to allocate with one malloc * \return 1 if there were invalid parameters, 2 if there was an allocation error or 0 if successful */ -template -int MyPage::init(int user_maxchunk, int user_pagesize, - int user_pagedelta) { - maxchunk = user_maxchunk; - pagesize = user_pagesize; - pagedelta = user_pagedelta; +template int MyPage::init(int user_maxchunk, int user_pagesize, int user_pagedelta) +{ + maxchunk = user_maxchunk; + pagesize = user_pagesize; + pagedelta = user_pagedelta; - if (maxchunk <= 0 || pagesize <= 0 || pagedelta <= 0) return 1; - if (maxchunk > pagesize) return 1; + if (maxchunk <= 0 || pagesize <= 0 || pagedelta <= 0) return 1; + if (maxchunk > pagesize) return 1; - // free storage if re-initialized + // free storage if re-initialized - deallocate(); + deallocate(); - // initial page allocation + // initial page allocation - allocate(); - if (errorflag) return 2; - reset(); - return 0; - } + allocate(); + if (errorflag) return 2; + reset(); + return 0; +} /** Pointer to location that can store N items. * @@ -110,8 +106,8 @@ int MyPage::init(int user_maxchunk, int user_pagesize, * \param n number of items for which storage is requested * \return memory location or null pointer, if error or allocation failed */ -template -T *MyPage::get(int n) { +template T *MyPage::get(int n) +{ if (n > maxchunk) { errorflag = 1; return nullptr; @@ -120,7 +116,7 @@ T *MyPage::get(int n) { nchunk++; // return pointer from current page - if (index+n <= pagesize) { + if (index + n <= pagesize) { int start = index; index += n; return &page[start]; @@ -137,11 +133,10 @@ T *MyPage::get(int n) { return &page[0]; } - /** Reset state of memory pool without freeing any memory */ -template -void MyPage::reset() { +template void MyPage::reset() +{ ndatum = nchunk = 0; index = ipage = 0; page = (pages != nullptr) ? pages[ipage] : nullptr; @@ -150,23 +145,22 @@ void MyPage::reset() { /* ---------------------------------------------------------------------- */ -template -void MyPage::allocate() { +template void MyPage::allocate() +{ npage += pagedelta; - pages = (T **) realloc(pages,npage*sizeof(T *)); + pages = (T **) realloc(pages, npage * sizeof(T *)); if (!pages) { errorflag = 2; return; } - for (int i = npage-pagedelta; i < npage; i++) { + for (int i = npage - pagedelta; i < npage; i++) { #if defined(LAMMPS_MEMALIGN) void *ptr; - if (posix_memalign(&ptr, LAMMPS_MEMALIGN, pagesize*sizeof(T))) - errorflag = 2; + if (posix_memalign(&ptr, LAMMPS_MEMALIGN, pagesize * sizeof(T))) errorflag = 2; pages[i] = (T *) ptr; #else - pages[i] = (T *) malloc(pagesize*sizeof(T)); + pages[i] = (T *) malloc(pagesize * sizeof(T)); if (!pages[i]) errorflag = 2; #endif } @@ -174,8 +168,8 @@ void MyPage::allocate() { /** Free all allocated pages of this class instance */ -template -void MyPage::deallocate() { +template void MyPage::deallocate() +{ reset(); for (int i = 0; i < npage; i++) free(pages[i]); free(pages); @@ -186,9 +180,9 @@ void MyPage::deallocate() { // explicit instantiations namespace LAMMPS_NS { - template class MyPage; - template class MyPage; - template class MyPage; - template class MyPage; - template class MyPage; -} +template class MyPage; +template class MyPage; +template class MyPage; +template class MyPage; +template class MyPage; +} // namespace LAMMPS_NS diff --git a/src/my_pool_chunk.cpp b/src/my_pool_chunk.cpp index 484a4b3fcf..74d2d037e0 100644 --- a/src/my_pool_chunk.cpp +++ b/src/my_pool_chunk.cpp @@ -1,4 +1,3 @@ -// clang-format off /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -50,7 +49,8 @@ using namespace LAMMPS_NS; template MyPoolChunk::MyPoolChunk(int user_minchunk, int user_maxchunk, int user_nbin, - int user_chunkperpage, int user_pagedelta) { + int user_chunkperpage, int user_pagedelta) +{ minchunk = user_minchunk; maxchunk = user_maxchunk; nbin = user_nbin; @@ -68,13 +68,13 @@ MyPoolChunk::MyPoolChunk(int user_minchunk, int user_maxchunk, int user_nbin, // insure nbin*binsize spans minchunk to maxchunk inclusive - binsize = (maxchunk-minchunk+1) / nbin; - if (minchunk + nbin*binsize <= maxchunk) binsize++; + binsize = (maxchunk - minchunk + 1) / nbin; + if (minchunk + nbin * binsize <= maxchunk) binsize++; freelist = nullptr; for (int ibin = 0; ibin < nbin; ibin++) { freehead[ibin] = -1; - chunksize[ibin] = minchunk + (ibin+1)*binsize - 1; + chunksize[ibin] = minchunk + (ibin + 1) * binsize - 1; if (chunksize[ibin] > maxchunk) chunksize[ibin] = maxchunk; } @@ -85,10 +85,10 @@ MyPoolChunk::MyPoolChunk(int user_minchunk, int user_maxchunk, int user_nbin, } /** Destroy class instance and free all allocated memory */ -template -MyPoolChunk::~MyPoolChunk() { - delete [] freehead; - delete [] chunksize; +template MyPoolChunk::~MyPoolChunk() +{ + delete[] freehead; + delete[] chunksize; if (npage) { free(freelist); for (int i = 0; i < npage; i++) free(pages[i]); @@ -102,9 +102,9 @@ MyPoolChunk::~MyPoolChunk() { * \param index Index of chunk in memory pool * \return Pointer to requested chunk of storage */ -template -T *MyPoolChunk::get(int &index) { - int ibin = nbin-1; +template T *MyPoolChunk::get(int &index) +{ + int ibin = nbin - 1; if (freehead[ibin] < 0) { allocate(ibin); if (errorflag) { @@ -116,10 +116,10 @@ T *MyPoolChunk::get(int &index) { ndatum += maxchunk; nchunk++; index = freehead[ibin]; - int ipage = index/chunkperpage; + int ipage = index / chunkperpage; int ientry = index % chunkperpage; freehead[ibin] = freelist[index]; - return &pages[ipage][ientry*chunksize[ibin]]; + return &pages[ipage][ientry * chunksize[ibin]]; } /** Return pointer/index of unused chunk of size N @@ -128,15 +128,15 @@ T *MyPoolChunk::get(int &index) { * \param index Index of chunk in memory pool * \return Pointer to requested chunk of storage */ -template -T *MyPoolChunk::get(int n, int &index) { +template T *MyPoolChunk::get(int n, int &index) +{ if (n < minchunk || n > maxchunk) { errorflag = 3; index = -1; return nullptr; } - int ibin = (n-minchunk) / binsize; + int ibin = (n - minchunk) / binsize; if (freehead[ibin] < 0) { allocate(ibin); if (errorflag) { @@ -148,35 +148,34 @@ T *MyPoolChunk::get(int n, int &index) { ndatum += n; nchunk++; index = freehead[ibin]; - int ipage = index/chunkperpage; + int ipage = index / chunkperpage; int ientry = index % chunkperpage; freehead[ibin] = freelist[index]; - return &pages[ipage][ientry*chunksize[ibin]]; + return &pages[ipage][ientry * chunksize[ibin]]; } /** Put indexed chunk back into memory pool via free list * * \param index Memory chunk index returned by call to get() */ -template -void MyPoolChunk::put(int index) { - if (index < 0) return; - int ipage = index/chunkperpage; - int ibin = whichbin[ipage]; - nchunk--; - ndatum -= chunksize[ibin]; - freelist[index] = freehead[ibin]; - freehead[ibin] = index; - } +template void MyPoolChunk::put(int index) +{ + if (index < 0) return; + int ipage = index / chunkperpage; + int ibin = whichbin[ipage]; + nchunk--; + ndatum -= chunksize[ibin]; + freelist[index] = freehead[ibin]; + freehead[ibin] = index; +} - -template -void MyPoolChunk::allocate(int ibin) { +template void MyPoolChunk::allocate(int ibin) +{ int oldpage = npage; npage += pagedelta; - freelist = (int *) realloc(freelist,sizeof(int)*npage*chunkperpage); - pages = (T **) realloc(pages,sizeof(T *)*npage); - whichbin = (int *) realloc(whichbin,sizeof(int)*npage); + freelist = (int *) realloc(freelist, sizeof(int) * npage * chunkperpage); + pages = (T **) realloc(pages, sizeof(T *) * npage); + whichbin = (int *) realloc(whichbin, sizeof(int) * npage); if (!freelist || !pages) { errorflag = 2; return; @@ -188,34 +187,32 @@ void MyPoolChunk::allocate(int ibin) { whichbin[i] = ibin; #if defined(LAMMPS_MEMALIGN) void *ptr; - if (posix_memalign(&ptr, LAMMPS_MEMALIGN, - sizeof(T)*chunkperpage*chunksize[ibin])) + if (posix_memalign(&ptr, LAMMPS_MEMALIGN, sizeof(T) * chunkperpage * chunksize[ibin])) errorflag = 2; pages[i] = (T *) ptr; #else - pages[i] = (T *) malloc(sizeof(T)*chunkperpage*chunksize[ibin]); + pages[i] = (T *) malloc(sizeof(T) * chunkperpage * chunksize[ibin]); if (!pages[i]) errorflag = 2; #endif } // reset free list for unused chunks on new pages - freehead[ibin] = oldpage*chunkperpage; - for (int i = freehead[ibin]; i < npage*chunkperpage; i++) freelist[i] = i+1; - freelist[npage*chunkperpage-1] = -1; + freehead[ibin] = oldpage * chunkperpage; + for (int i = freehead[ibin]; i < npage * chunkperpage; i++) freelist[i] = i + 1; + freelist[npage * chunkperpage - 1] = -1; } /** Return total size of allocated pages * * \return total storage used in bytes */ -template -double MyPoolChunk::size() const { - double bytes = (double)npage*chunkperpage*sizeof(int); - bytes += (double)npage*sizeof(T *); - bytes += (double)npage*sizeof(int); - for (int i=0; i < npage; ++i) - bytes += (double)chunkperpage*chunksize[i]*sizeof(T); +template double MyPoolChunk::size() const +{ + double bytes = (double) npage * chunkperpage * sizeof(int); + bytes += (double) npage * sizeof(T *); + bytes += (double) npage * sizeof(int); + for (int i = 0; i < npage; ++i) bytes += (double) chunkperpage * chunksize[i] * sizeof(T); return bytes; } @@ -223,6 +220,6 @@ double MyPoolChunk::size() const { // explicit instantiations namespace LAMMPS_NS { - template class MyPoolChunk; - template class MyPoolChunk; -} +template class MyPoolChunk; +template class MyPoolChunk; +} // namespace LAMMPS_NS diff --git a/src/neighbor.cpp b/src/neighbor.cpp index b7217926ca..6c25332257 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -365,10 +365,10 @@ void Neighbor::init() int icollection, jcollection; // If collections not yet defined, create default map using types - if (not custom_collection_flag) { + if (!custom_collection_flag) { ncollections = n; interval_collection_flag = 0; - if (not type2collection) + if (!type2collection) memory->create(type2collection,n+1,"neigh:type2collection"); for (i = 1; i <= n; i++) type2collection[i] = i-1; @@ -390,7 +390,7 @@ void Neighbor::init() for (j = 0; j < ncollections; j++) cutcollectionsq[i][j] = 0.0; - if (not interval_collection_flag) { + if (!interval_collection_flag) { finite_cut_flag = 0; for (i = 1; i <= n; i++){ icollection = type2collection[i]; @@ -419,7 +419,7 @@ void Neighbor::init() finite_cut_flag = 0; // Map types to collections - if (not type2collection) + if (!type2collection) memory->create(type2collection,n+1,"neigh:type2collection"); for (i = 1; i <= n; i++) @@ -2557,7 +2557,7 @@ void Neighbor::modify_params(int narg, char **arg) comm->ncollections_cutoff = 0; interval_collection_flag = 0; custom_collection_flag = 1; - if (not type2collection) + if (!type2collection) memory->create(type2collection,ntypes+1,"neigh:type2collection"); // Erase previous mapping diff --git a/src/text_file_reader.cpp b/src/text_file_reader.cpp index 926dedcf80..8fc57d9283 100644 --- a/src/text_file_reader.cpp +++ b/src/text_file_reader.cpp @@ -173,7 +173,7 @@ void TextFileReader::next_dvector(double *list, int n) } ValueTokenizer values(line); - while (values.has_next()) { list[i++] = values.next_double(); } + while (values.has_next() && i < n) { list[i++] = values.next_double(); } } } diff --git a/src/thermo.cpp b/src/thermo.cpp index 6e326e6891..eaf208c2eb 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -415,14 +415,14 @@ bigint Thermo::lost_check() error->all(FLERR,"Too many total atoms"); // print notification, if future warnings will be ignored - int maxwarn = error->get_maxwarn(); + bigint maxwarn = error->get_maxwarn(); if ((maxwarn > 0) && (warnbefore == 0) && (ntotal[1] > maxwarn)) { warnbefore = 1; if (comm->me == 0) error->message(FLERR,"WARNING: Too many warnings: {} vs {}. All " "future warnings will be suppressed",ntotal[1],maxwarn); } - error->set_allwarn(ntotal[1]); + error->set_allwarn(MIN(MAXSMALLINT,ntotal[1])); // no lost atoms, nothing else to do. if (ntotal[0] == atom->natoms) return ntotal[0]; diff --git a/src/timer.cpp b/src/timer.cpp index 79caab8b80..b01a7aa9d6 100644 --- a/src/timer.cpp +++ b/src/timer.cpp @@ -21,6 +21,9 @@ #include #ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif #include #include #else diff --git a/src/utils.cpp b/src/utils.cpp index 528908807c..17d544bffa 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -32,6 +32,21 @@ #include // for readlink #endif +#if defined(__APPLE__) +#include // for fcntl +#include +#endif + +#if defined(_WIN32) +// target Windows version is Windows 7 and later +#if defined(_WIN32_WINNT) +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT _WIN32_WINNT_WIN7 +#include +#include +#endif + /*! \file utils.cpp */ /* @@ -149,6 +164,9 @@ std::string utils::getsyserror() /** On Linux the folder /proc/self/fd holds symbolic links to the actual * pathnames associated with each open file descriptor of the current process. + * On macOS the same kind of information can be obtained using ``fcntl(fd,F_GETPATH,buf)``. + * On Windows we use ``GetFinalPathNameByHandleA()`` which is available with + * Windows Vista and later. * * This function is used to provide a filename with error messages in functions * where the filename is not passed as an argument, but the FILE * pointer. @@ -162,6 +180,20 @@ const char *utils::guesspath(char *buf, int len, FILE *fp) // get pathname from /proc or copy (unknown) if (readlink(fmt::format("/proc/self/fd/{}", fd).c_str(), buf, len - 1) <= 0) strncpy(buf, "(unknown)", len - 1); +#elif defined(__APPLE__) + int fd = fileno(fp); + char filepath[PATH_MAX]; + if (fcntl(fd, F_GETPATH, filepath) != -1) + strncpy(buf, filepath, len - 1); + else + strncpy(buf, "(unknown)", len - 1); +#elif defined(_WIN32) + char filepath[MAX_PATH]; + HANDLE h = (HANDLE) _get_osfhandle(_fileno(fp)); + if (GetFinalPathNameByHandleA(h, filepath, PATH_MAX, FILE_NAME_NORMALIZED) > 0) + strncpy(buf, filepath, len - 1); + else + strncpy(buf, "(unknown)", len - 1); #else strncpy(buf, "(unknown)", len - 1); #endif @@ -1284,6 +1316,30 @@ int utils::date2num(const std::string &date) return num; } +/* binary search in vector of ascending doubles */ +int utils::binary_search(const double needle, const int n, const double *haystack) +{ + int lo = 0; + int hi = n - 1; + + if (needle < haystack[lo]) return lo; + if (needle >= haystack[hi]) return hi; + + // insure haystack[lo] <= needle < haystack[hi] at every iteration + // done when lo,hi are adjacent + + int index = (lo + hi) / 2; + while (lo < hi - 1) { + if (needle < haystack[index]) + hi = index; + else if (needle >= haystack[index]) + lo = index; + index = (lo + hi) / 2; + } + + return index; +} + /* ---------------------------------------------------------------------- * Merge sort part 1: Loop over sublists doubling in size with each iteration. * Pre-sort small sublists with insertion sort for better overall performance. @@ -1412,26 +1468,26 @@ static int re_matchp(const char *text, re_t pattern, int *matchlen); #define MAX_CHAR_CLASS_LEN 40 /* Max length of character-class buffer in. */ enum { - UNUSED, - DOT, - BEGIN, - END, - QUESTIONMARK, - STAR, - PLUS, - CHAR, - CHAR_CLASS, - INV_CHAR_CLASS, - DIGIT, - NOT_DIGIT, - INTEGER, - NOT_INTEGER, - FLOAT, - NOT_FLOAT, - ALPHA, - NOT_ALPHA, - WHITESPACE, - NOT_WHITESPACE /*, BRANCH */ + RX_UNUSED, + RX_DOT, + RX_BEGIN, + RX_END, + RX_QUESTIONMARK, + RX_STAR, + RX_PLUS, + RX_CHAR, + RX_CHAR_CLASS, + RX_INV_CHAR_CLASS, + RX_DIGIT, + RX_NOT_DIGIT, + RX_INTEGER, + RX_NOT_INTEGER, + RX_FLOAT, + RX_NOT_FLOAT, + RX_ALPHA, + RX_NOT_ALPHA, + RX_WHITESPACE, + RX_NOT_WHITESPACE /*, BRANCH */ }; typedef struct regex_t { @@ -1483,7 +1539,7 @@ int re_matchp(const char *text, re_t pattern, int *matchlen) { *matchlen = 0; if (pattern != 0) { - if (pattern[0].type == BEGIN) { + if (pattern[0].type == RX_BEGIN) { return ((matchpattern(&pattern[1], text, matchlen)) ? 0 : -1); } else { int idx = -1; @@ -1518,22 +1574,22 @@ re_t re_compile(re_ctx_t context, const char *pattern) switch (c) { /* Meta-characters: */ case '^': { - re_compiled[j].type = BEGIN; + re_compiled[j].type = RX_BEGIN; } break; case '$': { - re_compiled[j].type = END; + re_compiled[j].type = RX_END; } break; case '.': { - re_compiled[j].type = DOT; + re_compiled[j].type = RX_DOT; } break; case '*': { - re_compiled[j].type = STAR; + re_compiled[j].type = RX_STAR; } break; case '+': { - re_compiled[j].type = PLUS; + re_compiled[j].type = RX_PLUS; } break; case '?': { - re_compiled[j].type = QUESTIONMARK; + re_compiled[j].type = RX_QUESTIONMARK; } break; /* Escaped character-classes (\s \w ...): */ @@ -1545,39 +1601,39 @@ re_t re_compile(re_ctx_t context, const char *pattern) switch (pattern[i]) { /* Meta-character: */ case 'd': { - re_compiled[j].type = DIGIT; + re_compiled[j].type = RX_DIGIT; } break; case 'D': { - re_compiled[j].type = NOT_DIGIT; + re_compiled[j].type = RX_NOT_DIGIT; } break; case 'i': { - re_compiled[j].type = INTEGER; + re_compiled[j].type = RX_INTEGER; } break; case 'I': { - re_compiled[j].type = NOT_INTEGER; + re_compiled[j].type = RX_NOT_INTEGER; } break; case 'f': { - re_compiled[j].type = FLOAT; + re_compiled[j].type = RX_FLOAT; } break; case 'F': { - re_compiled[j].type = NOT_FLOAT; + re_compiled[j].type = RX_NOT_FLOAT; } break; case 'w': { - re_compiled[j].type = ALPHA; + re_compiled[j].type = RX_ALPHA; } break; case 'W': { - re_compiled[j].type = NOT_ALPHA; + re_compiled[j].type = RX_NOT_ALPHA; } break; case 's': { - re_compiled[j].type = WHITESPACE; + re_compiled[j].type = RX_WHITESPACE; } break; case 'S': { - re_compiled[j].type = NOT_WHITESPACE; + re_compiled[j].type = RX_NOT_WHITESPACE; } break; /* Escaped character, e.g. '.' or '$' */ default: { - re_compiled[j].type = CHAR; + re_compiled[j].type = RX_CHAR; re_compiled[j].u.ch = pattern[i]; } break; } @@ -1592,14 +1648,14 @@ re_t re_compile(re_ctx_t context, const char *pattern) /* Look-ahead to determine if negated */ if (pattern[i + 1] == '^') { - re_compiled[j].type = INV_CHAR_CLASS; + re_compiled[j].type = RX_INV_CHAR_CLASS; i += 1; /* Increment i to avoid including '^' in the char-buffer */ if (pattern[i + 1] == 0) /* incomplete pattern, missing non-zero char after '^' */ { return 0; } } else { - re_compiled[j].type = CHAR_CLASS; + re_compiled[j].type = RX_CHAR_CLASS; } /* Copy characters inside [..] to buffer */ @@ -1628,7 +1684,7 @@ re_t re_compile(re_ctx_t context, const char *pattern) /* Other characters: */ default: { - re_compiled[j].type = CHAR; + re_compiled[j].type = RX_CHAR; re_compiled[j].u.ch = c; } break; } @@ -1639,8 +1695,8 @@ re_t re_compile(re_ctx_t context, const char *pattern) i += 1; j += 1; } - /* 'UNUSED' is a sentinel used to indicate end-of-pattern */ - re_compiled[j].type = UNUSED; + /* 'RX_UNUSED' is a sentinel used to indicate end-of-pattern */ + re_compiled[j].type = RX_UNUSED; return (re_t) re_compiled; } @@ -1753,31 +1809,31 @@ static int matchcharclass(char c, const char *str) static int matchone(regex_t p, char c) { switch (p.type) { - case DOT: + case RX_DOT: return matchdot(c); - case CHAR_CLASS: + case RX_CHAR_CLASS: return matchcharclass(c, (const char *) p.u.ccl); - case INV_CHAR_CLASS: + case RX_INV_CHAR_CLASS: return !matchcharclass(c, (const char *) p.u.ccl); - case DIGIT: + case RX_DIGIT: return matchdigit(c); - case NOT_DIGIT: + case RX_NOT_DIGIT: return !matchdigit(c); - case INTEGER: + case RX_INTEGER: return matchint(c); - case NOT_INTEGER: + case RX_NOT_INTEGER: return !matchint(c); - case FLOAT: + case RX_FLOAT: return matchfloat(c); - case NOT_FLOAT: + case RX_NOT_FLOAT: return !matchfloat(c); - case ALPHA: + case RX_ALPHA: return matchalphanum(c); - case NOT_ALPHA: + case RX_NOT_ALPHA: return !matchalphanum(c); - case WHITESPACE: + case RX_WHITESPACE: return matchwhitespace(c); - case NOT_WHITESPACE: + case RX_NOT_WHITESPACE: return !matchwhitespace(c); default: return (p.u.ch == c); @@ -1817,7 +1873,7 @@ static int matchplus(regex_t p, regex_t *pattern, const char *text, int *matchle static int matchquestion(regex_t p, regex_t *pattern, const char *text, int *matchlen) { - if (p.type == UNUSED) return 1; + if (p.type == RX_UNUSED) return 1; if (matchpattern(pattern, text, matchlen)) return 1; if (*text && matchone(p, *text++)) { if (matchpattern(pattern, text, matchlen)) { @@ -1833,13 +1889,13 @@ static int matchpattern(regex_t *pattern, const char *text, int *matchlen) { int pre = *matchlen; do { - if ((pattern[0].type == UNUSED) || (pattern[1].type == QUESTIONMARK)) { + if ((pattern[0].type == RX_UNUSED) || (pattern[1].type == RX_QUESTIONMARK)) { return matchquestion(pattern[0], &pattern[2], text, matchlen); - } else if (pattern[1].type == STAR) { + } else if (pattern[1].type == RX_STAR) { return matchstar(pattern[0], &pattern[2], text, matchlen); - } else if (pattern[1].type == PLUS) { + } else if (pattern[1].type == RX_PLUS) { return matchplus(pattern[0], &pattern[2], text, matchlen); - } else if ((pattern[0].type == END) && pattern[1].type == UNUSED) { + } else if ((pattern[0].type == RX_END) && pattern[1].type == RX_UNUSED) { return (text[0] == '\0'); } (*matchlen)++; diff --git a/src/utils.h b/src/utils.h index b761534d66..f53374144e 100644 --- a/src/utils.h +++ b/src/utils.h @@ -408,7 +408,7 @@ namespace utils { /*! Try to detect pathname from FILE pointer. * - * Currently only supported on Linux, otherwise will report "(unknown)". + * Currently supported on Linux, macOS, and Windows, otherwise will report "(unknown)". * * \param buf storage buffer for pathname. output will be truncated if not large enough * \param len size of storage buffer. output will be truncated to this length - 1 @@ -541,6 +541,23 @@ namespace utils { int date2num(const std::string &date); + /*! Binary search in a vector of ascending doubles of length N + * + * If the value is smaller than the smallest value in the vector, 0 is returned. + * If the value is larger or equal than the largest value in the vector, N-1 is returned. + * Otherwise the index that satisfies the condition + * + * haystack[index] <= value < haystack[index+1] + * + * is returned, i.e. a value from 1 to N-2. Note that if there are tied values in the + * haystack, always the larger index is returned as only that satisfied the condition. + * + * \param needle search value for which are are looking for the closest index + * \param n size of the haystack array + * \param haystack array with data in ascending order. + * \return index of value in the haystack array smaller or equal to needle */ + int binary_search(const double needle, const int n, const double *haystack); + /*! Custom merge sort implementation * * This function provides a custom upward hybrid merge sort diff --git a/tools/lammps-shell/lammps-shell.cpp b/tools/lammps-shell/lammps-shell.cpp index 699062059a..f77bd5442f 100644 --- a/tools/lammps-shell/lammps-shell.cpp +++ b/tools/lammps-shell/lammps-shell.cpp @@ -22,6 +22,7 @@ #if !defined(WIN32_LEAN_AND_MEAN) #define WIN32_LEAN_AND_MEAN #endif +#include #include #include #define chdir(x) _chdir(x) diff --git a/unittest/c-library/test_library_properties.cpp b/unittest/c-library/test_library_properties.cpp index cd405bfb93..57c0153c65 100644 --- a/unittest/c-library/test_library_properties.cpp +++ b/unittest/c-library/test_library_properties.cpp @@ -65,7 +65,7 @@ TEST_F(LibraryProperties, memory_usage) #if defined(__linux__) || defined(_WIN32) EXPECT_GE(meminfo[1], 0.0); #endif -#if !defined(__INTEL_LLVM_COMPILER) +#if (defined(__linux__) || defined(__APPLE__) || defined(_WIN32)) && !defined(__INTEL_LLVM_COMPILER) EXPECT_GT(meminfo[2], 0.0); #endif }; diff --git a/unittest/force-styles/CMakeLists.txt b/unittest/force-styles/CMakeLists.txt index fba632d3ec..75e95c3bf0 100644 --- a/unittest/force-styles/CMakeLists.txt +++ b/unittest/force-styles/CMakeLists.txt @@ -117,6 +117,9 @@ endforeach() # tester for timestepping fixes add_executable(test_fix_timestep test_fix_timestep.cpp) +if(NOT BUILD_SHARED_LIBS) + target_compile_definitions(test_fix_timestep PRIVATE USING_STATIC_LIBS=1) +endif() target_link_libraries(test_fix_timestep PRIVATE lammps style_tests) # tests for timestep related fixes (time integration, thermostat, force manipulation, constraints/restraints) diff --git a/unittest/force-styles/test_fix_timestep.cpp b/unittest/force-styles/test_fix_timestep.cpp index 362a632713..ac83ff9573 100644 --- a/unittest/force-styles/test_fix_timestep.cpp +++ b/unittest/force-styles/test_fix_timestep.cpp @@ -255,6 +255,9 @@ TEST(FixTimestep, plain) { if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); +#if defined(USING_STATIC_LIBS) + if (test_config.skip_tests.count("static")) GTEST_SKIP(); +#endif const char *args[] = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite"}; @@ -703,6 +706,9 @@ TEST(FixTimestep, omp) if (!LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP(); if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP(); if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP(); +#if defined(USING_STATIC_LIBS) + if (test_config.skip_tests.count("static")) GTEST_SKIP(); +#endif const char *args[] = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite", "-pk", "omp", "4", "-sf", "omp"}; diff --git a/unittest/force-styles/tests/atomic-pair-reaxff.yaml b/unittest/force-styles/tests/atomic-pair-reaxff.yaml index 2f706e58c6..ccb88d6ca4 100644 --- a/unittest/force-styles/tests/atomic-pair-reaxff.yaml +++ b/unittest/force-styles/tests/atomic-pair-reaxff.yaml @@ -1,7 +1,7 @@ --- lammps_version: 30 Jul 2021 date_generated: Mon Aug 23 20:32:03 2021 -epsilon: 2e-11 +epsilon: 2e-10 skip_tests: prerequisites: ! | pair reaxff diff --git a/unittest/force-styles/tests/atomic-pair-reaxff_lgvdw.yaml b/unittest/force-styles/tests/atomic-pair-reaxff_lgvdw.yaml index 5a50b0f7d3..b4afe5942a 100644 --- a/unittest/force-styles/tests/atomic-pair-reaxff_lgvdw.yaml +++ b/unittest/force-styles/tests/atomic-pair-reaxff_lgvdw.yaml @@ -1,7 +1,7 @@ --- lammps_version: 30 Jul 2021 date_generated: Mon Aug 23 20:32:03 2021 -epsilon: 3e-12 +epsilon: 4e-12 skip_tests: prerequisites: ! | pair reaxff diff --git a/unittest/force-styles/tests/fix-timestep-python_move_nve.yaml b/unittest/force-styles/tests/fix-timestep-python_move_nve.yaml index 9c78dbe416..04bd81670b 100644 --- a/unittest/force-styles/tests/fix-timestep-python_move_nve.yaml +++ b/unittest/force-styles/tests/fix-timestep-python_move_nve.yaml @@ -1,6 +1,7 @@ --- lammps_version: 10 Mar 2021 -date_generated: Wed Mar 24 18:57:26 202 +date_generated: Wed Mar 24 18:57:26 2021 +skip_tests: static epsilon: 9e-12 prerequisites: ! | atom full diff --git a/unittest/force-styles/tests/manybody-pair-drip.yaml b/unittest/force-styles/tests/manybody-pair-drip.yaml index 8fc2bb892b..f36436183a 100644 --- a/unittest/force-styles/tests/manybody-pair-drip.yaml +++ b/unittest/force-styles/tests/manybody-pair-drip.yaml @@ -1,7 +1,7 @@ --- lammps_version: 30 Jul 2021 date_generated: Tue Aug 24 15:36:39 2021 -epsilon: 2e-13 +epsilon: 7.5e-11 skip_tests: single prerequisites: ! | pair drip diff --git a/unittest/force-styles/tests/manybody-pair-drip_real.yaml b/unittest/force-styles/tests/manybody-pair-drip_real.yaml index bec2fb5f7b..78a9d0e6a3 100644 --- a/unittest/force-styles/tests/manybody-pair-drip_real.yaml +++ b/unittest/force-styles/tests/manybody-pair-drip_real.yaml @@ -1,7 +1,7 @@ --- lammps_version: 30 Jul 2021 date_generated: Tue Aug 24 15:36:41 2021 -epsilon: 5e-13 +epsilon: 2e-10 skip_tests: single prerequisites: ! | pair drip diff --git a/unittest/force-styles/tests/manybody-pair-lebedeva_z.yaml b/unittest/force-styles/tests/manybody-pair-lebedeva_z.yaml index b2792314db..5caeee3dca 100644 --- a/unittest/force-styles/tests/manybody-pair-lebedeva_z.yaml +++ b/unittest/force-styles/tests/manybody-pair-lebedeva_z.yaml @@ -1,7 +1,7 @@ --- lammps_version: 30 Jul 2021 date_generated: Wed Aug 25 07:37:07 2021 -epsilon: 1e-13 +epsilon: 2e-12 skip_tests: single prerequisites: ! | pair lebedeva/z diff --git a/unittest/python/CMakeLists.txt b/unittest/python/CMakeLists.txt index 1886d84537..5d0aad2f54 100644 --- a/unittest/python/CMakeLists.txt +++ b/unittest/python/CMakeLists.txt @@ -26,7 +26,7 @@ target_compile_definitions(test_python_package PRIVATE -DTEST_INPUT_FOLDER=${TES # this requires CMake 3.12. don't care to add backward compatibility for this. if(Python3_Development_FOUND) target_compile_definitions(test_python_package PRIVATE -DTEST_HAVE_PYTHON_DEVELOPMENT=1) - target_link_libraries(test_python_package PRIVATE Python::Python) + target_link_libraries(test_python_package PRIVATE Python3::Python) endif() add_test(NAME PythonPackage COMMAND test_python_package WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(PythonPackage PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}:${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH};PYTHONUNBUFFERED=1") diff --git a/unittest/python/python-pylammps.py b/unittest/python/python-pylammps.py index f703d206fa..6294972ab4 100644 --- a/unittest/python/python-pylammps.py +++ b/unittest/python/python-pylammps.py @@ -84,5 +84,40 @@ class PythonPyLammps(unittest.TestCase): self.assertEqual(len(self.pylmp.last_run.thermo.TotEng), 2) self.assertEqual(len(self.pylmp.last_run.thermo.Press), 2) + def test_info_queries(self): + self.pylmp.lattice("fcc", 0.8442), + self.pylmp.region("box block", 0, 4, 0, 4, 0, 4) + self.pylmp.create_box(1, "box") + self.pylmp.variable("a equal 10.0") + self.pylmp.variable("b string value") + self.assertEqual(self.pylmp.variables['a'].value, 10.0) + self.assertEqual(self.pylmp.variables['b'].value, 'value') + self.assertEqual(len(self.pylmp.variables),2) + self.assertEqual(self.pylmp.system.units,'lj') + self.assertEqual(self.pylmp.system.atom_style,'atomic') + self.assertEqual(self.pylmp.system.ntypes,1) + self.assertEqual(self.pylmp.system.natoms,0) + self.assertEqual(self.pylmp.communication.comm_style,'brick') + self.assertEqual(self.pylmp.communication.comm_layout,'uniform') + self.assertEqual(self.pylmp.communication.nprocs,1) + self.assertEqual(len(self.pylmp.computes),3) + self.assertEqual(self.pylmp.computes[0]['name'], 'thermo_temp') + self.assertEqual(self.pylmp.computes[0]['style'], 'temp') + self.assertEqual(self.pylmp.computes[0]['group'], 'all') + self.assertEqual(self.pylmp.computes[1]['name'], 'thermo_press') + self.assertEqual(self.pylmp.computes[1]['style'], 'pressure') + self.assertEqual(self.pylmp.computes[1]['group'], 'all') + self.assertEqual(self.pylmp.computes[2]['name'], 'thermo_pe') + self.assertEqual(self.pylmp.computes[2]['style'], 'pe') + self.assertEqual(self.pylmp.computes[2]['group'], 'all') + self.assertEqual(len(self.pylmp.dumps),0) + self.pylmp.fix('one','all','nve') + self.assertEqual(len(self.pylmp.fixes),1) + self.assertEqual(self.pylmp.fixes[0]['name'], 'one') + self.assertEqual(self.pylmp.fixes[0]['style'], 'nve') + self.assertEqual(self.pylmp.fixes[0]['group'], 'all') + self.pylmp.group('none','empty') + self.assertEqual(len(self.pylmp.groups),2) + if __name__ == "__main__": unittest.main() diff --git a/unittest/utils/test_utils.cpp b/unittest/utils/test_utils.cpp index 8c2845e817..5fb45cdf77 100644 --- a/unittest/utils/test_utils.cpp +++ b/unittest/utils/test_utils.cpp @@ -722,7 +722,7 @@ TEST(Utils, guesspath) { char buf[256]; FILE *fp = fopen("test_guesspath.txt", "w"); -#if defined(__linux__) +#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32) const char *path = utils::guesspath(buf, sizeof(buf), fp); ASSERT_THAT(path, EndsWith("test_guesspath.txt")); #else @@ -875,6 +875,24 @@ TEST(Utils, date2num) ASSERT_EQ(utils::date2num("31December100"), 1001231); } +TEST(Utils, binary_search) +{ + double data[] = {-2.0, -1.8, -1.0, -1.0, -1.0, -0.5, -0.2, 0.0, 0.1, 0.1, + 0.2, 0.3, 0.5, 0.5, 0.6, 0.7, 1.0, 1.2, 1.5, 2.0}; + const int n = sizeof(data) / sizeof(double); + ASSERT_EQ(utils::binary_search(-5.0, n, data), 0); + ASSERT_EQ(utils::binary_search(-2.0, n, data), 0); + ASSERT_EQ(utils::binary_search(-1.9, n, data), 0); + ASSERT_EQ(utils::binary_search(-1.0, n, data), 4); + ASSERT_EQ(utils::binary_search(0.0, n, data), 7); + ASSERT_EQ(utils::binary_search(0.1, n, data), 9); + ASSERT_EQ(utils::binary_search(0.4, n, data), 11); + ASSERT_EQ(utils::binary_search(1.1, n, data), 16); + ASSERT_EQ(utils::binary_search(1.5, n, data), 18); + ASSERT_EQ(utils::binary_search(2.0, n, data), 19); + ASSERT_EQ(utils::binary_search(2.5, n, data), 19); +} + static int compare(int a, int b, void *) { if (a < b)