forked from lijiext/lammps
Merge branch 'master' into collected-small-changes
This commit is contained in:
commit
0b60650c1b
|
@ -101,6 +101,9 @@ and parsing files or arguments.
|
|||
.. doxygenfunction:: split_words
|
||||
:project: progguide
|
||||
|
||||
.. doxygenfunction:: split_lines
|
||||
:project: progguide
|
||||
|
||||
.. doxygenfunction:: strmatch
|
||||
:project: progguide
|
||||
|
||||
|
|
|
@ -740,6 +740,7 @@ void Neighbor::build_nbor_list(double **x, const int inum, const int host_inum,
|
|||
|
||||
// If binning on GPU, do this now
|
||||
if (_gpu_nbor==1) {
|
||||
mn = _max_nbors;
|
||||
const numtyp i_cell_size=static_cast<numtyp>(1.0/_cell_size);
|
||||
const int neigh_block=_block_cell_id;
|
||||
const int GX=(int)ceil((float)nall/neigh_block);
|
||||
|
|
|
@ -15,7 +15,7 @@ from .pylammps import *
|
|||
|
||||
# convert module string version to numeric version
|
||||
def get_version_number():
|
||||
from datetime import datetime
|
||||
import time
|
||||
from sys import version_info
|
||||
vstring = None
|
||||
if version_info.major == 3 and version_info.minor >= 8:
|
||||
|
@ -32,7 +32,7 @@ def get_version_number():
|
|||
if not vstring:
|
||||
return 0
|
||||
|
||||
d = datetime.strptime(vstring, "%d%b%Y")
|
||||
return d.year*10000 + d.month*100 + d.day
|
||||
t = time.strptime(vstring, "%d%b%Y")
|
||||
return t.tm_year*10000 + t.tm_mon*100 + t.tm_mday
|
||||
|
||||
__version__ = get_version_number()
|
||||
|
|
|
@ -729,12 +729,11 @@ class lammps(object):
|
|||
def extract_global(self, name, dtype=LAMMPS_AUTODETECT):
|
||||
"""Query LAMMPS about global settings of different types.
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_extract_global`
|
||||
function of the C-library interface. Unlike the C function
|
||||
this method returns the value and not a pointer and thus can
|
||||
only return the first value for keywords representing a list
|
||||
of values. The :cpp:func:`lammps_extract_global` documentation
|
||||
includes a list of the supported keywords and their data types.
|
||||
This is a wrapper around the :cpp:func:`lammps_extract_global` function
|
||||
of the C-library interface. Since there are no pointers in Python, this
|
||||
method will - unlike the C function - return the value or a list of
|
||||
values. The :cpp:func:`lammps_extract_global` documentation includes a
|
||||
list of the supported keywords and their data types.
|
||||
Since Python needs to know the data type to be able to interpret
|
||||
the result, by default, this function will try to auto-detect the data type
|
||||
by asking the library. You can also force a specific data type. For that
|
||||
|
@ -746,12 +745,23 @@ class lammps(object):
|
|||
:type name: string
|
||||
:param dtype: data type of the returned data (see :ref:`py_datatype_constants`)
|
||||
:type dtype: int, optional
|
||||
:return: value of the property or None
|
||||
:rtype: int, float, or NoneType
|
||||
:return: value of the property or list of values or None
|
||||
:rtype: int, float, list, or NoneType
|
||||
"""
|
||||
|
||||
if dtype == LAMMPS_AUTODETECT:
|
||||
dtype = self.extract_global_datatype(name)
|
||||
|
||||
# set length of vector for items that are not a scalar
|
||||
vec_dict = { 'boxlo':3, 'boxhi':3, 'sublo':3, 'subhi':3,
|
||||
'sublo_lambda':3, 'subhi_lambda':3, 'periodicity':3 }
|
||||
if name in vec_dict:
|
||||
veclen = vec_dict[name]
|
||||
elif name == 'respa_dt':
|
||||
veclen = self.extract_global('respa_levels',LAMMPS_INT)
|
||||
else:
|
||||
veclen = 1
|
||||
|
||||
if name: name = name.encode()
|
||||
else: return None
|
||||
|
||||
|
@ -766,14 +776,19 @@ class lammps(object):
|
|||
target_type = float
|
||||
elif dtype == LAMMPS_STRING:
|
||||
self.lib.lammps_extract_global.restype = c_char_p
|
||||
target_type = lambda x: str(x, 'ascii')
|
||||
|
||||
ptr = self.lib.lammps_extract_global(self.lmp, name)
|
||||
if ptr:
|
||||
return target_type(ptr[0])
|
||||
if dtype == LAMMPS_STRING:
|
||||
return ptr.decode('utf-8')
|
||||
if veclen > 1:
|
||||
result = []
|
||||
for i in range(0,veclen):
|
||||
result.append(target_type(ptr[i]))
|
||||
return result
|
||||
else: return target_type(ptr[0])
|
||||
return None
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# extract per-atom info datatype
|
||||
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing authors: Axel Kohlmeyer (Temple U),
|
||||
Ryan S. Elliott (UMN)
|
||||
Ellad B. Tadmor (UMN)
|
||||
Ronald Miller (Carleton U)
|
||||
Yaser Afshar (UMN)
|
||||
Contributing authors: Axel Kohlmeyer (Temple U),
|
||||
Ryan S. Elliott (UMN),
|
||||
Ellad B. Tadmor (UMN),
|
||||
Ronald Miller (Carleton U),
|
||||
Yaser Afshar (UMN)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
@ -65,6 +65,7 @@
|
|||
#include "error.h"
|
||||
#include "fix_store_kim.h"
|
||||
#include "input.h"
|
||||
#include "variable.h"
|
||||
#include "modify.h"
|
||||
#include "update.h"
|
||||
|
||||
|
@ -129,6 +130,7 @@ void KimInteractions::do_setup(int narg, char **arg)
|
|||
"=======\n");
|
||||
|
||||
if (simulatorModel) {
|
||||
auto first_visit = input->variable->find("kim_update");
|
||||
if (!fixed_types) {
|
||||
std::string atom_type_sym_list =
|
||||
fmt::format("{}", fmt::join(arg, arg + narg, " "));
|
||||
|
@ -198,15 +200,17 @@ void KimInteractions::do_setup(int narg, char **arg)
|
|||
|
||||
const std::string sim_field_str(sim_field);
|
||||
if (sim_field_str == "model-defn") {
|
||||
if (first_visit < 0) input->one("variable kim_update equal 0");
|
||||
else input->one("variable kim_update equal 1");
|
||||
if (domain->periodicity[0] &&
|
||||
domain->periodicity[1] &&
|
||||
domain->periodicity[2])
|
||||
input->one("variable kim_periodic equal 1");
|
||||
else if (domain->periodicity[0] &&
|
||||
domain->periodicity[1] &&
|
||||
else if (!domain->periodicity[0] &&
|
||||
!domain->periodicity[1] &&
|
||||
!domain->periodicity[2])
|
||||
input->one("variable kim_periodic equal 2");
|
||||
else input->one("variable kim_periodic equal 0");
|
||||
input->one("variable kim_periodic equal 0");
|
||||
else input->one("variable kim_periodic equal 2");
|
||||
|
||||
// KIM Simulator Model has a Model definition
|
||||
no_model_definition = false;
|
||||
|
@ -241,6 +245,7 @@ void KimInteractions::do_setup(int narg, char **arg)
|
|||
|
||||
} else {
|
||||
|
||||
|
||||
// not a simulator model. issue pair_style and pair_coeff commands.
|
||||
|
||||
if (fixed_types)
|
||||
|
|
|
@ -55,6 +55,16 @@ PythonImpl::PythonImpl(LAMMPS *lmp) : Pointers(lmp)
|
|||
|
||||
nfunc = 0;
|
||||
pfuncs = nullptr;
|
||||
|
||||
// check for PYTHONUNBUFFERED environment variable
|
||||
const char * PYTHONUNBUFFERED = getenv("PYTHONUNBUFFERED");
|
||||
|
||||
if (PYTHONUNBUFFERED != nullptr && strcmp(PYTHONUNBUFFERED, "1") == 0) {
|
||||
// Python Global configuration variable
|
||||
// Force the stdout and stderr streams to be unbuffered.
|
||||
Py_UnbufferedStdioFlag = 1;
|
||||
}
|
||||
|
||||
// one-time initialization of Python interpreter
|
||||
// pyMain stores pointer to main module
|
||||
external_interpreter = Py_IsInitialized();
|
||||
|
@ -496,6 +506,7 @@ int PythonImpl::create_entry(char *name)
|
|||
"cannot be used unless output is a string");
|
||||
pfuncs[ifunc].length_longstr = length_longstr;
|
||||
pfuncs[ifunc].longstr = new char[length_longstr+1];
|
||||
pfuncs[ifunc].longstr[length_longstr] = '\0';
|
||||
}
|
||||
|
||||
if (strstr(ostr,"v_") != ostr) error->all(FLERR,"Invalid python command");
|
||||
|
|
|
@ -551,7 +551,7 @@ void PairOxdna2Coaxstk::coeff(int narg, char **arg)
|
|||
{
|
||||
int count;
|
||||
|
||||
if (narg != 21) error->all(FLERR,"Incorrect args for pair coefficients in oxdna/coaxstk");
|
||||
if (narg != 21) error->all(FLERR,"Incorrect args for pair coefficients in oxdna2/coaxstk");
|
||||
if (!allocated) allocate();
|
||||
|
||||
int ilo,ihi,jlo,jhi;
|
||||
|
@ -673,7 +673,7 @@ void PairOxdna2Coaxstk::coeff(int narg, char **arg)
|
|||
}
|
||||
}
|
||||
|
||||
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients in oxdna/coaxstk");
|
||||
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients in oxdna2/coaxstk");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -273,7 +273,7 @@ void PairOxdna2Dh::coeff(int narg, char **arg)
|
|||
{
|
||||
int count;
|
||||
|
||||
if (narg != 5) error->all(FLERR,"Incorrect args for pair coefficients in oxdna/dh");
|
||||
if (narg != 5) error->all(FLERR,"Incorrect args for pair coefficients in oxdna2/dh");
|
||||
if (!allocated) allocate();
|
||||
|
||||
int ilo,ihi,jlo,jhi;
|
||||
|
@ -356,7 +356,7 @@ void PairOxdna2Dh::coeff(int narg, char **arg)
|
|||
}
|
||||
}
|
||||
|
||||
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients in oxdna/dh");
|
||||
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients in oxdna2/dh");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
|
|
@ -1022,7 +1022,7 @@ void PairOxrna2Stk::coeff(int narg, char **arg)
|
|||
}
|
||||
}
|
||||
|
||||
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients in oxdna/stk");
|
||||
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients in oxrna2/stk");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -576,7 +576,7 @@ void PairOxrna2Xstk::coeff(int narg, char **arg)
|
|||
{
|
||||
int count;
|
||||
|
||||
if (narg != 22) error->all(FLERR,"Incorrect args for pair coefficients in oxdna/xstk");
|
||||
if (narg != 22) error->all(FLERR,"Incorrect args for pair coefficients in oxrna2/xstk");
|
||||
if (!allocated) allocate();
|
||||
|
||||
int ilo,ihi,jlo,jhi;
|
||||
|
@ -707,7 +707,7 @@ void PairOxrna2Xstk::coeff(int narg, char **arg)
|
|||
}
|
||||
}
|
||||
|
||||
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients in oxdna/xstk");
|
||||
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients in oxrna2/xstk");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -31,12 +31,14 @@
|
|||
#include "group.h"
|
||||
#include "info.h"
|
||||
#include "input.h"
|
||||
#include "integrate.h"
|
||||
#include "memory.h"
|
||||
#include "modify.h"
|
||||
#include "molecule.h"
|
||||
#include "neigh_list.h"
|
||||
#include "neighbor.h"
|
||||
#include "region.h"
|
||||
#include "respa.h"
|
||||
#include "output.h"
|
||||
#include "thermo.h"
|
||||
#include "timer.h"
|
||||
|
@ -984,12 +986,14 @@ to then decide how to cast the (void*) pointer and access the data.
|
|||
* \return integer constant encoding the data type of the property
|
||||
* or -1 if not found. */
|
||||
|
||||
int lammps_extract_global_datatype(void *handle, const char *name)
|
||||
int lammps_extract_global_datatype(void * /*handle*/, const char *name)
|
||||
{
|
||||
if (strcmp(name,"dt") == 0) return LAMMPS_DOUBLE;
|
||||
if (strcmp(name,"ntimestep") == 0) return LAMMPS_BIGINT;
|
||||
if (strcmp(name,"atime") == 0) return LAMMPS_DOUBLE;
|
||||
if (strcmp(name,"atimestep") == 0) return LAMMPS_BIGINT;
|
||||
if (strcmp(name,"respa_levels") == 0) return LAMMPS_INT;
|
||||
if (strcmp(name,"respa_dt") == 0) return LAMMPS_DOUBLE;
|
||||
|
||||
if (strcmp(name,"boxlo") == 0) return LAMMPS_DOUBLE;
|
||||
if (strcmp(name,"boxhi") == 0) return LAMMPS_DOUBLE;
|
||||
|
@ -1116,6 +1120,14 @@ report the "native" data type. The following tables are provided:
|
|||
- bigint
|
||||
- 1
|
||||
- the number of the timestep when "atime" was last updated.
|
||||
* - respa_levels
|
||||
- int
|
||||
- 1
|
||||
- number of r-RESPA levels. See :doc:`run_style`.
|
||||
* - respa_dt
|
||||
- double
|
||||
- number of r-RESPA levels
|
||||
- length of the time steps with r-RESPA. See :doc:`run_style`.
|
||||
|
||||
.. _extract_box_settings:
|
||||
|
||||
|
@ -1366,12 +1378,22 @@ void *lammps_extract_global(void *handle, const char *name)
|
|||
if (strcmp(name,"atime") == 0) return (void *) &lmp->update->atime;
|
||||
if (strcmp(name,"atimestep") == 0) return (void *) &lmp->update->atimestep;
|
||||
|
||||
if (utils::strmatch(lmp->update->integrate_style,"^respa")) {
|
||||
Respa *respa = (Respa *)lmp->update->integrate;
|
||||
if (strcmp(name,"respa_levels") == 0) return (void *) &respa->nlevels;
|
||||
if (strcmp(name,"respa_dt") == 0) return (void *) respa->step;
|
||||
}
|
||||
if (strcmp(name,"boxlo") == 0) return (void *) lmp->domain->boxlo;
|
||||
if (strcmp(name,"boxhi") == 0) return (void *) lmp->domain->boxhi;
|
||||
if (strcmp(name,"sublo") == 0) return (void *) lmp->domain->sublo;
|
||||
if (strcmp(name,"subhi") == 0) return (void *) lmp->domain->subhi;
|
||||
if (strcmp(name,"sublo_lambda") == 0) return (void *) lmp->domain->sublo_lamda;
|
||||
if (strcmp(name,"subhi_lambda") == 0) return (void *) lmp->domain->subhi_lamda;
|
||||
// these are only valid for a triclinic cell
|
||||
if (lmp->domain->triclinic) {
|
||||
if (strcmp(name,"sublo_lambda") == 0)
|
||||
return (void *) lmp->domain->sublo_lamda;
|
||||
if (strcmp(name,"subhi_lambda") == 0)
|
||||
return (void *) lmp->domain->subhi_lamda;
|
||||
}
|
||||
if (strcmp(name,"boxxlo") == 0) return (void *) &lmp->domain->boxlo[0];
|
||||
if (strcmp(name,"boxxhi") == 0) return (void *) &lmp->domain->boxhi[0];
|
||||
if (strcmp(name,"boxylo") == 0) return (void *) &lmp->domain->boxlo[1];
|
||||
|
|
|
@ -851,6 +851,14 @@ std::vector<std::string> utils::split_words(const std::string &text)
|
|||
return list;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Convert multi-line string into lines
|
||||
------------------------------------------------------------------------- */
|
||||
std::vector<std::string> utils::split_lines(const std::string &text)
|
||||
{
|
||||
return Tokenizer(text, "\n").as_vector();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Return whether string is a valid integer number
|
||||
------------------------------------------------------------------------- */
|
||||
|
|
|
@ -321,6 +321,12 @@ namespace LAMMPS_NS {
|
|||
|
||||
std::vector<std::string> split_words(const std::string &text);
|
||||
|
||||
/** Take multi-line text and split into lines
|
||||
*
|
||||
* \param text string that should be split
|
||||
* \return STL vector with the lines */
|
||||
std::vector<std::string> split_lines(const std::string &text);
|
||||
|
||||
/** Check if string can be converted to valid integer
|
||||
*
|
||||
* \param str string that should be checked
|
||||
|
|
|
@ -124,7 +124,7 @@ file(GLOB FIX_TIMESTEP_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/fix-tim
|
|||
foreach(TEST ${FIX_TIMESTEP_TESTS})
|
||||
string(REGEX REPLACE "^.*fix-timestep-(.*)\.yaml" "FixTimestep:\\1" TNAME ${TEST})
|
||||
add_test(NAME ${TNAME} COMMAND test_fix_timestep ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
|
||||
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH}")
|
||||
endforeach()
|
||||
|
||||
# dihedral style tester
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
lammps_version: 10 Mar 2021
|
||||
date_generated: Wed Mar 24 18:57:26 202
|
||||
epsilon: 9e-12
|
||||
prerequisites: ! |
|
||||
atom full
|
||||
fix python/move
|
||||
pre_commands: ! ""
|
||||
post_commands: ! |
|
||||
fix test all python/move py_nve.NVE
|
||||
input_file: in.fourmol
|
||||
natoms: 29
|
||||
run_pos: ! |2
|
||||
1 -2.7045559775384037e-01 2.4912159905679729e+00 -1.6695851791541885e-01
|
||||
2 3.1004029573899528e-01 2.9612354631094391e+00 -8.5466363037021464e-01
|
||||
3 -7.0398551400789477e-01 1.2305509955830618e+00 -6.2777526944456274e-01
|
||||
4 -1.5818159336499285e+00 1.4837407818929933e+00 -1.2538710836062004e+00
|
||||
5 -9.0719763672789266e-01 9.2652103885675297e-01 3.9954210488374786e-01
|
||||
6 2.4831720524855985e-01 2.8313021497871271e-01 -1.2314233331711453e+00
|
||||
7 3.4143527641386412e-01 -2.2646551041391422e-02 -2.5292291414903052e+00
|
||||
8 1.1743552229100009e+00 -4.8863228565853950e-01 -6.3783432910825522e-01
|
||||
9 1.3800524229500313e+00 -2.5274721030406683e-01 2.8353985887095157e-01
|
||||
10 2.0510765220543883e+00 -1.4604063740302866e+00 -9.8323745081712954e-01
|
||||
11 1.7878031944442556e+00 -1.9921863272948861e+00 -1.8890602447625777e+00
|
||||
12 3.0063007039340053e+00 -4.9013350496963298e-01 -1.6231898107386229e+00
|
||||
13 4.0515402959192999e+00 -8.9202011606653986e-01 -1.6400005529924957e+00
|
||||
14 2.6066963345543819e+00 -4.1789253965514150e-01 -2.6634003608794394e+00
|
||||
15 2.9695287185712913e+00 5.5422613165234036e-01 -1.2342022021790127e+00
|
||||
16 2.6747029695228521e+00 -2.4124119054564295e+00 -2.3435746150616148e-02
|
||||
17 2.2153577785283796e+00 -2.0897985186907717e+00 1.1963150794479436e+00
|
||||
18 2.1369701704115704e+00 3.0158507413630606e+00 -3.5179348337215015e+00
|
||||
19 1.5355837136087378e+00 2.6255292355375675e+00 -4.2353987779879052e+00
|
||||
20 2.7727573005678776e+00 3.6923910449610169e+00 -3.9330842459133493e+00
|
||||
21 4.9040128073204299e+00 -4.0752348172957946e+00 -3.6210314709891711e+00
|
||||
22 4.3582355554440841e+00 -4.2126119427287048e+00 -4.4612844196314052e+00
|
||||
23 5.7439382849307599e+00 -3.5821957939275029e+00 -3.8766361295935821e+00
|
||||
24 2.0689243582422630e+00 3.1513346907271012e+00 3.1550389754828800e+00
|
||||
25 1.3045351331492134e+00 3.2665125705842848e+00 2.5111855257433504e+00
|
||||
26 2.5809237402711274e+00 4.0117602605482832e+00 3.2212060529089896e+00
|
||||
27 -1.9611343130357228e+00 -4.3563411931359752e+00 2.1098293115523705e+00
|
||||
28 -2.7473562684513411e+00 -4.0200819932379330e+00 1.5830052163433954e+00
|
||||
29 -1.3126000191359855e+00 -3.5962518039482929e+00 2.2746342468737835e+00
|
||||
run_vel: ! |2
|
||||
1 8.1705744183262364e-03 1.6516406176274288e-02 4.7902264318912978e-03
|
||||
2 5.4501493445687759e-03 5.1791699408496334e-03 -1.4372931530376651e-03
|
||||
3 -8.2298292722385643e-03 -1.2926551614621381e-02 -4.0984181178163881e-03
|
||||
4 -3.7699042590093588e-03 -6.5722892098813799e-03 -1.1184640360133230e-03
|
||||
5 -1.1021961004346586e-02 -9.8906780939335987e-03 -2.8410737829284395e-03
|
||||
6 -3.9676663166400034e-02 4.6817061464710256e-02 3.7148491979476124e-02
|
||||
7 9.1033953013898580e-04 -1.0128524411938794e-02 -5.1568251805019748e-02
|
||||
8 7.9064712058855707e-03 -3.3507254552631767e-03 3.4557098492564629e-02
|
||||
9 1.5644176117320923e-03 3.7365546102722164e-03 1.5047408822037646e-02
|
||||
10 2.9201446820573174e-02 -2.9249578745486147e-02 -1.5018077424322538e-02
|
||||
11 -4.7835961513517560e-03 -3.7481385134185206e-03 -2.3464104142290089e-03
|
||||
12 2.2696451841920521e-03 -3.4774154398129479e-04 -3.0640770327796806e-03
|
||||
13 2.7531740451953168e-03 5.8171061612840667e-03 -7.9467454022160518e-04
|
||||
14 3.5246182371994252e-03 -5.7939995585585468e-03 -3.9478431172751344e-03
|
||||
15 -1.8547943640122894e-03 -5.8554729942777743e-03 6.2938485140538649e-03
|
||||
16 1.8681499973445245e-02 -1.3262466204585335e-02 -4.5638651457003243e-02
|
||||
17 -1.2896269981100382e-02 9.7527665265956451e-03 3.7296535360836762e-02
|
||||
18 -8.0065794848261610e-04 -8.6270473212554395e-04 -1.4483040697508738e-03
|
||||
19 1.2452390836182623e-03 -2.5061097118772701e-03 7.2998631009712975e-03
|
||||
20 3.5930060229597042e-03 3.6938860309252966e-03 3.2322732687893028e-03
|
||||
21 -1.4689220370766550e-03 -2.7352129761527741e-04 7.0581624215243391e-04
|
||||
22 -7.0694199254630339e-03 -4.2577148924878554e-03 2.8079117614251796e-04
|
||||
23 6.0446963117374913e-03 -1.4000131614795382e-03 2.5819754847014255e-03
|
||||
24 3.1926367902287940e-04 -9.9445664749276438e-04 1.4999996959365452e-04
|
||||
25 1.3789754514814662e-04 -4.4335894884532569e-03 -8.1808136725080281e-04
|
||||
26 2.0485904035217549e-03 2.7813358633835984e-03 4.3245727149206692e-03
|
||||
27 4.5604120293369857e-04 -1.0305523026921137e-03 2.1188058381358511e-04
|
||||
28 -6.2544520861855116e-03 1.4127711176146942e-03 -1.8429821884794269e-03
|
||||
29 6.4110631534401762e-04 3.1273432719593867e-03 3.7253671105656715e-03
|
||||
...
|
|
@ -0,0 +1,104 @@
|
|||
from __future__ import print_function
|
||||
from lammps import lammps
|
||||
|
||||
class LAMMPSFix(object):
|
||||
def __init__(self, ptr, group_name="all"):
|
||||
self.lmp = lammps(ptr=ptr)
|
||||
self.group_name = group_name
|
||||
|
||||
class LAMMPSFixMove(LAMMPSFix):
|
||||
def __init__(self, ptr, group_name="all"):
|
||||
super(LAMMPSFixMove, self).__init__(ptr, group_name)
|
||||
|
||||
def init(self):
|
||||
pass
|
||||
|
||||
def initial_integrate(self, vflag):
|
||||
pass
|
||||
|
||||
def final_integrate(self):
|
||||
pass
|
||||
|
||||
def initial_integrate_respa(self, vflag, ilevel, iloop):
|
||||
pass
|
||||
|
||||
def final_integrate_respa(self, ilevel, iloop):
|
||||
pass
|
||||
|
||||
def reset_dt(self):
|
||||
pass
|
||||
|
||||
|
||||
class NVE(LAMMPSFixMove):
|
||||
""" Python implementation of fix/nve """
|
||||
def __init__(self, ptr, group_name="all"):
|
||||
super(NVE, self).__init__(ptr)
|
||||
assert(self.group_name == "all")
|
||||
self._step_respa = None
|
||||
|
||||
def init(self):
|
||||
dt = self.lmp.extract_global("dt")
|
||||
ftm2v = self.lmp.extract_global("ftm2v")
|
||||
self.ntypes = self.lmp.extract_global("ntypes")
|
||||
self.dtv = dt
|
||||
self.dtf = 0.5 * dt * ftm2v
|
||||
|
||||
@property
|
||||
def step_respa(self):
|
||||
if not self._step_respa:
|
||||
self._step_respa = self.lmp.extract_global("respa_dt")
|
||||
return self._step_respa
|
||||
|
||||
def initial_integrate(self, vflag):
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
mass = self.lmp.extract_atom("mass")
|
||||
atype = self.lmp.extract_atom("type")
|
||||
x = self.lmp.extract_atom("x")
|
||||
v = self.lmp.extract_atom("v")
|
||||
f = self.lmp.extract_atom("f")
|
||||
|
||||
for i in range(nlocal):
|
||||
dtfm = self.dtf / mass[int(atype[i])]
|
||||
v[i][0] += dtfm * f[i][0]
|
||||
v[i][1] += dtfm * f[i][1]
|
||||
v[i][2] += dtfm * f[i][2]
|
||||
x[i][0] += self.dtv * v[i][0]
|
||||
x[i][1] += self.dtv * v[i][1]
|
||||
x[i][2] += self.dtv * v[i][2]
|
||||
|
||||
def final_integrate(self):
|
||||
nlocal = self.lmp.extract_global("nlocal")
|
||||
mass = self.lmp.extract_atom("mass")
|
||||
atype = self.lmp.extract_atom("type")
|
||||
v = self.lmp.extract_atom("v")
|
||||
f = self.lmp.extract_atom("f")
|
||||
|
||||
for i in range(nlocal):
|
||||
dtfm = self.dtf / mass[int(atype[i])]
|
||||
v[i][0] += dtfm * f[i][0]
|
||||
v[i][1] += dtfm * f[i][1]
|
||||
v[i][2] += dtfm * f[i][2]
|
||||
|
||||
def initial_integrate_respa(self, vflag, ilevel, iloop):
|
||||
ftm2v = self.lmp.extract_global("ftm2v")
|
||||
self.dtv = self.step_respa[ilevel]
|
||||
self.dtf = 0.5 * self.step_respa[ilevel] * ftm2v
|
||||
|
||||
# innermost level - NVE update of v and x
|
||||
# all other levels - NVE update of v
|
||||
|
||||
if ilevel == 0:
|
||||
self.initial_integrate(vflag)
|
||||
else:
|
||||
self.final_integrate()
|
||||
|
||||
def final_integrate_respa(self, ilevel, iloop):
|
||||
ftm2v = self.lmp.extract_global("ftm2v")
|
||||
self.dtf = 0.5 * self.step_respa[ilevel] * ftm2v
|
||||
self.final_integrate()
|
||||
|
||||
def reset_dt(self):
|
||||
dt = self.lmp.extract_global("dt")
|
||||
ftm2v = self.lmp.extract_global("ftm2v")
|
||||
self.dtv = dt;
|
||||
self.dtf = 0.5 * dt * ftm2v;
|
|
@ -8,7 +8,7 @@ add_executable(test_python_package test_python_package.cpp)
|
|||
target_link_libraries(test_python_package PRIVATE lammps GTest::GMock GTest::GTest)
|
||||
target_compile_definitions(test_python_package PRIVATE -DTEST_INPUT_FOLDER=${TEST_INPUT_FOLDER})
|
||||
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}")
|
||||
set_tests_properties(PythonPackage PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}:${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH};PYTHONUNBUFFERED=1")
|
||||
|
||||
# we must have shared libraries enabled for testing the python module
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
|
|
|
@ -4,6 +4,16 @@ from __future__ import print_function
|
|||
def square(val):
|
||||
return val*val
|
||||
|
||||
def bool_to_val(txt):
|
||||
if txt.upper() in ["TRUE", "YES"]:
|
||||
return 1.0
|
||||
return 0.0
|
||||
|
||||
def val_to_bool(val):
|
||||
if val != 0:
|
||||
return "True"
|
||||
return "False"
|
||||
|
||||
def printnum():
|
||||
print("2.25")
|
||||
|
||||
|
@ -11,8 +21,10 @@ def printtxt():
|
|||
print("sometext")
|
||||
|
||||
def getidxvar(lmpptr):
|
||||
from lammps import lammps, LMP_VAR_EQUAL
|
||||
from lammps import lammps
|
||||
lmp = lammps(ptr=lmpptr)
|
||||
|
||||
val = lmp.extract_variable("idx",None,LMP_VAR_EQUAL)
|
||||
val = lmp.extract_variable("idx")
|
||||
print(val)
|
||||
|
||||
def longstr():
|
||||
return "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent metus."
|
||||
|
|
|
@ -259,15 +259,43 @@ create_atoms 1 single &
|
|||
result = self.lmp.get_thermo(key)
|
||||
self.assertEqual(value, result, key)
|
||||
|
||||
def test_extract_global_double(self):
|
||||
def test_extract_global(self):
|
||||
self.lmp.command("region box block -1 1 -2 2 -3 3")
|
||||
self.lmp.command("create_box 1 box")
|
||||
self.assertEqual(self.lmp.extract_global("units"), "lj")
|
||||
self.assertEqual(self.lmp.extract_global("ntimestep"), 0)
|
||||
self.assertEqual(self.lmp.extract_global("dt"), 0.005)
|
||||
|
||||
self.assertEqual(self.lmp.extract_global("boxxlo"), -1.0)
|
||||
self.assertEqual(self.lmp.extract_global("boxxhi"), 1.0)
|
||||
self.assertEqual(self.lmp.extract_global("boxylo"), -2.0)
|
||||
self.assertEqual(self.lmp.extract_global("boxyhi"), 2.0)
|
||||
self.assertEqual(self.lmp.extract_global("boxzlo"), -3.0)
|
||||
self.assertEqual(self.lmp.extract_global("boxzhi"), 3.0)
|
||||
self.assertEqual(self.lmp.extract_global("boxlo"), [-1.0, -2.0, -3.0])
|
||||
self.assertEqual(self.lmp.extract_global("boxhi"), [1.0, 2.0, 3.0])
|
||||
self.assertEqual(self.lmp.extract_global("sublo"), [-1.0, -2.0, -3.0])
|
||||
self.assertEqual(self.lmp.extract_global("subhi"), [1.0, 2.0, 3.0])
|
||||
self.assertEqual(self.lmp.extract_global("periodicity"), [1,1,1])
|
||||
self.assertEqual(self.lmp.extract_global("triclinic"), 0)
|
||||
self.assertEqual(self.lmp.extract_global("sublo_lambda"), None)
|
||||
self.assertEqual(self.lmp.extract_global("subhi_lambda"), None)
|
||||
self.assertEqual(self.lmp.extract_global("respa_levels"), None)
|
||||
self.assertEqual(self.lmp.extract_global("respa_dt"), None)
|
||||
|
||||
# set and initialize r-RESPA
|
||||
self.lmp.command("run_style respa 3 5 2 pair 2 kspace 3")
|
||||
self.lmp.command("mass * 1.0")
|
||||
self.lmp.command("run 1 post no")
|
||||
self.assertEqual(self.lmp.extract_global("ntimestep"), 1)
|
||||
self.assertEqual(self.lmp.extract_global("respa_levels"), 3)
|
||||
self.assertEqual(self.lmp.extract_global("respa_dt"), [0.0005, 0.0025, 0.005])
|
||||
|
||||
# checks only for triclinic boxes
|
||||
self.lmp.command("change_box all triclinic")
|
||||
self.assertEqual(self.lmp.extract_global("triclinic"), 1)
|
||||
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])
|
||||
|
||||
##############################
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
from __future__ import print_function
|
||||
print("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent metus.")
|
|
@ -14,19 +14,25 @@
|
|||
#include "atom.h"
|
||||
#include "info.h"
|
||||
#include "input.h"
|
||||
#include "variable.h"
|
||||
#include "library.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include "../testing/core.h"
|
||||
#include "../testing/systems/melt.h"
|
||||
|
||||
// location of '*.py' files required by tests
|
||||
#define STRINGIFY(val) XSTR(val)
|
||||
#define XSTR(val) #val
|
||||
std::string INPUT_FOLDER = STRINGIFY(TEST_INPUT_FOLDER);
|
||||
|
||||
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
|
||||
const char * LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent metus.";
|
||||
bool verbose = false;
|
||||
|
||||
using LAMMPS_NS::utils::split_words;
|
||||
|
@ -34,95 +40,287 @@ using LAMMPS_NS::utils::split_words;
|
|||
namespace LAMMPS_NS {
|
||||
using ::testing::MatchesRegex;
|
||||
using ::testing::StrEq;
|
||||
using ::testing::Eq;
|
||||
using ::testing::HasSubstr;
|
||||
|
||||
class PythonPackageTest : public ::testing::Test {
|
||||
class PythonPackageTest : public LAMMPSTest {
|
||||
protected:
|
||||
LAMMPS *lmp;
|
||||
Info *info;
|
||||
|
||||
void SetUp() override
|
||||
void InitSystem() override
|
||||
{
|
||||
const char *args[] = {"PythonPackageTest", "-log", "none", "-echo", "screen", "-nocite"};
|
||||
char **argv = (char **)args;
|
||||
int argc = sizeof(args) / sizeof(char *);
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
ASSERT_NE(lmp, nullptr);
|
||||
info = new Info(lmp);
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
lmp->input->one("units real");
|
||||
lmp->input->one("dimension 3");
|
||||
lmp->input->one("region box block -4 4 -4 4 -4 4");
|
||||
lmp->input->one("create_box 1 box");
|
||||
lmp->input->one("create_atoms 1 single 0.0 0.0 0.0 units box");
|
||||
lmp->input->one("create_atoms 1 single 1.9 -1.9 1.9999 units box");
|
||||
lmp->input->one("pair_style zero 2.0");
|
||||
lmp->input->one("pair_coeff * *");
|
||||
lmp->input->one("mass * 1.0");
|
||||
lmp->input->one("variable input_dir index " + INPUT_FOLDER);
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
}
|
||||
if (!info->has_package("PYTHON")) GTEST_SKIP();
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
delete info;
|
||||
delete lmp;
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
HIDE_OUTPUT([&] {
|
||||
command("units real");
|
||||
command("dimension 3");
|
||||
command("region box block -4 4 -4 4 -4 4");
|
||||
command("create_box 1 box");
|
||||
command("create_atoms 1 single 0.0 0.0 0.0 units box");
|
||||
command("create_atoms 1 single 1.9 -1.9 1.9999 units box");
|
||||
command("pair_style zero 2.0");
|
||||
command("pair_coeff * *");
|
||||
command("mass * 1.0");
|
||||
command("variable input_dir index " + INPUT_FOLDER);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(PythonPackageTest, python_invoke)
|
||||
class FixPythonInvokeTest : public MeltTest {
|
||||
protected:
|
||||
void InitSystem() override
|
||||
{
|
||||
if (!info->has_package("PYTHON")) GTEST_SKIP();
|
||||
|
||||
MeltTest::InitSystem();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(PythonPackageTest, InvokeFunctionFromFile)
|
||||
{
|
||||
if (!info->has_style("command", "python")) GTEST_SKIP();
|
||||
// execute python function from file
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
lmp->input->one("python printnum file ${input_dir}/func.py");
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
::testing::internal::CaptureStdout();
|
||||
lmp->input->one("python printnum invoke");
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
if (verbose) std::cout << output;
|
||||
ASSERT_THAT(output, MatchesRegex("python.*2.25.*"));
|
||||
HIDE_OUTPUT([&] {
|
||||
command("python printnum file ${input_dir}/func.py");
|
||||
});
|
||||
|
||||
auto output = CAPTURE_OUTPUT([&]() {
|
||||
command("python printnum invoke");
|
||||
});
|
||||
ASSERT_THAT(output, HasSubstr("2.25\n"));
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, InvokeFunctionPassInt)
|
||||
{
|
||||
// execute python function, passing integer as argument
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable sq python square");
|
||||
command("python square input 1 2 format ii return v_sq file ${input_dir}/func.py");
|
||||
command("python square invoke");
|
||||
});
|
||||
|
||||
ASSERT_EQ(get_variable_value("sq"), 4.0);
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, InvokeFunctionPassFloat)
|
||||
{
|
||||
// execute python function, passing float as argument
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable sq python square");
|
||||
command("python square input 1 2.5 format ff return v_sq file ${input_dir}/func.py");
|
||||
});
|
||||
|
||||
ASSERT_EQ(get_variable_value("sq"), 6.25);
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, InvokeFunctionPassString)
|
||||
{
|
||||
// execute python function, passing string as argument
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable val python bool_to_val");
|
||||
command("python bool_to_val input 1 \"true\" format sf return v_val file ${input_dir}/func.py");
|
||||
});
|
||||
|
||||
ASSERT_EQ(get_variable_value("val"), 1.0);
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, InvokeFunctionPassStringVariable)
|
||||
{
|
||||
// execute python function, passing string variable as argument
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable val python bool_to_val");
|
||||
command("python bool_to_val input 1 v_str format sf return v_val file ${input_dir}/func.py");
|
||||
});
|
||||
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable str string \"true\"");
|
||||
});
|
||||
|
||||
ASSERT_EQ(get_variable_value("val"), 1.0);
|
||||
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable str string \"false\"");
|
||||
});
|
||||
|
||||
ASSERT_EQ(get_variable_value("val"), 0.0);
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, InvokeStringFunction)
|
||||
{
|
||||
// execute python function, passing string variable as argument
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable str python val_to_bool");
|
||||
command("python val_to_bool input 1 v_val format is return v_str file ${input_dir}/func.py");
|
||||
});
|
||||
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable val equal 0");
|
||||
});
|
||||
|
||||
ASSERT_THAT(get_variable_string("str"), StrEq("False"));
|
||||
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable val equal 1");
|
||||
});
|
||||
|
||||
ASSERT_THAT(get_variable_string("str"), StrEq("True"));
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, InvokeLongStringFunction)
|
||||
{
|
||||
// execute python function, passing string variable as argument
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable str python longstr");
|
||||
command("python longstr format s length 72 return v_str file ${input_dir}/func.py");
|
||||
});
|
||||
|
||||
ASSERT_THAT(get_variable_string("str"), StrEq(LOREM_IPSUM));
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, InvokeOtherFunctionFromFile)
|
||||
{
|
||||
// execute another python function from same file
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
lmp->input->one("python printtxt exists");
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
::testing::internal::CaptureStdout();
|
||||
lmp->input->one("python printtxt invoke");
|
||||
output = ::testing::internal::GetCapturedStdout();
|
||||
if (verbose) std::cout << output;
|
||||
ASSERT_THAT(output, MatchesRegex("python.*sometext.*"));
|
||||
HIDE_OUTPUT([&] {
|
||||
command("python printnum file ${input_dir}/func.py");
|
||||
command("python printtxt exists");
|
||||
});
|
||||
|
||||
auto output = CAPTURE_OUTPUT([&] {
|
||||
command("python printtxt invoke");
|
||||
});
|
||||
ASSERT_THAT(output, HasSubstr("sometext\n"));
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, InvokeFunctionThatUsesLAMMPSModule)
|
||||
{
|
||||
// execute python function that uses the LAMMPS python module
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
lmp->input->one("variable idx equal 2.25");
|
||||
lmp->input->one("python getidxvar input 1 SELF format p exists");
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
::testing::internal::CaptureStdout();
|
||||
lmp->input->one("python getidxvar invoke");
|
||||
output = ::testing::internal::GetCapturedStdout();
|
||||
if (verbose) std::cout << output;
|
||||
ASSERT_THAT(output, MatchesRegex("python.*2.25.*"));
|
||||
HIDE_OUTPUT([&] {
|
||||
command("python printnum file ${input_dir}/func.py");
|
||||
command("variable idx equal 2.25");
|
||||
command("python getidxvar input 1 SELF format p exists");
|
||||
});
|
||||
auto output = CAPTURE_OUTPUT([&] {
|
||||
command("python getidxvar invoke");
|
||||
});
|
||||
ASSERT_THAT(output, HasSubstr("2.25\n"));
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, python_variable)
|
||||
{
|
||||
if (!info->has_style("command", "python")) GTEST_SKIP();
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
lmp->input->one("variable sq python square");
|
||||
lmp->input->one("variable val index 1.5");
|
||||
lmp->input->one("python square input 1 v_val return v_sq format ff file ${input_dir}/func.py");
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
::testing::internal::CaptureStdout();
|
||||
lmp->input->one("print \"${sq}\"");
|
||||
std::string output = ::testing::internal::GetCapturedStdout();
|
||||
if (verbose) std::cout << output;
|
||||
// define variable that evaluates a python function
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable sq python square");
|
||||
command("variable val index 1.5");
|
||||
command("python square input 1 v_val return v_sq format ff file ${input_dir}/func.py");
|
||||
});
|
||||
std::string output = CAPTURE_OUTPUT([&] {
|
||||
command("print \"${sq}\"");
|
||||
});
|
||||
ASSERT_THAT(output, MatchesRegex("print.*2.25.*"));
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, InlineFunction)
|
||||
{
|
||||
// define variable that evaluates a python function
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable fact python factorial");
|
||||
command("python factorial input 1 v_n return v_fact format ii here \"\"\"\n"
|
||||
"def factorial(n):\n"
|
||||
" if n == 0 or n == 1: return 1\n"
|
||||
" return n*factorial(n-1)\n"
|
||||
"\"\"\"");
|
||||
});
|
||||
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable n equal 1");
|
||||
});
|
||||
|
||||
ASSERT_EQ(get_variable_value("fact"), 1.0);
|
||||
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable n equal 2");
|
||||
});
|
||||
|
||||
ASSERT_EQ(get_variable_value("fact"), 2.0);
|
||||
|
||||
HIDE_OUTPUT([&] {
|
||||
command("variable n equal 3");
|
||||
});
|
||||
|
||||
ASSERT_EQ(get_variable_value("fact"), 6.0);
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, RunSource)
|
||||
{
|
||||
// execute python script from file
|
||||
auto output = CAPTURE_OUTPUT([&] {
|
||||
command("python xyz source ${input_dir}/run.py");
|
||||
});
|
||||
|
||||
ASSERT_THAT(output, HasSubstr(LOREM_IPSUM));
|
||||
}
|
||||
|
||||
TEST_F(PythonPackageTest, RunSourceInline)
|
||||
{
|
||||
// execute inline python script
|
||||
auto output = CAPTURE_OUTPUT([&] {
|
||||
command("python xyz source \"\"\"\n"
|
||||
"from __future__ import print_function\n"
|
||||
"print(2+2)\n"
|
||||
"\"\"\""
|
||||
);
|
||||
});
|
||||
|
||||
ASSERT_THAT(output, HasSubstr("4"));
|
||||
}
|
||||
|
||||
TEST_F(FixPythonInvokeTest, end_of_step)
|
||||
{
|
||||
HIDE_OUTPUT([&] {
|
||||
command("python end_of_step_callback here \"\"\"\n"
|
||||
"from __future__ import print_function\n"
|
||||
"def end_of_step_callback(ptr):\n"
|
||||
" print(\"PYTHON_END_OF_STEP\")\n"
|
||||
"\"\"\"");
|
||||
command("fix eos all python/invoke 10 end_of_step end_of_step_callback");
|
||||
});
|
||||
|
||||
auto output = CAPTURE_OUTPUT([&] {
|
||||
command("run 50");
|
||||
});
|
||||
|
||||
auto lines = utils::split_lines(output);
|
||||
int count = 0;
|
||||
|
||||
for(auto & line : lines) {
|
||||
if (line == "PYTHON_END_OF_STEP") ++count;
|
||||
}
|
||||
|
||||
ASSERT_EQ(count, 5);
|
||||
}
|
||||
|
||||
TEST_F(FixPythonInvokeTest, post_force)
|
||||
{
|
||||
HIDE_OUTPUT([&] {
|
||||
command("python post_force_callback here \"\"\"\n"
|
||||
"from __future__ import print_function\n"
|
||||
"def post_force_callback(ptr, vflag):\n"
|
||||
" print(\"PYTHON_POST_FORCE\")\n"
|
||||
"\"\"\"");
|
||||
command("fix pf all python/invoke 10 post_force post_force_callback");
|
||||
});
|
||||
|
||||
auto output = CAPTURE_OUTPUT([&] {
|
||||
command("run 50");
|
||||
});
|
||||
|
||||
auto lines = utils::split_lines(output);
|
||||
int count = 0;
|
||||
|
||||
for(auto & line : lines) {
|
||||
if (line == "PYTHON_POST_FORCE") ++count;
|
||||
}
|
||||
|
||||
ASSERT_EQ(count, 5);
|
||||
}
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -132,7 +330,7 @@ int main(int argc, char **argv)
|
|||
|
||||
// handle arguments passed via environment variable
|
||||
if (const char *var = getenv("TEST_ARGS")) {
|
||||
std::vector<std::string> env = split_words(var);
|
||||
auto env = split_words(var);
|
||||
for (auto arg : env) {
|
||||
if (arg == "-v") {
|
||||
verbose = true;
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
#include "info.h"
|
||||
#include "input.h"
|
||||
#include "lammps.h"
|
||||
#include "variable.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
using ::testing::MatchesRegex;
|
||||
|
@ -45,29 +48,58 @@ class LAMMPSTest : public ::testing::Test {
|
|||
public:
|
||||
void command(const std::string &line) { lmp->input->one(line.c_str()); }
|
||||
|
||||
void HIDE_OUTPUT(std::function<void()> f) {
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
f();
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
}
|
||||
|
||||
std::string CAPTURE_OUTPUT(std::function<void()> f) {
|
||||
::testing::internal::CaptureStdout();
|
||||
f();
|
||||
auto output = ::testing::internal::GetCapturedStdout();
|
||||
if (verbose) std::cout << output;
|
||||
return output;
|
||||
}
|
||||
|
||||
double get_variable_value(const std::string & name) {
|
||||
char * str = utils::strdup(fmt::format("v_{}", name));
|
||||
double value = lmp->input->variable->compute_equal(str);
|
||||
delete [] str;
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string get_variable_string(const std::string & name) {
|
||||
return lmp->input->variable->retrieve(name.c_str());
|
||||
}
|
||||
|
||||
protected:
|
||||
const char *testbinary = "LAMMPSTest";
|
||||
LAMMPS *lmp;
|
||||
Info *info;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
const char *args[] = {testbinary, "-log", "none", "-echo", "screen", "-nocite"};
|
||||
char **argv = (char **)args;
|
||||
int argc = sizeof(args) / sizeof(char *);
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
|
||||
HIDE_OUTPUT([&] {
|
||||
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
|
||||
info = new Info(lmp);
|
||||
});
|
||||
InitSystem();
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
}
|
||||
|
||||
virtual void InitSystem() {}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
if (!verbose) ::testing::internal::CaptureStdout();
|
||||
delete lmp;
|
||||
lmp = nullptr;
|
||||
if (!verbose) ::testing::internal::GetCapturedStdout();
|
||||
HIDE_OUTPUT([&] {
|
||||
delete info;
|
||||
delete lmp;
|
||||
info = nullptr;
|
||||
lmp = nullptr;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -19,23 +19,25 @@ class MeltTest : public LAMMPSTest {
|
|||
protected:
|
||||
virtual void InitSystem() override
|
||||
{
|
||||
command("units lj");
|
||||
command("atom_style atomic");
|
||||
command("atom_modify map yes");
|
||||
HIDE_OUTPUT([&] {
|
||||
command("units lj");
|
||||
command("atom_style atomic");
|
||||
command("atom_modify map yes");
|
||||
|
||||
command("lattice fcc 0.8442");
|
||||
command("region box block 0 2 0 2 0 2");
|
||||
command("create_box 1 box");
|
||||
command("create_atoms 1 box");
|
||||
command("mass 1 1.0");
|
||||
command("lattice fcc 0.8442");
|
||||
command("region box block 0 2 0 2 0 2");
|
||||
command("create_box 1 box");
|
||||
command("create_atoms 1 box");
|
||||
command("mass 1 1.0");
|
||||
|
||||
command("velocity all create 3.0 87287");
|
||||
command("velocity all create 3.0 87287");
|
||||
|
||||
command("pair_style lj/cut 2.5");
|
||||
command("pair_coeff 1 1 1.0 1.0 2.5");
|
||||
command("pair_style lj/cut 2.5");
|
||||
command("pair_coeff 1 1 1.0 1.0 2.5");
|
||||
|
||||
command("neighbor 0.3 bin");
|
||||
command("neigh_modify every 20 delay 0 check no");
|
||||
command("neighbor 0.3 bin");
|
||||
command("neigh_modify every 20 delay 0 check no");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ TEST(Utils, count_words_with_extra_spaces)
|
|||
|
||||
TEST(Utils, split_words_simple)
|
||||
{
|
||||
std::vector<std::string> list = utils::split_words("one two three");
|
||||
auto list = utils::split_words("one two three");
|
||||
ASSERT_EQ(list.size(), 3);
|
||||
ASSERT_THAT(list[0], StrEq("one"));
|
||||
ASSERT_THAT(list[1], StrEq("two"));
|
||||
|
@ -122,7 +122,7 @@ TEST(Utils, split_words_simple)
|
|||
|
||||
TEST(Utils, split_words_quoted)
|
||||
{
|
||||
std::vector<std::string> list = utils::split_words("one 'two' \"three\"");
|
||||
auto list = utils::split_words("one 'two' \"three\"");
|
||||
ASSERT_EQ(list.size(), 3);
|
||||
ASSERT_THAT(list[0], StrEq("one"));
|
||||
ASSERT_THAT(list[1], StrEq("two"));
|
||||
|
@ -131,7 +131,7 @@ TEST(Utils, split_words_quoted)
|
|||
|
||||
TEST(Utils, split_words_escaped)
|
||||
{
|
||||
std::vector<std::string> list = utils::split_words("1\\' '\"two\"' 3\\\"");
|
||||
auto list = utils::split_words("1\\' '\"two\"' 3\\\"");
|
||||
ASSERT_EQ(list.size(), 3);
|
||||
ASSERT_THAT(list[0], StrEq("1\\'"));
|
||||
ASSERT_THAT(list[1], StrEq("\"two\""));
|
||||
|
@ -140,13 +140,22 @@ TEST(Utils, split_words_escaped)
|
|||
|
||||
TEST(Utils, split_words_quote_in_quoted)
|
||||
{
|
||||
std::vector<std::string> list = utils::split_words("one 't\\'wo' \"th\\\"ree\"");
|
||||
auto list = utils::split_words("one 't\\'wo' \"th\\\"ree\"");
|
||||
ASSERT_EQ(list.size(), 3);
|
||||
ASSERT_THAT(list[0], StrEq("one"));
|
||||
ASSERT_THAT(list[1], StrEq("t\\'wo"));
|
||||
ASSERT_THAT(list[2], StrEq("th\\\"ree"));
|
||||
}
|
||||
|
||||
TEST(Utils, split_lines)
|
||||
{
|
||||
auto list = utils::split_lines(" line 1\nline 2 \n line 3 \n");
|
||||
ASSERT_EQ(list.size(), 3);
|
||||
ASSERT_THAT(list[0], StrEq(" line 1"));
|
||||
ASSERT_THAT(list[1], StrEq("line 2 "));
|
||||
ASSERT_THAT(list[2], StrEq(" line 3 "));
|
||||
}
|
||||
|
||||
TEST(Utils, valid_integer1)
|
||||
{
|
||||
ASSERT_TRUE(utils::is_integer("10"));
|
||||
|
|
Loading…
Reference in New Issue