pylammps: make use of lammps_last_thermo
this now avoids parsing LAMMPS output to extract thermo data, but instead uses the new lammps_last_thermo library function
This commit is contained in:
@ -746,6 +746,11 @@ class lammps(object):
|
|||||||
return self.lib.lammps_get_thermo(self.lmp,name)
|
return self.lib.lammps_get_thermo(self.lmp,name)
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
@property
|
||||||
|
def last_thermo_step(self):
|
||||||
|
with ExceptionCheck(self):
|
||||||
|
ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("step".encode()), 0)
|
||||||
|
return cast(ptr, POINTER(self.c_bigint)).contents.value
|
||||||
|
|
||||||
def last_thermo(self):
|
def last_thermo(self):
|
||||||
"""Get a dictionary of the last thermodynamic output
|
"""Get a dictionary of the last thermodynamic output
|
||||||
@ -760,9 +765,7 @@ class lammps(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
rv = dict()
|
rv = dict()
|
||||||
with ExceptionCheck(self):
|
mystep = self.last_thermo_step
|
||||||
ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("step".encode()), 0)
|
|
||||||
mystep = cast(ptr, POINTER(self.c_bigint)).contents.value
|
|
||||||
if mystep < 0:
|
if mystep < 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@ -377,55 +377,6 @@ class variable_set:
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.__str__()
|
return self.__str__()
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def get_thermo_data(output):
|
|
||||||
""" traverse output of runs and extract thermo data columns """
|
|
||||||
if isinstance(output, str):
|
|
||||||
lines = output.splitlines()
|
|
||||||
else:
|
|
||||||
lines = output
|
|
||||||
|
|
||||||
runs = []
|
|
||||||
columns = []
|
|
||||||
in_run = False
|
|
||||||
current_run = {}
|
|
||||||
|
|
||||||
for line in lines:
|
|
||||||
if line.startswith("Per MPI rank memory allocation"):
|
|
||||||
in_run = True
|
|
||||||
elif in_run and len(columns) == 0:
|
|
||||||
# first line after memory usage are column names
|
|
||||||
columns = line.split()
|
|
||||||
|
|
||||||
current_run = {}
|
|
||||||
|
|
||||||
for col in columns:
|
|
||||||
current_run[col] = []
|
|
||||||
|
|
||||||
elif line.startswith("Loop time of "):
|
|
||||||
in_run = False
|
|
||||||
columns = []
|
|
||||||
thermo_data = variable_set('ThermoData', current_run)
|
|
||||||
r = {'thermo' : thermo_data }
|
|
||||||
runs.append(namedtuple('Run', list(r.keys()))(*list(r.values())))
|
|
||||||
elif in_run and len(columns) > 0:
|
|
||||||
items = line.split()
|
|
||||||
# Convert thermo output and store it.
|
|
||||||
# It must have the same number of columns and
|
|
||||||
# all of them must be convertible to floats.
|
|
||||||
# Otherwise we ignore the line
|
|
||||||
if len(items) == len(columns):
|
|
||||||
try:
|
|
||||||
values = [float(x) for x in items]
|
|
||||||
for i, col in enumerate(columns):
|
|
||||||
current_run[col].append(values[i])
|
|
||||||
except ValueError:
|
|
||||||
# cannot convert. must be a non-thermo output. ignore.
|
|
||||||
pass
|
|
||||||
|
|
||||||
return runs
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -573,6 +524,13 @@ class PyLammps(object):
|
|||||||
if self.enable_cmd_history:
|
if self.enable_cmd_history:
|
||||||
self._cmd_history.append(cmd)
|
self._cmd_history.append(cmd)
|
||||||
|
|
||||||
|
def _append_run_thermo(self, thermo):
|
||||||
|
for k, v in thermo.items():
|
||||||
|
if k in self._current_run:
|
||||||
|
self._current_run[k].append(v)
|
||||||
|
else:
|
||||||
|
self._current_run[k] = [v]
|
||||||
|
|
||||||
def run(self, *args, **kwargs):
|
def run(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Execute LAMMPS run command with given arguments
|
Execute LAMMPS run command with given arguments
|
||||||
@ -581,8 +539,25 @@ class PyLammps(object):
|
|||||||
:py:attr:`PyLammps.runs`. The latest run can be retrieved by
|
:py:attr:`PyLammps.runs`. The latest run can be retrieved by
|
||||||
:py:attr:`PyLammps.last_run`.
|
:py:attr:`PyLammps.last_run`.
|
||||||
"""
|
"""
|
||||||
|
self._current_run = {}
|
||||||
|
self._last_thermo_step = -1
|
||||||
|
def end_of_step_callback(lmp):
|
||||||
|
if self.lmp.last_thermo_step == self._last_thermo_step: return
|
||||||
|
thermo = self.lmp.last_thermo()
|
||||||
|
self._append_run_thermo(thermo)
|
||||||
|
self._last_thermo_step = thermo['Step']
|
||||||
|
|
||||||
|
import __main__
|
||||||
|
__main__._PyLammps_end_of_step_callback = end_of_step_callback
|
||||||
|
|
||||||
|
self.fix("__pylammps_internal_run_callback", "all", "python/invoke", "1", "end_of_step", "_PyLammps_end_of_step_callback")
|
||||||
output = self.__getattr__('run')(*args, **kwargs)
|
output = self.__getattr__('run')(*args, **kwargs)
|
||||||
self.runs += get_thermo_data(output)
|
self.unfix("__pylammps_internal_run_callback")
|
||||||
|
self._append_run_thermo(self.lmp.last_thermo())
|
||||||
|
|
||||||
|
thermo_data = variable_set('ThermoData', self._current_run)
|
||||||
|
r = {'thermo' : thermo_data }
|
||||||
|
self.runs.append(namedtuple('Run', list(r.keys()))(*list(r.values())))
|
||||||
return output
|
return output
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
Reference in New Issue
Block a user