Read/Write Per-Particles properties from python with lammps_extract_fix

Submitted by jorisheyman on Mon, 12/17/2012 - 17:47

Hi,

I wrote a fix similar to "fix_cfd_compute_force" that add a constant force to all atoms.
It works well when a constant force is applied at the initialization (no coupling).

I want now to access this property/atom array from python to allow coupling. There is the function "lammps_extract_fix" in library.cpp that seems to do that.

When I call it from python, I get a pointer to a pointer to a c_double (see terminal output)
However, when I try to access any value, there is an error so that the memory is not allocated. I don't understand because it seems that the function could find the "f1" fix and provides a valid pointer to its array value (if it would not find it, a NULL pointer would be set), but the pointer to the pointer seems wrong...

Python call :

v1 = lmp.extract_fix("f1", 1, 2, 1, 1)
print("v1=%s" % v1)
v2 = v1[1]
print("v2=%s" % v2)
v3= v2[0]
print("v3=%s" % v3)

Terminal Output:

Loop time of 9.53674e-07 on 1 procs for 0 steps with 30 atoms
Step Atoms KinEng 1 Volume CPU
1 30 0.0076871121 8.3995398e-07 0.0008 0
10 30 0.13298132 0.00042168989 0.0008 0.0013840199
11 30 0.13211083 0.00044754583 0.0008 0.0015540123
Loop time of 0.00156808 on 1 procs for 10 steps with 30 atoms
v1=lammps.LP_LP_c_double object at 0x9b9277c
v2=lammps.LP_c_double object at 0x9b9280c

[joris-desktop:23678] *** Process received signal ***
[joris-desktop:23678] Signal: Segmentation fault (11)
[joris-desktop:23678] Signal code: Address not mapped (1)
[joris-desktop:23678] Failing at address: 0x5f616371
[joris-desktop:23678] [ 0] [0xb779840c]
[joris-desktop:23678] [ 1] /usr/lib/python2.7/lib-dynload/_ctypes.so(+0x77b2) [0xb5ffd7b2]
[joris-desktop:23678] [ 2] python(PyEval_EvalFrameEx+0x11a4) [0x81958d4]
[joris-desktop:23678] [ 3] python(PyEval_EvalCodeEx+0x150) [0x819af70]
[joris-desktop:23678] [ 4] python(PyRun_FileExFlags+0xe1) [0x819b8a1]
[joris-desktop:23678] [ 5] python(PyRun_SimpleFileExFlags+0x21a) [0x80a8bda]
[joris-desktop:23678] [ 6] python(Py_Main+0x559) [0x80a9949]
[joris-desktop:23678] [ 7] python(main+0x1b) [0x805ea5b]
[joris-desktop:23678] [ 8] /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0xb73a74d3]
[joris-desktop:23678] [ 9] python() [0x805ea81]
[joris-desktop:23678] *** End of error message ***
Segmentation fault (core dumped)

Thanks for your help,
Joris

jorisheyman | Wed, 12/19/2012 - 08:49

ok, I found the trick. I wrote a new routine in library.cpp that extract a pointer to a property/atom vector. I add it also in the lammps.py file so that I can now access and modify the property/atome force from python.


void *lammps_extract_property(void *ptr, char *name)
{
LAMMPS *lmp = (LAMMPS *) ptr;
Fix *fix = NULL;
fix = lmp->modify->find_fix_property(name,"property/atom","vector",0,0,"cfd coupling",false);
if(fix)
{
return (void*) fix->array_atom;
}
}


def extract_property(self,name):
self.lib.lammps_extract_property.restype = POINTER(POINTER(c_double))
ptr = self.lib.lammps_extract_property(self.lmp,name)
return ptr