add support for set_vector for fix external in c-library, python and unittest
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -44,6 +44,7 @@ Thumbs.db
|
||||
/build*
|
||||
/CMakeCache.txt
|
||||
/CMakeFiles/
|
||||
/Testing
|
||||
/Makefile
|
||||
/cmake_install.cmake
|
||||
/lmp
|
||||
|
||||
@ -8,7 +8,11 @@ functions. They do not directly call the LAMMPS library.
|
||||
- :cpp:func:`lammps_decode_image_flags`
|
||||
- :cpp:func:`lammps_set_fix_external_callback`
|
||||
- :cpp:func:`lammps_fix_external_set_energy_global`
|
||||
- :cpp:func:`lammps_fix_external_set_energy_peratom`
|
||||
- :cpp:func:`lammps_fix_external_set_virial_global`
|
||||
- :cpp:func:`lammps_fix_external_set_virial_peratom`
|
||||
- :cpp:func:`lammps_fix_external_set_vector_length`
|
||||
- :cpp:func:`lammps_fix_external_set_vector`
|
||||
- :cpp:func:`lammps_free`
|
||||
- :cpp:func:`lammps_is_running`
|
||||
- :cpp:func:`lammps_force_timeout`
|
||||
@ -43,11 +47,31 @@ where such memory buffers were allocated that require the use of
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_fix_external_set_energy_peratom
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_fix_external_set_virial_global
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_fix_external_set_virial_peratom
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_fix_external_set_vector_length
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_fix_external_set_vector
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_free
|
||||
:project: progguide
|
||||
|
||||
|
||||
@ -303,6 +303,9 @@ class lammps(object):
|
||||
self.lib.lammps_fix_external_set_energy_peratom.argtypes = [c_void_p, c_char_p, POINTER(c_double)]
|
||||
self.lib.lammps_fix_external_set_virial_peratom.argtypes = [c_void_p, c_char_p, POINTER(POINTER(c_double))]
|
||||
|
||||
self.lib.lammps_fix_external_set_vector_length.argtypes = [c_void_p, c_char_p, c_int]
|
||||
self.lib.lammps_fix_external_set_vector.argtypes = [c_void_p, c_char_p, c_int, c_double]
|
||||
|
||||
# detect if Python is using a version of mpi4py that can pass communicators
|
||||
# only needed if LAMMPS has been compiled with MPI support.
|
||||
self.has_mpi4py = False
|
||||
@ -1806,6 +1809,40 @@ class lammps(object):
|
||||
with ExceptionCheck(self):
|
||||
return self.lib.lammps_fix_external_set_energy_global(self.lmp, fix_id.encode(), eng)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def fix_external_set_vector_length(self, fix_id, length):
|
||||
"""Set the vector length for a global vector stored with fix external for analysis
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_fix_external_set_vector_length` function
|
||||
of the C-library interface.
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:param length: length of the global vector
|
||||
:type: int
|
||||
"""
|
||||
|
||||
with ExceptionCheck(self):
|
||||
return self.lib.lammps_fix_external_set_vector_length(self.lmp, fix_id.encode(), length)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def fix_external_set_vector(self, fix_id, idx, val):
|
||||
"""Store a global vector value for a fix external instance with the given ID.
|
||||
|
||||
This is a wrapper around the :cpp:func:`lammps_fix_external_set_vector` function
|
||||
of the C-library interface.
|
||||
|
||||
:param fix_id: Fix-ID of a fix external instance
|
||||
:type: string
|
||||
:param idx: 1-based index of the value in the global vector
|
||||
:type: int
|
||||
:param val: value to be stored in the global vector
|
||||
:type: float
|
||||
"""
|
||||
|
||||
with ExceptionCheck(self):
|
||||
return self.lib.lammps_fix_external_set_vector(self.lmp, fix_id.encode(), idx, val)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def get_neighlist(self, idx):
|
||||
|
||||
@ -4821,7 +4821,7 @@ mode. The function has to have C language bindings with the prototype:
|
||||
|
||||
void func(void *ptr, bigint timestep, int nlocal, tagint *ids, double **x, double **fexternal);
|
||||
|
||||
This is an alternative to the array mechanism set up by :cpp:func:`lammps_fix_external_set_force`.
|
||||
This is an alternative to the array mechanism set up by :cpp:func:`lammps_fix_external_get_force`.
|
||||
|
||||
Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
more information about how to use the fix and how to couple it with an
|
||||
@ -4913,7 +4913,7 @@ double **lammps_fix_external_get_force(void *handle, const char *id)
|
||||
\verbatim embed:rst
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and
|
||||
:cpp:func:`lammps_fix_external_set_force` to also set the contribution
|
||||
:cpp:func:`lammps_fix_external_get_force` to also set the contribution
|
||||
to the global energy from the external code.
|
||||
|
||||
Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
@ -4952,7 +4952,7 @@ void lammps_fix_external_set_energy_global(void *handle, const char *id, double
|
||||
\verbatim embed:rst
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and
|
||||
:cpp:func:`lammps_fix_external_set_force` to also set the contribution
|
||||
:cpp:func:`lammps_fix_external_get_force` to also set the contribution
|
||||
to the global virial from the external code.
|
||||
|
||||
Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
@ -4991,7 +4991,7 @@ void lammps_fix_external_set_virial_global(void *handle, const char *id, double
|
||||
\verbatim embed:rst
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and
|
||||
:cpp:func:`lammps_fix_external_set_force` to also set the contribution
|
||||
:cpp:func:`lammps_fix_external_get_force` to also set the contribution
|
||||
to the per-atom energy from the external code.
|
||||
|
||||
Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
@ -5030,7 +5030,7 @@ void lammps_fix_external_set_energy_peratom(void *handle, const char *id, double
|
||||
\verbatim embed:rst
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and
|
||||
:cpp:func:`lammps_fix_external_set_force` to also set the contribution
|
||||
:cpp:func:`lammps_fix_external_get_force` to also set the contribution
|
||||
to the per-atom virial from the external code.
|
||||
|
||||
Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
@ -5064,6 +5064,86 @@ void lammps_fix_external_set_virial_peratom(void *handle, const char *id, double
|
||||
END_CAPTURE
|
||||
}
|
||||
|
||||
/** Set the vector length for a global vector stored with fix external for analysis
|
||||
|
||||
\verbatim embed:rst
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and
|
||||
:cpp:func:`lammps_fix_external_get_force` to set the length of a global vector of
|
||||
properties that will be stored with the fix via :cpp:func:`lammps_fix_external_set_vector`.
|
||||
|
||||
Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
more information about how to use the fix and how to couple it with an
|
||||
external code.
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
* \param id fix ID of fix external instance
|
||||
* \param len length of the global vector to be stored with the fix */
|
||||
|
||||
void lammps_fix_external_set_vector_length(void *handle, const char *id, int len)
|
||||
{
|
||||
LAMMPS *lmp = (LAMMPS *) handle;
|
||||
|
||||
BEGIN_CAPTURE
|
||||
{
|
||||
int ifix = lmp->modify->find_fix(id);
|
||||
if (ifix < 0)
|
||||
lmp->error->all(FLERR,"Can not find fix with ID '{}'!", id);
|
||||
|
||||
Fix *fix = lmp->modify->fix[ifix];
|
||||
|
||||
if (strcmp("external",fix->style) != 0)
|
||||
lmp->error->all(FLERR,"Fix '{}' is not of style external!", id);
|
||||
|
||||
FixExternal *fext = (FixExternal*) fix;
|
||||
fext->set_vector_length(len);
|
||||
}
|
||||
END_CAPTURE
|
||||
}
|
||||
|
||||
/** Store global vector for a fix external instance with the given ID.
|
||||
|
||||
\verbatim embed:rst
|
||||
|
||||
This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and
|
||||
:cpp:func:`lammps_fix_external_get_force` to set the values of a global vector of
|
||||
properties that will be stored with the fix. The length of the vector
|
||||
must be set beforehand with :cpp:func:`lammps_fix_external_set_vector_length`.
|
||||
|
||||
Please see the documentation for :doc:`fix external <fix_external>` for
|
||||
more information about how to use the fix and how to couple it with an
|
||||
external code.
|
||||
|
||||
\endverbatim
|
||||
*
|
||||
* \param handle pointer to a previously created LAMMPS instance cast to ``void *``.
|
||||
* \param id fix ID of fix external instance
|
||||
* \param idx 1 based index of in global vector
|
||||
* \param val value to be stored in global vector */
|
||||
|
||||
void lammps_fix_external_set_vector(void *handle, const char *id, int idx, double val)
|
||||
{
|
||||
LAMMPS *lmp = (LAMMPS *) handle;
|
||||
|
||||
BEGIN_CAPTURE
|
||||
{
|
||||
int ifix = lmp->modify->find_fix(id);
|
||||
if (ifix < 0)
|
||||
lmp->error->all(FLERR,"Can not find fix with ID '{}'!", id);
|
||||
|
||||
Fix *fix = lmp->modify->fix[ifix];
|
||||
|
||||
if (strcmp("external",fix->style) != 0)
|
||||
lmp->error->all(FLERR,"Fix '{}' is not of style external!", id);
|
||||
|
||||
FixExternal * fext = (FixExternal*) fix;
|
||||
fext->set_vector(idx, val);
|
||||
}
|
||||
END_CAPTURE
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Free memory buffer allocated by LAMMPS.
|
||||
|
||||
@ -240,7 +240,7 @@ void lammps_fix_external_set_energy_peratom(void *handle, const char *id, double
|
||||
void lammps_fix_external_set_virial_global(void *handle, const char *id, double *virial);
|
||||
void lammps_fix_external_set_virial_peratom(void *handle, const char *id, double **virial);
|
||||
void lammps_fix_external_set_vector_length(void *handle, const char *id, int len);
|
||||
void lammps_fix_external_set_virial_peratom(void *handle, const char *id, double **val);
|
||||
void lammps_fix_external_set_vector(void *handle, const char *id, int idx, double val);
|
||||
|
||||
void lammps_free(void *ptr);
|
||||
|
||||
|
||||
@ -28,12 +28,20 @@ static void callback_one(void *handle, step_t timestep, int nlocal, tag_t *, dou
|
||||
{
|
||||
for (int i = 0; i < nlocal; ++i)
|
||||
f[i][0] = f[i][1] = f[i][2] = (double)timestep;
|
||||
if (timestep < 10)
|
||||
lammps_fix_external_set_energy_global(handle, "ext", 0.0);
|
||||
else
|
||||
lammps_fix_external_set_energy_global(handle, "ext", 1.0);
|
||||
|
||||
double v[6] = {1.0, 1.0, 1.0, 0.0, 0.0, 0.0};
|
||||
lammps_fix_external_set_virial_global(handle, "ext", v);
|
||||
if (timestep < 10) {
|
||||
lammps_fix_external_set_energy_global(handle, "ext", 0.5);
|
||||
lammps_fix_external_set_vector(handle, "ext", 1, timestep);
|
||||
lammps_fix_external_set_vector(handle, "ext", 3, 1.0);
|
||||
lammps_fix_external_set_vector(handle, "ext", 4, -0.25);
|
||||
} else {
|
||||
lammps_fix_external_set_energy_global(handle, "ext", 1.0);
|
||||
lammps_fix_external_set_vector(handle, "ext", 2, timestep);
|
||||
lammps_fix_external_set_vector(handle, "ext", 5, -1.0);
|
||||
lammps_fix_external_set_vector(handle, "ext", 6, 0.25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,11 +65,12 @@ TEST(lammps_external, callback)
|
||||
"pair_style zero 0.1\n"
|
||||
"pair_coeff 1 1\n"
|
||||
"velocity all set 0.1 0.0 -0.1\n"
|
||||
"thermo 5\n"
|
||||
"fix 1 all nve\n"
|
||||
"fix ext all external pf/callback 5 1\n"
|
||||
"thermo_style custom step temp pe ke etotal press\n"
|
||||
"thermo 5\n"
|
||||
"fix_modify ext energy yes virial yes\n");
|
||||
|
||||
lammps_fix_external_set_vector_length(handle, "ext", 6);
|
||||
output = ::testing::internal::GetCapturedStdout();
|
||||
if (verbose) std::cout << output;
|
||||
|
||||
@ -71,11 +80,19 @@ TEST(lammps_external, callback)
|
||||
double temp = lammps_get_thermo(handle, "temp");
|
||||
double pe = lammps_get_thermo(handle, "pe");
|
||||
double press = lammps_get_thermo(handle, "press");
|
||||
double val = 0.0;
|
||||
double *valp;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
valp = (double *)lammps_extract_fix(handle, "ext", LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, i, 0);
|
||||
val += *valp;
|
||||
lammps_free(valp);
|
||||
}
|
||||
output = ::testing::internal::GetCapturedStdout();
|
||||
if (verbose) std::cout << output;
|
||||
EXPECT_DOUBLE_EQ(temp, 1.0 / 30.0);
|
||||
EXPECT_DOUBLE_EQ(pe, 1.0 / 8.0);
|
||||
EXPECT_DOUBLE_EQ(press, 0.15416666666666667);
|
||||
EXPECT_DOUBLE_EQ(val, 15);
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
lammps_close(handle);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import sys,os,unittest
|
||||
from ctypes import *
|
||||
from lammps import lammps
|
||||
from lammps import lammps, LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR
|
||||
|
||||
# add timestep dependent force
|
||||
def callback_one(lmp, ntimestep, nlocal, tag, x, f):
|
||||
@ -10,8 +10,14 @@ def callback_one(lmp, ntimestep, nlocal, tag, x, f):
|
||||
f[i][2] = float(ntimestep)
|
||||
if ntimestep < 10:
|
||||
lmp.fix_external_set_energy_global("ext", 0.5)
|
||||
lmp.fix_external_set_vector("ext", 1, ntimestep)
|
||||
lmp.fix_external_set_vector("ext", 3, 1.0)
|
||||
lmp.fix_external_set_vector("ext", 4, -0.25)
|
||||
else:
|
||||
lmp.fix_external_set_energy_global("ext", 1.0)
|
||||
lmp.fix_external_set_vector("ext", 2, ntimestep)
|
||||
lmp.fix_external_set_vector("ext", 5, -1.0)
|
||||
lmp.fix_external_set_vector("ext", 6, 0.25)
|
||||
|
||||
class PythonExternal(unittest.TestCase):
|
||||
def testExternalCallback(self):
|
||||
@ -31,15 +37,22 @@ class PythonExternal(unittest.TestCase):
|
||||
pair_style zero 0.1
|
||||
pair_coeff 1 1
|
||||
velocity all set 0.1 0.0 -0.1
|
||||
thermo_style custom step temp pe ke etotal press
|
||||
thermo 5
|
||||
fix 1 all nve
|
||||
fix ext all external pf/callback 5 1
|
||||
fix_modify ext energy yes virial yes
|
||||
"""
|
||||
lmp.commands_string(basic_system)
|
||||
lmp.fix_external_set_vector_length("ext",6);
|
||||
lmp.set_fix_external_callback("ext",callback_one,lmp)
|
||||
lmp.command("run 10 post no")
|
||||
self.assertAlmostEqual(lmp.get_thermo("temp"),1.0/30.0,14)
|
||||
self.assertAlmostEqual(lmp.get_thermo("pe"),1.0/8.0,14)
|
||||
val = 0.0
|
||||
for i in range(0,6):
|
||||
val += lmp.extract_fix("ext",LMP_STYLE_GLOBAL,LMP_TYPE_VECTOR,nrow=i)
|
||||
self.assertAlmostEqual(val,15.0,14)
|
||||
|
||||
def testExternalArray(self):
|
||||
"""Test fix external from Python with pf/array"""
|
||||
|
||||
Reference in New Issue
Block a user