Merge branch 'master' into kk_gridcomm
This commit is contained in:
@ -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)
|
||||
|
||||
@ -206,6 +206,9 @@ Convenience functions
|
||||
Customized standard functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. doxygenfunction:: binary_search
|
||||
:project: progguide
|
||||
|
||||
.. doxygenfunction:: merge_sort
|
||||
:project: progguide
|
||||
|
||||
|
||||
@ -47,13 +47,18 @@ using namespace FixConst;
|
||||
|
||||
// socket interface
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#include <netdb.h>
|
||||
#else
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define MSGLEN 12
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
42
src/comm.cpp
42
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,
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -51,6 +51,9 @@
|
||||
#include <map>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#define PSAPI_VERSION 1
|
||||
#include <windows.h>
|
||||
#include <cstdint>
|
||||
|
||||
@ -55,7 +55,9 @@
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#if defined(_WIN32)
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h> // for isatty()
|
||||
#endif
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -11,17 +11,8 @@
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include <ciso646>
|
||||
#if !defined(__MINGW32__)
|
||||
#include "erf.h"
|
||||
#endif
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <direct.h>
|
||||
// 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
|
||||
|
||||
|
||||
@ -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 <cstdlib>
|
||||
|
||||
#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 <class T>
|
||||
MyPage<T>::MyPage() : ndatum(0), nchunk(0), pages(nullptr), page(nullptr),
|
||||
npage(0), ipage(-1), index(-1), maxchunk(-1),
|
||||
pagesize(-1), pagedelta(1), errorflag(0) {};
|
||||
MyPage<T>::MyPage() :
|
||||
ndatum(0), nchunk(0), pages(nullptr), page(nullptr), npage(0), ipage(-1), index(-1),
|
||||
maxchunk(-1), pagesize(-1), pagedelta(1), errorflag(0){};
|
||||
|
||||
template <class T>
|
||||
MyPage<T>::~MyPage() {
|
||||
template <class T> MyPage<T>::~MyPage()
|
||||
{
|
||||
deallocate();
|
||||
}
|
||||
|
||||
@ -79,27 +76,26 @@ MyPage<T>::~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<class T>
|
||||
int MyPage<T>::init(int user_maxchunk, int user_pagesize,
|
||||
int user_pagedelta) {
|
||||
maxchunk = user_maxchunk;
|
||||
pagesize = user_pagesize;
|
||||
pagedelta = user_pagedelta;
|
||||
template <class T> int MyPage<T>::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<T>::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 <class T>
|
||||
T *MyPage<T>::get(int n) {
|
||||
template <class T> T *MyPage<T>::get(int n)
|
||||
{
|
||||
if (n > maxchunk) {
|
||||
errorflag = 1;
|
||||
return nullptr;
|
||||
@ -120,7 +116,7 @@ T *MyPage<T>::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<T>::get(int n) {
|
||||
return &page[0];
|
||||
}
|
||||
|
||||
|
||||
/** Reset state of memory pool without freeing any memory */
|
||||
|
||||
template <class T>
|
||||
void MyPage<T>::reset() {
|
||||
template <class T> void MyPage<T>::reset()
|
||||
{
|
||||
ndatum = nchunk = 0;
|
||||
index = ipage = 0;
|
||||
page = (pages != nullptr) ? pages[ipage] : nullptr;
|
||||
@ -150,23 +145,22 @@ void MyPage<T>::reset() {
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
template <class T>
|
||||
void MyPage<T>::allocate() {
|
||||
template <class T> void MyPage<T>::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<T>::allocate() {
|
||||
|
||||
/** Free all allocated pages of this class instance */
|
||||
|
||||
template <class T>
|
||||
void MyPage<T>::deallocate() {
|
||||
template <class T> void MyPage<T>::deallocate()
|
||||
{
|
||||
reset();
|
||||
for (int i = 0; i < npage; i++) free(pages[i]);
|
||||
free(pages);
|
||||
@ -186,9 +180,9 @@ void MyPage<T>::deallocate() {
|
||||
// explicit instantiations
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
template class MyPage<int>;
|
||||
template class MyPage<long>;
|
||||
template class MyPage<long long>;
|
||||
template class MyPage<double>;
|
||||
template class MyPage<HyperOneCoeff>;
|
||||
}
|
||||
template class MyPage<int>;
|
||||
template class MyPage<long>;
|
||||
template class MyPage<long long>;
|
||||
template class MyPage<double>;
|
||||
template class MyPage<HyperOneCoeff>;
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
@ -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 <class T>
|
||||
MyPoolChunk<T>::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<T>::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<T>::MyPoolChunk(int user_minchunk, int user_maxchunk, int user_nbin,
|
||||
}
|
||||
|
||||
/** Destroy class instance and free all allocated memory */
|
||||
template <class T>
|
||||
MyPoolChunk<T>::~MyPoolChunk() {
|
||||
delete [] freehead;
|
||||
delete [] chunksize;
|
||||
template <class T> MyPoolChunk<T>::~MyPoolChunk()
|
||||
{
|
||||
delete[] freehead;
|
||||
delete[] chunksize;
|
||||
if (npage) {
|
||||
free(freelist);
|
||||
for (int i = 0; i < npage; i++) free(pages[i]);
|
||||
@ -102,9 +102,9 @@ MyPoolChunk<T>::~MyPoolChunk() {
|
||||
* \param index Index of chunk in memory pool
|
||||
* \return Pointer to requested chunk of storage */
|
||||
|
||||
template <class T>
|
||||
T *MyPoolChunk<T>::get(int &index) {
|
||||
int ibin = nbin-1;
|
||||
template <class T> T *MyPoolChunk<T>::get(int &index)
|
||||
{
|
||||
int ibin = nbin - 1;
|
||||
if (freehead[ibin] < 0) {
|
||||
allocate(ibin);
|
||||
if (errorflag) {
|
||||
@ -116,10 +116,10 @@ T *MyPoolChunk<T>::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<T>::get(int &index) {
|
||||
* \param index Index of chunk in memory pool
|
||||
* \return Pointer to requested chunk of storage */
|
||||
|
||||
template <class T>
|
||||
T *MyPoolChunk<T>::get(int n, int &index) {
|
||||
template <class T> T *MyPoolChunk<T>::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<T>::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 <class T>
|
||||
void MyPoolChunk<T>::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 <class T> void MyPoolChunk<T>::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 <class T>
|
||||
void MyPoolChunk<T>::allocate(int ibin) {
|
||||
template <class T> void MyPoolChunk<T>::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<T>::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 <class T>
|
||||
double MyPoolChunk<T>::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 <class T> double MyPoolChunk<T>::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<T>::size() const {
|
||||
// explicit instantiations
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
template class MyPoolChunk<int>;
|
||||
template class MyPoolChunk<double>;
|
||||
}
|
||||
template class MyPoolChunk<int>;
|
||||
template class MyPoolChunk<double>;
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -21,6 +21,9 @@
|
||||
#include <cstring>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <cstdint>
|
||||
#else
|
||||
|
||||
178
src/utils.cpp
178
src/utils.cpp
@ -32,6 +32,21 @@
|
||||
#include <unistd.h> // for readlink
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <fcntl.h> // for fcntl
|
||||
#include <sys/syslimits.h>
|
||||
#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 <io.h>
|
||||
#include <windows.h>
|
||||
#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)++;
|
||||
|
||||
19
src/utils.h
19
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
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#define chdir(x) _chdir(x)
|
||||
|
||||
@ -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
|
||||
};
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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"};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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)
|
||||
|
||||
Reference in New Issue
Block a user