Merge pull request #3197 from akohlmey/custom-thermo-headers
add support for custom header keywords with thermo output and dump styles
This commit is contained in:
@ -79,6 +79,10 @@ This data can be extracted and parsed from a log file using python with:
|
||||
.. code-block:: python
|
||||
|
||||
import re, yaml
|
||||
try:
|
||||
from yaml import CSafeLoader as Loader, CSafeDumper as Dumper
|
||||
except ImportError:
|
||||
from yaml import SafeLoader as Loader, SafeDumper as Dumper
|
||||
|
||||
docs = ""
|
||||
with open("log.lammps") as f:
|
||||
@ -86,7 +90,7 @@ This data can be extracted and parsed from a log file using python with:
|
||||
m = re.search(r"^(keywords:.*$|data:$|---$|\.\.\.$| - \[.*\]$)", line)
|
||||
if m: docs += m.group(0) + '\n'
|
||||
|
||||
thermo = list(yaml.load_all(docs, Loader=yaml.SafeLoader))
|
||||
thermo = list(yaml.load_all(docs, Loader=Loader))
|
||||
|
||||
print("Number of runs: ", len(thermo))
|
||||
print(thermo[1]['keywords'][4], ' = ', thermo[1]['data'][2][4])
|
||||
|
||||
@ -26,6 +26,10 @@ Syntax
|
||||
N = index of frame written upon first dump
|
||||
*balance* arg = *yes* or *no*
|
||||
*buffer* arg = *yes* or *no*
|
||||
*colname* values = ID string, or *default*
|
||||
string = new column header name
|
||||
ID = integer from 1 to N, or integer from -1 to -N, where N = # of quantities being output
|
||||
*or* a custom dump keyword or reference to compute, fix, property or variable.
|
||||
*delay* arg = Dstep
|
||||
Dstep = delay output until this timestep
|
||||
*element* args = E1 E2 ... EN, where N = # of atom types
|
||||
@ -40,9 +44,10 @@ Syntax
|
||||
Np = write one file for every this many processors
|
||||
*first* arg = *yes* or *no*
|
||||
*flush* arg = *yes* or *no*
|
||||
*format* args = *line* string, *int* string, *float* string, M string, or *none*
|
||||
*format* args = *line* string, *int* string, *float* string, ID string, or *none*
|
||||
string = C-style format string
|
||||
M = integer from 1 to N, where N = # of per-atom quantities being output
|
||||
ID = integer from 1 to N, or integer from -1 to -N, where N = # of quantities being output
|
||||
*or* a custom dump keyword or reference to compute, fix, property or variable.
|
||||
*header* arg = *yes* or *no*
|
||||
*yes* to write the header
|
||||
*no* to not write the header
|
||||
@ -375,6 +380,29 @@ performed with dump style *xtc*\ .
|
||||
|
||||
----------
|
||||
|
||||
The *colname* keyword can be used to change the default header keyword
|
||||
for dump styles: *atom*, *custom*, and *cfg* and their compressed, ADIOS,
|
||||
and MPIIO variants. The setting for *ID string* replaces the default
|
||||
text with the provided string. *ID* can be a positive integer when it
|
||||
represents the column number counting from the left, a negative integer
|
||||
when it represents the column number from the right (i.e. -1 is the last
|
||||
column/keyword), or a custom dump keyword (or compute, fix, property, or
|
||||
variable reference) and then it replaces the string for that specific
|
||||
keyword. For *atom* dump styles only the keywords "id", "type", "x",
|
||||
"y", "z", "ix", "iy", "iz" can be accessed via string regardless of
|
||||
whether scaled or unwrapped coordinates were enabled or disabled, and
|
||||
it always assumes 8 columns for indexing regardless of whether image
|
||||
flags are enabled or not. For dump style *cfg* only the "auxiliary"
|
||||
keywords (6th or later keyword) may be changed and the column indexing
|
||||
considers only them (i.e. the 6th keyword is the the 1st column).
|
||||
|
||||
The *colname* keyword can be used multiple times. If multiple *colname*
|
||||
settings refer to the same keyword, the last setting has precedence. A
|
||||
setting of *default* clears all previous settings, reverting all values
|
||||
to their default names.
|
||||
|
||||
----------
|
||||
|
||||
The *format* keyword can be used to change the default numeric format output
|
||||
by the text-based dump styles: *atom*, *local*, *custom*, *cfg*, and
|
||||
*xyz* styles, and their MPIIO variants. Only the *line* or *none*
|
||||
|
||||
@ -474,7 +474,7 @@ list on GPUs. This can be faster in some cases (e.g. ReaxFF HNS
|
||||
benchmark) but slower in others (e.g. Lennard Jones benchmark). The
|
||||
copy between different memory layouts is done out of place and
|
||||
therefore doubles the memory overhead of the neigh list, which can be
|
||||
signicant.
|
||||
significant.
|
||||
|
||||
The *newton* keyword sets the Newton flags for pairwise and bonded
|
||||
interactions to *off* or *on*, the same as the :doc:`newton <newton>`
|
||||
|
||||
@ -21,9 +21,14 @@ Syntax
|
||||
*norm* value = *yes* or *no*
|
||||
*flush* value = *yes* or *no*
|
||||
*line* value = *one* or *multi* or *yaml*
|
||||
*format* values = *line* string, *int* string, *float* string, M string, or *none*
|
||||
*colname* values = ID string, or *default*
|
||||
string = new column header name
|
||||
ID = integer from 1 to N, or integer from -1 to -N, where N = # of quantities being output
|
||||
*or* a thermo keyword or reference to compute, fix, property or variable.
|
||||
*format* values = *line* string, *int* string, *float* string, ID string, or *none*
|
||||
string = C-style format string
|
||||
M = integer from 1 to N, where N = # of quantities being output
|
||||
ID = integer from 1 to N, or integer from -1 to -N, where N = # of quantities being output
|
||||
*or* a thermo keyword or reference to compute, fix, property or variable.
|
||||
*temp* value = compute ID that calculates a temperature
|
||||
*press* value = compute ID that calculates a pressure
|
||||
|
||||
@ -36,7 +41,8 @@ Examples
|
||||
thermo_modify temp myTemp format 3 %15.8g
|
||||
thermo_modify temp myTemp format line "%ld %g %g %15.8g"
|
||||
thermo_modify line multi format float %g
|
||||
themos_modify line yaml format none
|
||||
thermo_modify line yaml format none
|
||||
thermo_modify colname 1 Timestep colname -2 Pressure colname f_1[1] AvgDensity
|
||||
|
||||
Description
|
||||
"""""""""""
|
||||
@ -147,6 +153,20 @@ containing the timestep and CPU time ("multi"), or in a YAML format
|
||||
block ("yaml"). This modify option overrides the *one*, *multi*, or
|
||||
*yaml* thermo_style settings.
|
||||
|
||||
The *colname* keyword can be used to change the default header keyword
|
||||
for a column or field of thermodynamic output. The setting for *ID
|
||||
string* replaces the default text with the provided string. *ID* can be
|
||||
a positive integer when it represents the column number counting from
|
||||
the left, a negative integer when it represents the column number from
|
||||
the right (i.e. -1 is the last column/keyword), or a thermo keyword (or
|
||||
compute, fix, property, or variable reference) and then it replaces the
|
||||
string for that specific thermo keyword.
|
||||
|
||||
The *colname* keyword can be used multiple times. If multiple *colname*
|
||||
settings refer to the same keyword, the last setting has precedence. A
|
||||
setting of *default* clears all previous settings, reverting all values
|
||||
to their default values.
|
||||
|
||||
The *format* keyword can be used to change the default numeric format of
|
||||
any of quantities the :doc:`thermo_style <thermo_style>` command
|
||||
outputs. All the specified format strings are C-style formats, e.g. as
|
||||
@ -155,12 +175,16 @@ argument which is the format string for the entire line of thermo
|
||||
output, with N fields, which you must enclose in quotes if it is more
|
||||
than one field. The *int* and *float* keywords take a single format
|
||||
argument and are applied to all integer or floating-point quantities
|
||||
output. The setting for *M string* also takes a single format argument
|
||||
which is used for the Mth value output in each line, e.g. the fifth
|
||||
column is output in high precision for "format 5 %20.15g".
|
||||
output. The setting for *ID string* also takes a single format argument
|
||||
which is used for the indexed value in each line. The interpretation is
|
||||
the same as for *colname*, i.e. a positive integer is the n-th value
|
||||
corresponding to the n-th thermo keyword, a negative integer is counting
|
||||
backwards, and a string matches the entry with the thermo keyword.,
|
||||
e.g. the fifth column is output in high precision for "format 5 %20.15g"
|
||||
and the pair energy for "format epair %20.15g".
|
||||
|
||||
The *format* keyword can be used multiple times. The precedence is
|
||||
that for each value in a line of output, the *M* format (if specified)
|
||||
that for each value in a line of output, the *ID* format (if specified)
|
||||
is used, else the *int* or *float* setting (if specified) is used,
|
||||
else the *line* setting (if specified) for that value is used, else
|
||||
the default setting is used. A setting of *none* clears all previous
|
||||
@ -173,9 +197,10 @@ settings, reverting all values to their default format.
|
||||
When specifying the *format int* option you can use a "%d"-style
|
||||
format identifier in the format string and LAMMPS will convert this
|
||||
to the corresponding 8-byte form when it is applied to those
|
||||
keywords. However, when specifying the *line* option or *format M
|
||||
keywords. However, when specifying the *line* option or *format ID
|
||||
string* option for *step* and *natoms*, you should specify a format
|
||||
string appropriate for an 8-byte signed integer, e.g. one with "%ld".
|
||||
string appropriate for an 8-byte signed integer, e.g. one with "%ld"
|
||||
or "%lld" depending on the platform.
|
||||
|
||||
The *temp* keyword is used to determine how thermodynamic temperature is
|
||||
calculated, which is used by all thermo quantities that require a
|
||||
|
||||
@ -1789,6 +1789,7 @@ Liu
|
||||
Livermore
|
||||
lj
|
||||
llammps
|
||||
lld
|
||||
LLVM
|
||||
lm
|
||||
lmp
|
||||
|
||||
@ -118,6 +118,7 @@ ttm: two-temeperature model examples
|
||||
vashishta: models using the Vashishta potential
|
||||
voronoi: Voronoi tesselation via compute voronoi/atom command
|
||||
wall: use of reflective walls with different stochastic models
|
||||
yaml: demonstrates use of yaml thermo and dump styles
|
||||
|
||||
Here is how you might run and visualize one of the sample problems:
|
||||
|
||||
|
||||
37
examples/yaml/in.yaml
Normal file
37
examples/yaml/in.yaml
Normal file
@ -0,0 +1,37 @@
|
||||
# 3d Lennard-Jones melt
|
||||
|
||||
variable x index 1
|
||||
variable y index 1
|
||||
variable z index 1
|
||||
|
||||
variable xx equal 20*$x
|
||||
variable yy equal 20*$y
|
||||
variable zz equal 20*$z
|
||||
|
||||
units lj
|
||||
atom_style atomic
|
||||
|
||||
lattice fcc 0.8442
|
||||
region box block 0 ${xx} 0 ${yy} 0 ${zz}
|
||||
create_box 1 box
|
||||
create_atoms 1 box
|
||||
mass 1 1.0
|
||||
|
||||
velocity all create 1.44 87287 loop geom
|
||||
|
||||
pair_style lj/cut 2.5
|
||||
pair_coeff 1 1 1.0 1.0 2.5
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 0 every 20 check no
|
||||
|
||||
fix 1 all nve
|
||||
thermo_style yaml
|
||||
thermo 10
|
||||
|
||||
dump 1 all yaml 25 dump.yaml id type x y z ix iy iz vx vy vz
|
||||
dump_modify 1 sort id thermo yes units yes time yes format 1 %5d format float "% 12.8e" format int %2d
|
||||
|
||||
run 100
|
||||
|
||||
run 100
|
||||
151
examples/yaml/log.7Apr22.yaml.g++.1
Normal file
151
examples/yaml/log.7Apr22.yaml.g++.1
Normal file
@ -0,0 +1,151 @@
|
||||
LAMMPS (24 Mar 2022)
|
||||
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98)
|
||||
using 1 OpenMP thread(s) per MPI task
|
||||
# 3d Lennard-Jones melt
|
||||
|
||||
variable x index 1
|
||||
variable y index 1
|
||||
variable z index 1
|
||||
|
||||
variable xx equal 20*$x
|
||||
variable xx equal 20*1
|
||||
variable yy equal 20*$y
|
||||
variable yy equal 20*1
|
||||
variable zz equal 20*$z
|
||||
variable zz equal 20*1
|
||||
|
||||
units lj
|
||||
atom_style atomic
|
||||
|
||||
lattice fcc 0.8442
|
||||
Lattice spacing in x,y,z = 1.6795962 1.6795962 1.6795962
|
||||
region box block 0 ${xx} 0 ${yy} 0 ${zz}
|
||||
region box block 0 20 0 ${yy} 0 ${zz}
|
||||
region box block 0 20 0 20 0 ${zz}
|
||||
region box block 0 20 0 20 0 20
|
||||
create_box 1 box
|
||||
Created orthogonal box = (0 0 0) to (33.591924 33.591924 33.591924)
|
||||
1 by 1 by 1 MPI processor grid
|
||||
create_atoms 1 box
|
||||
Created 32000 atoms
|
||||
using lattice units in orthogonal box = (0 0 0) to (33.591924 33.591924 33.591924)
|
||||
create_atoms CPU = 0.003 seconds
|
||||
mass 1 1.0
|
||||
|
||||
velocity all create 1.44 87287 loop geom
|
||||
|
||||
pair_style lj/cut 2.5
|
||||
pair_coeff 1 1 1.0 1.0 2.5
|
||||
|
||||
neighbor 0.3 bin
|
||||
neigh_modify delay 0 every 20 check no
|
||||
|
||||
fix 1 all nve
|
||||
thermo_style yaml
|
||||
thermo 10
|
||||
|
||||
dump 1 all yaml 25 dump.yaml id type x y z ix iy iz vx vy vz
|
||||
dump_modify 1 sort id thermo yes units yes time yes format 1 %5d format float "% 12.8e" format int %2d
|
||||
|
||||
run 100
|
||||
generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
|
||||
Neighbor list info ...
|
||||
update every 20 steps, delay 0 steps, check no
|
||||
max neighbors/atom: 2000, page size: 100000
|
||||
master list distance cutoff = 2.8
|
||||
ghost atom cutoff = 2.8
|
||||
binsize = 1.4, bins = 24 24 24
|
||||
1 neighbor lists, perpetual/occasional/extra = 1 0 0
|
||||
(1) pair lj/cut, perpetual
|
||||
attributes: half, newton on
|
||||
pair build: half/bin/atomonly/newton
|
||||
stencil: half/bin/3d
|
||||
bin: standard
|
||||
Per MPI rank memory allocation (min/avg/max) = 20.56 | 20.56 | 20.56 Mbytes
|
||||
---
|
||||
keywords: [Step, Temp, KinEng, PotEng, E_bond, E_angle, E_dihed, E_impro, E_vdwl, E_coul, E_long, Press, ]
|
||||
data:
|
||||
- [0, 1.44000000000001, 2.15993250000001, -6.77336805323422, 0, 0, 0, 0, -6.77336805323422, 0, 0, -5.01970725908556, ]
|
||||
- [10, 1.12539487029313, 1.68803955255514, -6.30005271976029, 0, 0, 0, 0, -6.30005271976029, 0, 0, -2.55968522600129, ]
|
||||
- [20, 0.625793798302192, 0.938661363368992, -5.55655653922756, 0, 0, 0, 0, -5.55655653922756, 0, 0, 0.973517658007722, ]
|
||||
- [30, 0.745927295413064, 1.11885597777762, -5.73951278150759, 0, 0, 0, 0, -5.73951278150759, 0, 0, 0.339284096694852, ]
|
||||
- [40, 0.731026217827733, 1.09650505988764, -5.71764564663628, 0, 0, 0, 0, -5.71764564663628, 0, 0, 0.388973418756238, ]
|
||||
- [50, 0.740091517740786, 1.11010258482128, -5.73150426762886, 0, 0, 0, 0, -5.73150426762886, 0, 0, 0.335273324523691, ]
|
||||
- [60, 0.750500641591031, 1.12571578266897, -5.74713299283555, 0, 0, 0, 0, -5.74713299283555, 0, 0, 0.26343139026926, ]
|
||||
- [70, 0.755436366857812, 1.13311913920702, -5.75480059117447, 0, 0, 0, 0, -5.75480059117447, 0, 0, 0.224276619217515, ]
|
||||
- [80, 0.759974280364828, 1.13992579675285, -5.76187162670983, 0, 0, 0, 0, -5.76187162670983, 0, 0, 0.191626237124102, ]
|
||||
- [90, 0.760464250735042, 1.14066072934081, -5.76280209529731, 0, 0, 0, 0, -5.76280209529731, 0, 0, 0.189478083345243, ]
|
||||
- [100, 0.757453103239936, 1.13614414924569, -5.75850548601596, 0, 0, 0, 0, -5.75850548601596, 0, 0, 0.207261053624723, ]
|
||||
...
|
||||
Loop time of 1.89046 on 1 procs for 100 steps with 32000 atoms
|
||||
|
||||
Performance: 22851.622 tau/day, 52.897 timesteps/s
|
||||
99.6% CPU use with 1 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 1.2896 | 1.2896 | 1.2896 | 0.0 | 68.22
|
||||
Neigh | 0.17687 | 0.17687 | 0.17687 | 0.0 | 9.36
|
||||
Comm | 0.014543 | 0.014543 | 0.014543 | 0.0 | 0.77
|
||||
Output | 0.37678 | 0.37678 | 0.37678 | 0.0 | 19.93
|
||||
Modify | 0.028638 | 0.028638 | 0.028638 | 0.0 | 1.51
|
||||
Other | | 0.003975 | | | 0.21
|
||||
|
||||
Nlocal: 32000 ave 32000 max 32000 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 19657 ave 19657 max 19657 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 1.20283e+06 ave 1.20283e+06 max 1.20283e+06 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 1202833
|
||||
Ave neighs/atom = 37.588531
|
||||
Neighbor list builds = 5
|
||||
Dangerous builds not checked
|
||||
|
||||
run 100
|
||||
generated 0 of 0 mixed pair_coeff terms from geometric mixing rule
|
||||
Per MPI rank memory allocation (min/avg/max) = 20.57 | 20.57 | 20.57 Mbytes
|
||||
---
|
||||
keywords: [Step, Temp, KinEng, PotEng, E_bond, E_angle, E_dihed, E_impro, E_vdwl, E_coul, E_long, Press, ]
|
||||
data:
|
||||
- [100, 0.757453103239935, 1.13614414924569, -5.7585054860159, 0, 0, 0, 0, -5.7585054860159, 0, 0, 0.207261053624721, ]
|
||||
- [110, 0.759322359337036, 1.13894794576996, -5.7614668389562, 0, 0, 0, 0, -5.7614668389562, 0, 0, 0.194314975399602, ]
|
||||
- [120, 0.759372342462676, 1.13902291811546, -5.76149365656489, 0, 0, 0, 0, -5.76149365656489, 0, 0, 0.191600048851267, ]
|
||||
- [130, 0.756833027516501, 1.13521406472659, -5.75777334823494, 0, 0, 0, 0, -5.75777334823494, 0, 0, 0.208792327853067, ]
|
||||
- [140, 0.759725426691298, 1.13955252790757, -5.76208910746081, 0, 0, 0, 0, -5.76208910746081, 0, 0, 0.193895435346637, ]
|
||||
- [150, 0.760545839455106, 1.14078310859643, -5.7633284876011, 0, 0, 0, 0, -5.7633284876011, 0, 0, 0.187959630462945, ]
|
||||
- [160, 0.758404626168493, 1.13757138903589, -5.76023198892283, 0, 0, 0, 0, -5.76023198892283, 0, 0, 0.19692107984108, ]
|
||||
- [170, 0.758880300638885, 1.13828487844424, -5.76103232235402, 0, 0, 0, 0, -5.76103232235402, 0, 0, 0.197653518549842, ]
|
||||
- [180, 0.753691827878246, 1.13050241251294, -5.75304767384283, 0, 0, 0, 0, -5.75304767384283, 0, 0, 0.237041776410937, ]
|
||||
- [190, 0.757361226563721, 1.13600633853809, -5.75852399133222, 0, 0, 0, 0, -5.75852399133222, 0, 0, 0.219529562657488, ]
|
||||
- [200, 0.759531750132731, 1.13926202214831, -5.76188923485725, 0, 0, 0, 0, -5.76188923485725, 0, 0, 0.209105747192796, ]
|
||||
...
|
||||
Loop time of 1.93916 on 1 procs for 100 steps with 32000 atoms
|
||||
|
||||
Performance: 22277.687 tau/day, 51.569 timesteps/s
|
||||
99.4% CPU use with 1 MPI tasks x 1 OpenMP threads
|
||||
|
||||
MPI task timing breakdown:
|
||||
Section | min time | avg time | max time |%varavg| %total
|
||||
---------------------------------------------------------------
|
||||
Pair | 1.3292 | 1.3292 | 1.3292 | 0.0 | 68.55
|
||||
Neigh | 0.18317 | 0.18317 | 0.18317 | 0.0 | 9.45
|
||||
Comm | 0.013626 | 0.013626 | 0.013626 | 0.0 | 0.70
|
||||
Output | 0.38206 | 0.38206 | 0.38206 | 0.0 | 19.70
|
||||
Modify | 0.027034 | 0.027034 | 0.027034 | 0.0 | 1.39
|
||||
Other | | 0.004028 | | | 0.21
|
||||
|
||||
Nlocal: 32000 ave 32000 max 32000 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Nghost: 19570 ave 19570 max 19570 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
Neighs: 1.19982e+06 ave 1.19982e+06 max 1.19982e+06 min
|
||||
Histogram: 1 0 0 0 0 0 0 0 0 0
|
||||
|
||||
Total # of neighbors = 1199821
|
||||
Ave neighs/atom = 37.494406
|
||||
Neighbor list builds = 5
|
||||
Dangerous builds not checked
|
||||
Total wall time: 0:00:04
|
||||
@ -14,14 +14,19 @@
|
||||
################################################################################
|
||||
# LAMMPS output formats
|
||||
# Written by Richard Berger <richard.berger@temple.edu>
|
||||
# and Axel Kohlmeyer <akohlmey@gmail.com>
|
||||
################################################################################
|
||||
|
||||
import re
|
||||
import re, yaml
|
||||
try:
|
||||
from yaml import CSafeLoader as Loader, CSafeDumper as Dumper
|
||||
except ImportError:
|
||||
from yaml import SafeLoader as Loader, SafeDumper as Dumper
|
||||
|
||||
class LogFile:
|
||||
"""Reads LAMMPS log files and extracts the thermo information
|
||||
|
||||
It supports both the default thermo output style (including custom) and multi.
|
||||
It supports the line, multi, and yaml thermo output styles.
|
||||
|
||||
:param filename: path to log file
|
||||
:type filename: str
|
||||
@ -33,11 +38,13 @@ class LogFile:
|
||||
|
||||
STYLE_DEFAULT = 0
|
||||
STYLE_MULTI = 1
|
||||
STYLE_YAML = 2
|
||||
|
||||
def __init__(self, filename):
|
||||
alpha = re.compile(r'[a-df-zA-DF-Z]') # except e or E for floating-point numbers
|
||||
kvpairs = re.compile(r'([a-zA-Z_0-9]+)\s+=\s*([0-9\.eE\-]+)')
|
||||
style = LogFile.STYLE_DEFAULT
|
||||
yamllog = ""
|
||||
self.runs = []
|
||||
self.errors = []
|
||||
with open(filename, 'rt') as f:
|
||||
@ -46,14 +53,33 @@ class LogFile:
|
||||
for line in f:
|
||||
if "ERROR" in line or "exited on signal" in line:
|
||||
self.errors.append(line)
|
||||
elif line.startswith('Step '):
|
||||
|
||||
elif re.match(r'^ *Step ', line):
|
||||
in_thermo = True
|
||||
in_data_section = True
|
||||
keys = line.split()
|
||||
current_run = {}
|
||||
for k in keys:
|
||||
current_run[k] = []
|
||||
elif line.startswith('---------------- Step'):
|
||||
|
||||
elif re.match(r'^(keywords:.*$|data:$|---$| - \[.*\]$)', line):
|
||||
style = LogFile.STYLE_YAML
|
||||
yamllog += line;
|
||||
current_run = {}
|
||||
|
||||
elif re.match(r'^\.\.\.$', line):
|
||||
thermo = yaml.load(yamllog, Loader=Loader)
|
||||
for k in thermo['keywords']:
|
||||
current_run[k] = []
|
||||
for step in thermo['data']:
|
||||
icol = 0
|
||||
for k in thermo['keywords']:
|
||||
current_run[k].append(step[icol])
|
||||
icol += 1
|
||||
self.runs.append(current_run)
|
||||
yamllog = ""
|
||||
|
||||
elif re.match(r'^------* Step ', line):
|
||||
if not in_thermo:
|
||||
current_run = {'Step': [], 'CPU': []}
|
||||
in_thermo = True
|
||||
@ -64,28 +90,29 @@ class LogFile:
|
||||
cpu = float(str_cpu.split('=')[1].split()[0])
|
||||
current_run["Step"].append(step)
|
||||
current_run["CPU"].append(cpu)
|
||||
|
||||
elif line.startswith('Loop time of'):
|
||||
in_thermo = False
|
||||
self.runs.append(current_run)
|
||||
if style != LogFile.STYLE_YAML:
|
||||
self.runs.append(current_run)
|
||||
|
||||
elif in_thermo and in_data_section:
|
||||
if style == LogFile.STYLE_DEFAULT:
|
||||
if alpha.search(line):
|
||||
continue
|
||||
|
||||
for k, v in zip(keys, map(float, line.split())):
|
||||
current_run[k].append(v)
|
||||
|
||||
elif style == LogFile.STYLE_MULTI:
|
||||
if '=' not in line:
|
||||
in_data_section = False
|
||||
continue
|
||||
|
||||
for k,v in kvpairs.findall(line):
|
||||
if k not in current_run:
|
||||
current_run[k] = [float(v)]
|
||||
else:
|
||||
current_run[k].append(float(v))
|
||||
|
||||
|
||||
class AvgChunkFile:
|
||||
"""Reads files generated by fix ave/chunk
|
||||
|
||||
|
||||
@ -238,6 +238,9 @@ void DumpAtomADIOS::init_style()
|
||||
columnNames = {"id", "type", "xs", "ys", "zs", "ix", "iy", "iz"};
|
||||
}
|
||||
|
||||
for (int icol = 0; icol < (int)columnNames.size(); ++icol)
|
||||
if (keyword_user[icol].size()) columnNames[icol] = keyword_user[icol];
|
||||
|
||||
// setup function ptrs
|
||||
|
||||
if (scale_flag == 1 && image_flag == 0 && domain->triclinic == 0)
|
||||
|
||||
@ -214,6 +214,19 @@ void DumpCustomADIOS::write()
|
||||
|
||||
void DumpCustomADIOS::init_style()
|
||||
{
|
||||
// assemble column string from defaults and user values
|
||||
|
||||
delete[] columns;
|
||||
std::string combined;
|
||||
int icol = 0;
|
||||
for (auto item : utils::split_words(columns_default)) {
|
||||
if (combined.size()) combined += " ";
|
||||
if (keyword_user[icol].size()) combined += keyword_user[icol];
|
||||
else combined += item;
|
||||
++icol;
|
||||
}
|
||||
columns = utils::strdup(combined);
|
||||
|
||||
// setup boundary string
|
||||
|
||||
domain->boundary_string(boundstr);
|
||||
|
||||
@ -234,14 +234,25 @@ void DumpAtomMPIIO::init_style()
|
||||
|
||||
// setup column string
|
||||
|
||||
std::string default_columns;
|
||||
|
||||
if (scale_flag == 0 && image_flag == 0)
|
||||
columns = (char *) "id type x y z";
|
||||
default_columns = "id type x y z";
|
||||
else if (scale_flag == 0 && image_flag == 1)
|
||||
columns = (char *) "id type x y z ix iy iz";
|
||||
default_columns = "id type x y z ix iy iz";
|
||||
else if (scale_flag == 1 && image_flag == 0)
|
||||
columns = (char *) "id type xs ys zs";
|
||||
default_columns = "id type xs ys zs";
|
||||
else if (scale_flag == 1 && image_flag == 1)
|
||||
columns = (char *) "id type xs ys zs ix iy iz";
|
||||
default_columns = "id type xs ys zs ix iy iz";
|
||||
|
||||
int icol = 0;
|
||||
columns.clear();
|
||||
for (auto item : utils::split_words(default_columns)) {
|
||||
if (columns.size()) columns += " ";
|
||||
if (keyword_user[icol].size()) columns += keyword_user[icol];
|
||||
else columns += item;
|
||||
++icol;
|
||||
}
|
||||
|
||||
// setup function ptrs
|
||||
|
||||
|
||||
@ -39,17 +39,6 @@ using namespace LAMMPS_NS;
|
||||
#define DUMP_BUF_CHUNK_SIZE 16384
|
||||
#define DUMP_BUF_INCREMENT_SIZE 4096
|
||||
|
||||
// clang-format off
|
||||
enum{ ID, MOL, TYPE, ELEMENT, MASS,
|
||||
X, Y, Z, XS, YS, ZS, XSTRI, YSTRI, ZSTRI, XU, YU, ZU, XUTRI, YUTRI, ZUTRI,
|
||||
XSU, YSU, ZSU, XSUTRI, YSUTRI, ZSUTRI,
|
||||
IX, IY, IZ, VX, VY, VZ, FX, FY, FZ,
|
||||
Q, MUX, MUY, MUZ, MU, RADIUS, DIAMETER,
|
||||
OMEGAX, OMEGAY, OMEGAZ, ANGMOMX, ANGMOMY, ANGMOMZ,
|
||||
TQX, TQY, TQZ, SPIN, ERADIUS, ERVEL, ERFORCE,
|
||||
COMPUTE, FIX, VARIABLE };
|
||||
enum{ LT, LE, GT, GE, EQ, NEQ };
|
||||
// clang-format on
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
DumpCustomMPIIO::DumpCustomMPIIO(LAMMPS *lmp, int narg, char **arg)
|
||||
@ -216,6 +205,19 @@ void DumpCustomMPIIO::write()
|
||||
|
||||
void DumpCustomMPIIO::init_style()
|
||||
{
|
||||
// assemble ITEMS: column string from defaults and user values
|
||||
|
||||
delete[] columns;
|
||||
std::string combined;
|
||||
int icol = 0;
|
||||
for (auto item : utils::split_words(columns_default)) {
|
||||
if (combined.size()) combined += " ";
|
||||
if (keyword_user[icol].size()) combined += keyword_user[icol];
|
||||
else combined += item;
|
||||
++icol;
|
||||
}
|
||||
columns = utils::strdup(combined);
|
||||
|
||||
// format = copy of default or user-specified line format
|
||||
|
||||
delete[] format;
|
||||
|
||||
@ -38,17 +38,6 @@ using namespace LAMMPS_NS;
|
||||
#define DUMP_BUF_CHUNK_SIZE 16384
|
||||
#define DUMP_BUF_INCREMENT_SIZE 4096
|
||||
|
||||
enum{ID,MOL,TYPE,ELEMENT,MASS,
|
||||
X,Y,Z,XS,YS,ZS,XSTRI,YSTRI,ZSTRI,XU,YU,ZU,XUTRI,YUTRI,ZUTRI,
|
||||
XSU,YSU,ZSU,XSUTRI,YSUTRI,ZSUTRI,
|
||||
IX,IY,IZ,
|
||||
VX,VY,VZ,FX,FY,FZ,
|
||||
Q,MUX,MUY,MUZ,MU,RADIUS,DIAMETER,
|
||||
OMEGAX,OMEGAY,OMEGAZ,ANGMOMX,ANGMOMY,ANGMOMZ,
|
||||
TQX,TQY,TQZ,SPIN,ERADIUS,ERVEL,ERFORCE,
|
||||
COMPUTE,FIX,VARIABLE};
|
||||
enum{LT,LE,GT,GE,EQ,NEQ};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
DumpXYZMPIIO::DumpXYZMPIIO(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
@ -356,7 +356,9 @@ void FixPOEMS::init()
|
||||
for (auto ifix : modify->get_fix_list()) {
|
||||
if (utils::strmatch(ifix->style, "^poems")) pflag = true;
|
||||
if (pflag && (ifix->setmask() & POST_FORCE) && !ifix->rigid_flag)
|
||||
if (comm->me == 0) error->warning(FLERR, "Fix {} alters forces after fix poems", ifix->id);
|
||||
if (comm->me == 0)
|
||||
error->warning(FLERR,"Fix {} with ID {} alters forces after fix poems",
|
||||
ifix->style, ifix->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -693,7 +693,8 @@ void FixRigid::init()
|
||||
for (auto ifix : modify->get_fix_list()) {
|
||||
if (ifix->rigid_flag) rflag = true;
|
||||
if ((comm->me == 0) && rflag && (ifix->setmask() & POST_FORCE) && !ifix->rigid_flag)
|
||||
error->warning(FLERR,"Fix {} alters forces after fix rigid", ifix->id);
|
||||
error->warning(FLERR,"Fix {} with ID {} alters forces after fix rigid",
|
||||
ifix->style, ifix->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -538,7 +538,8 @@ void FixRigidSmall::init()
|
||||
for (auto ifix : modify->get_fix_list()) {
|
||||
if (ifix->rigid_flag) rflag = true;
|
||||
if ((comm->me == 0) && rflag && (ifix->setmask() & POST_FORCE) && !ifix->rigid_flag)
|
||||
error->warning(FLERR,"Fix {} alters forces after fix rigid", ifix->id);
|
||||
error->warning(FLERR,"Fix {} with ID {} alters forces after fix rigid/small",
|
||||
ifix->style, ifix->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
66
src/dump.cpp
66
src/dump.cpp
@ -150,19 +150,19 @@ Dump::Dump(LAMMPS *lmp, int /*narg*/, char **arg) : Pointers(lmp)
|
||||
|
||||
Dump::~Dump()
|
||||
{
|
||||
delete [] id;
|
||||
delete [] style;
|
||||
delete [] filename;
|
||||
delete [] multiname;
|
||||
delete[] id;
|
||||
delete[] style;
|
||||
delete[] filename;
|
||||
delete[] multiname;
|
||||
|
||||
delete [] format;
|
||||
delete [] format_default;
|
||||
delete [] format_line_user;
|
||||
delete [] format_float_user;
|
||||
delete [] format_int_user;
|
||||
delete [] format_bigint_user;
|
||||
delete[] format;
|
||||
delete[] format_default;
|
||||
delete[] format_line_user;
|
||||
delete[] format_float_user;
|
||||
delete[] format_int_user;
|
||||
delete[] format_bigint_user;
|
||||
|
||||
delete [] refresh;
|
||||
delete[] refresh;
|
||||
|
||||
// format_column_user is deallocated by child classes that use it
|
||||
|
||||
@ -1019,7 +1019,7 @@ void Dump::balance()
|
||||
memory->destroy(tmp);
|
||||
memory->destroy(proc_offsets);
|
||||
memory->destroy(proc_new_offsets);
|
||||
delete [] request;
|
||||
delete[] request;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -1059,7 +1059,7 @@ void Dump::modify_params(int narg, char **arg)
|
||||
if (strcmp(id,output->dump[idump]->id) == 0) break;
|
||||
int n;
|
||||
if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) {
|
||||
delete [] output->var_dump[idump];
|
||||
delete[] output->var_dump[idump];
|
||||
output->var_dump[idump] = utils::strdup(&arg[iarg+1][2]);
|
||||
n = 0;
|
||||
} else {
|
||||
@ -1077,7 +1077,7 @@ void Dump::modify_params(int narg, char **arg)
|
||||
if (strcmp(id,output->dump[idump]->id) == 0) break;
|
||||
double delta;
|
||||
if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) {
|
||||
delete [] output->var_dump[idump];
|
||||
delete[] output->var_dump[idump];
|
||||
output->var_dump[idump] = utils::strdup(&arg[iarg+1][2]);
|
||||
delta = 0.0;
|
||||
} else {
|
||||
@ -1107,7 +1107,7 @@ void Dump::modify_params(int narg, char **arg)
|
||||
MPI_Comm_free(&clustercomm);
|
||||
MPI_Comm_split(world,icluster,0,&clustercomm);
|
||||
|
||||
delete [] multiname;
|
||||
delete[] multiname;
|
||||
char *ptr = strchr(filename,'%');
|
||||
*ptr = '\0';
|
||||
multiname = utils::strdup(fmt::format("{}{}{}", filename, icluster, ptr+1));
|
||||
@ -1124,14 +1124,38 @@ void Dump::modify_params(int narg, char **arg)
|
||||
flush_flag = utils::logical(FLERR,arg[iarg+1],false,lmp);
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"colname") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command");
|
||||
if (strcmp(arg[iarg+1],"default") == 0) {
|
||||
for (auto item : keyword_user) item.clear();
|
||||
iarg += 2;
|
||||
} else {
|
||||
if (iarg+3 > narg) error->all(FLERR,"Illegal dump_modify command");
|
||||
int icol = -1;
|
||||
if (utils::is_integer(arg[iarg + 1])) {
|
||||
icol = utils::inumeric(FLERR,arg[iarg + 1],false,lmp);
|
||||
if (icol < 0) icol = keyword_user.size() + icol + 1;
|
||||
icol--;
|
||||
} else {
|
||||
try {
|
||||
icol = key2col.at(arg[iarg + 1]);
|
||||
} catch (std::out_of_range &) {
|
||||
icol = -1;
|
||||
}
|
||||
}
|
||||
if ((icol < 0) || (icol >= (int)keyword_user.size()))
|
||||
error->all(FLERR, "Illegal thermo_modify command");
|
||||
keyword_user[icol] = arg[iarg+2];
|
||||
iarg += 3;
|
||||
}
|
||||
} else if (strcmp(arg[iarg],"format") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command");
|
||||
|
||||
if (strcmp(arg[iarg+1],"none") == 0) {
|
||||
delete [] format_line_user;
|
||||
delete [] format_int_user;
|
||||
delete [] format_bigint_user;
|
||||
delete [] format_float_user;
|
||||
delete[] format_line_user;
|
||||
delete[] format_int_user;
|
||||
delete[] format_bigint_user;
|
||||
delete[] format_float_user;
|
||||
format_line_user = nullptr;
|
||||
format_int_user = nullptr;
|
||||
format_bigint_user = nullptr;
|
||||
@ -1146,7 +1170,7 @@ void Dump::modify_params(int narg, char **arg)
|
||||
if (iarg+3 > narg) error->all(FLERR,"Illegal dump_modify command");
|
||||
|
||||
if (strcmp(arg[iarg+1],"line") == 0) {
|
||||
delete [] format_line_user;
|
||||
delete[] format_line_user;
|
||||
format_line_user = utils::strdup(arg[iarg+2]);
|
||||
iarg += 3;
|
||||
} else { // pass other format options to child classes
|
||||
@ -1204,7 +1228,7 @@ void Dump::modify_params(int narg, char **arg)
|
||||
MPI_Comm_free(&clustercomm);
|
||||
MPI_Comm_split(world,icluster,0,&clustercomm);
|
||||
|
||||
delete [] multiname;
|
||||
delete[] multiname;
|
||||
char *ptr = strchr(filename,'%');
|
||||
*ptr = '\0';
|
||||
multiname = utils::strdup(fmt::format("{}{}{}", filename, icluster, ptr+1));
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
|
||||
#include "pointers.h" // IWYU pragma: export
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class Dump : protected Pointers {
|
||||
@ -100,6 +102,8 @@ class Dump : protected Pointers {
|
||||
char *format_bigint_user;
|
||||
char **format_column_user;
|
||||
enum { INT, DOUBLE, STRING, BIGINT };
|
||||
std::map<std::string, int> key2col;
|
||||
std::vector<std::string> keyword_user;
|
||||
|
||||
FILE *fp; // file to write dump to
|
||||
int size_one; // # of quantities for one atom
|
||||
|
||||
@ -38,6 +38,9 @@ DumpAtom::DumpAtom(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg)
|
||||
buffer_allow = 1;
|
||||
buffer_flag = 1;
|
||||
format_default = nullptr;
|
||||
key2col = { { "id", 0 }, { "type", 1 }, { "x", 2 }, { "y", 3 },
|
||||
{ "z", 4 }, { "ix", 5 }, { "iy", 6 }, { "iz", 7 } };
|
||||
keyword_user = { "", "", "", "", "", "", "", "" };
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -64,14 +67,25 @@ void DumpAtom::init_style()
|
||||
|
||||
// setup column string
|
||||
|
||||
std::string default_columns;
|
||||
|
||||
if (scale_flag == 0 && image_flag == 0)
|
||||
columns = (char *) "id type x y z";
|
||||
default_columns = "id type x y z";
|
||||
else if (scale_flag == 0 && image_flag == 1)
|
||||
columns = (char *) "id type x y z ix iy iz";
|
||||
default_columns = "id type x y z ix iy iz";
|
||||
else if (scale_flag == 1 && image_flag == 0)
|
||||
columns = (char *) "id type xs ys zs";
|
||||
default_columns = "id type xs ys zs";
|
||||
else if (scale_flag == 1 && image_flag == 1)
|
||||
columns = (char *) "id type xs ys zs ix iy iz";
|
||||
default_columns = "id type xs ys zs ix iy iz";
|
||||
|
||||
int icol = 0;
|
||||
columns.clear();
|
||||
for (auto item : utils::split_words(default_columns)) {
|
||||
if (columns.size()) columns += " ";
|
||||
if (keyword_user[icol].size()) columns += keyword_user[icol];
|
||||
else columns += item;
|
||||
++icol;
|
||||
}
|
||||
|
||||
// setup function ptrs
|
||||
|
||||
@ -201,9 +215,9 @@ void DumpAtom::header_unit_style_binary()
|
||||
|
||||
void DumpAtom::header_columns_binary()
|
||||
{
|
||||
int len = strlen(columns);
|
||||
int len = columns.size();
|
||||
fwrite(&len, sizeof(int), 1, fp);
|
||||
fwrite(columns, sizeof(char), len, fp);
|
||||
fwrite(columns.c_str(), sizeof(char), len, fp);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -301,7 +315,7 @@ void DumpAtom::header_item(bigint ndump)
|
||||
fprintf(fp,"%-1.16e %-1.16e\n",boxxlo,boxxhi);
|
||||
fprintf(fp,"%-1.16e %-1.16e\n",boxylo,boxyhi);
|
||||
fprintf(fp,"%-1.16e %-1.16e\n",boxzlo,boxzhi);
|
||||
fprintf(fp,"ITEM: ATOMS %s\n",columns);
|
||||
fprintf(fp,"ITEM: ATOMS %s\n",columns.c_str());
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -322,7 +336,7 @@ void DumpAtom::header_item_triclinic(bigint ndump)
|
||||
fprintf(fp,"%-1.16e %-1.16e %-1.16e\n",boxxlo,boxxhi,boxxy);
|
||||
fprintf(fp,"%-1.16e %-1.16e %-1.16e\n",boxylo,boxyhi,boxxz);
|
||||
fprintf(fp,"%-1.16e %-1.16e %-1.16e\n",boxzlo,boxzhi,boxyz);
|
||||
fprintf(fp,"ITEM: ATOMS %s\n",columns);
|
||||
fprintf(fp,"ITEM: ATOMS %s\n",columns.c_str());
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
@ -36,7 +36,7 @@ class DumpAtom : public Dump {
|
||||
int scale_flag; // 1 if atom coords are scaled, 0 if no
|
||||
int image_flag; // 1 if append box count to atom coords, 0 if no
|
||||
|
||||
char *columns; // column labels
|
||||
std::string columns; // column labels
|
||||
|
||||
void init_style() override;
|
||||
int modify_param(int, char **) override;
|
||||
|
||||
@ -53,26 +53,26 @@ DumpCFG::DumpCFG(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
if (strcmp(earg[2],"xs") == 0) {
|
||||
if (strcmp(earg[3],"ysu") == 0 || strcmp(earg[4],"zsu") == 0)
|
||||
error->all(FLERR,
|
||||
"Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu");
|
||||
error->all(FLERR,"Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu");
|
||||
unwrapflag = 0;
|
||||
} else {
|
||||
if (strcmp(earg[3],"ys") == 0 || strcmp(earg[4],"zs") == 0)
|
||||
error->all(FLERR,
|
||||
"Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu");
|
||||
error->all(FLERR,"Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu");
|
||||
unwrapflag = 1;
|
||||
}
|
||||
|
||||
// setup auxiliary property name strings
|
||||
// convert 'X_ID[m]' (X=c,f,v) to 'X_ID_m'
|
||||
|
||||
if (nfield > 5) auxname = new char*[nfield];
|
||||
if (nfield > 5) auxname = new char*[nfield-5];
|
||||
else auxname = nullptr;
|
||||
|
||||
int i = 0;
|
||||
key2col.clear();
|
||||
keyword_user.resize(nfield-5);
|
||||
for (int iarg = 5; iarg < nfield; iarg++, i++) {
|
||||
ArgInfo argi(earg[iarg],ArgInfo::COMPUTE|ArgInfo::FIX|ArgInfo::VARIABLE
|
||||
|ArgInfo::DNAME|ArgInfo::INAME);
|
||||
ArgInfo argi(earg[iarg],ArgInfo::COMPUTE|ArgInfo::FIX|ArgInfo::VARIABLE|
|
||||
ArgInfo::DNAME|ArgInfo::INAME);
|
||||
|
||||
if (argi.get_dim() == 1) {
|
||||
std::string newarg = fmt::format("{}_{}_{}", earg[iarg][0], argi.get_name(), argi.get_index1());
|
||||
@ -80,6 +80,8 @@ DumpCFG::DumpCFG(LAMMPS *lmp, int narg, char **arg) :
|
||||
} else {
|
||||
auxname[i] = utils::strdup(earg[iarg]);
|
||||
}
|
||||
key2col[earg[iarg]] = i;
|
||||
keyword_user[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,8 +90,8 @@ DumpCFG::DumpCFG(LAMMPS *lmp, int narg, char **arg) :
|
||||
DumpCFG::~DumpCFG()
|
||||
{
|
||||
if (auxname) {
|
||||
for (int i = 0; i < nfield-5; i++) delete [] auxname[i];
|
||||
delete [] auxname;
|
||||
for (int i = 0; i < nfield-5; i++) delete[] auxname[i];
|
||||
delete[] auxname;
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,8 +138,12 @@ void DumpCFG::write_header(bigint n)
|
||||
fprintf(fp,"H0(3,3) = %g A\n",domain->zprd);
|
||||
fprintf(fp,".NO_VELOCITY.\n");
|
||||
fprintf(fp,"entry_count = %d\n",nfield-2);
|
||||
for (int i = 0; i < nfield-5; i++)
|
||||
fprintf(fp,"auxiliary[%d] = %s\n",i,auxname[i]);
|
||||
for (int i = 0; i < nfield-5; i++) {
|
||||
if (keyword_user[i].size())
|
||||
fprintf(fp,"auxiliary[%d] = %s\n",i,keyword_user[i].c_str());
|
||||
else
|
||||
fprintf(fp,"auxiliary[%d] = %s\n",i,auxname[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@ -55,14 +55,11 @@ enum{LT,LE,GT,GE,EQ,NEQ,XOR};
|
||||
DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) :
|
||||
Dump(lmp, narg, arg),
|
||||
idregion(nullptr), thresh_array(nullptr), thresh_op(nullptr), thresh_value(nullptr),
|
||||
thresh_last(nullptr), thresh_fix(nullptr),
|
||||
thresh_fixID(nullptr), thresh_first(nullptr),
|
||||
earg(nullptr), vtype(nullptr), vformat(nullptr), columns(nullptr), choose(nullptr),
|
||||
dchoose(nullptr), clist(nullptr), field2index(nullptr),
|
||||
argindex(nullptr), id_compute(nullptr),
|
||||
compute(nullptr), id_fix(nullptr), fix(nullptr),
|
||||
id_variable(nullptr), variable(nullptr),
|
||||
vbuf(nullptr), id_custom(nullptr), custom(nullptr), custom_flag(nullptr),
|
||||
thresh_last(nullptr), thresh_fix(nullptr), thresh_fixID(nullptr), thresh_first(nullptr),
|
||||
earg(nullptr), vtype(nullptr), vformat(nullptr), columns(nullptr), columns_default(nullptr),
|
||||
choose(nullptr), dchoose(nullptr), clist(nullptr), field2index(nullptr), argindex(nullptr),
|
||||
id_compute(nullptr), compute(nullptr), id_fix(nullptr), fix(nullptr), id_variable(nullptr),
|
||||
variable(nullptr), vbuf(nullptr), id_custom(nullptr), custom(nullptr), custom_flag(nullptr),
|
||||
typenames(nullptr), pack_choice(nullptr)
|
||||
{
|
||||
if (narg == 5) error->all(FLERR,"No dump custom arguments specified");
|
||||
@ -180,13 +177,14 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) :
|
||||
// setup column string
|
||||
|
||||
cols.clear();
|
||||
keyword_user.resize(nfield);
|
||||
for (int iarg = 0; iarg < nfield; iarg++) {
|
||||
key2col[earg[iarg]] = iarg;
|
||||
keyword_user[iarg].clear();
|
||||
if (cols.size()) cols += " ";
|
||||
cols += earg[iarg];
|
||||
cols += " ";
|
||||
}
|
||||
// remove trailing blank and copy
|
||||
cols.resize(cols.size()-1);
|
||||
columns = utils::strdup(cols);
|
||||
columns_default = utils::strdup(cols);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -257,6 +255,7 @@ DumpCustom::~DumpCustom()
|
||||
delete[] format_column_user;
|
||||
}
|
||||
|
||||
delete[] columns_default;
|
||||
delete[] columns;
|
||||
}
|
||||
|
||||
@ -264,6 +263,19 @@ DumpCustom::~DumpCustom()
|
||||
|
||||
void DumpCustom::init_style()
|
||||
{
|
||||
// assemble ITEMS: column string from defaults and user values
|
||||
|
||||
delete[] columns;
|
||||
std::string combined;
|
||||
int icol = 0;
|
||||
for (auto item : utils::split_words(columns_default)) {
|
||||
if (combined.size()) combined += " ";
|
||||
if (keyword_user[icol].size()) combined += keyword_user[icol];
|
||||
else combined += item;
|
||||
++icol;
|
||||
}
|
||||
columns = utils::strdup(combined);
|
||||
|
||||
// format = copy of default or user-specified line format
|
||||
|
||||
delete[] format;
|
||||
|
||||
@ -60,6 +60,7 @@ class DumpCustom : public Dump {
|
||||
char **vformat; // format string for each vector element
|
||||
//
|
||||
char *columns; // column labels
|
||||
char *columns_default;
|
||||
//
|
||||
int nchoose; // # of selected atoms
|
||||
int maxlocal; // size of atom selection and variable arrays
|
||||
|
||||
@ -249,11 +249,11 @@ void Modify::init()
|
||||
|
||||
for (i = 0; i < nfix; i++)
|
||||
if (!fix[i]->dynamic_group_allow && group->dynamic[fix[i]->igroup])
|
||||
error->all(FLERR, "Fix {} does not allow use with a dynamic group", fix[i]->id);
|
||||
error->all(FLERR, "Fix {} does not allow use with a dynamic group", fix[i]->style);
|
||||
|
||||
for (i = 0; i < ncompute; i++)
|
||||
if (!compute[i]->dynamic_group_allow && group->dynamic[compute[i]->igroup])
|
||||
error->all(FLERR, "Compute {} does not allow use with a dynamic group", compute[i]->id);
|
||||
error->all(FLERR, "Compute {} does not allow use with a dynamic group", compute[i]->style);
|
||||
|
||||
// warn if any particle is time integrated more than once
|
||||
|
||||
|
||||
@ -252,8 +252,12 @@ void Thermo::init()
|
||||
format[i] += format_this + " ";
|
||||
else if (lineflag == YAMLLINE)
|
||||
format[i] += format_this + ", ";
|
||||
else
|
||||
format[i] += fmt::format("{:<8} = {} ", keyword[i], format_this);
|
||||
else {
|
||||
if (keyword_user[i].size())
|
||||
format[i] += fmt::format("{:<8} = {} ", keyword_user[i], format_this);
|
||||
else
|
||||
format[i] += fmt::format("{:<8} = {} ", keyword[i], format_this);
|
||||
}
|
||||
}
|
||||
|
||||
// chop off trailing blank or add closing bracket if needed and then add newline
|
||||
@ -324,11 +328,13 @@ void Thermo::header()
|
||||
std::string hdr;
|
||||
if (lineflag == YAMLLINE) hdr = "---\nkeywords: [";
|
||||
for (int i = 0; i < nfield; i++) {
|
||||
auto head = keyword[i];
|
||||
if (keyword_user[i].size()) head = keyword_user[i];
|
||||
if (lineflag == ONELINE) {
|
||||
if (vtype[i] == FLOAT)
|
||||
hdr += fmt::format("{:^14} ", keyword[i]);
|
||||
hdr += fmt::format("{:^14} ", head);
|
||||
else if ((vtype[i] == INT) || (vtype[i] == BIGINT))
|
||||
hdr += fmt::format("{:^11} ", keyword[i]);
|
||||
hdr += fmt::format("{:^11} ", head);
|
||||
} else if (lineflag == YAMLLINE) {
|
||||
hdr += keyword[i];
|
||||
hdr += ", ";
|
||||
@ -622,6 +628,29 @@ void Thermo::modify_params(int narg, char **arg)
|
||||
error->all(FLERR, "Illegal thermo_modify command");
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg], "colname") == 0) {
|
||||
if (iarg + 2 > narg) error->all(FLERR, "Illegal thermo_modify command");
|
||||
if (strcmp(arg[iarg + 1], "default") == 0) {
|
||||
for (auto item : keyword_user) item.clear();
|
||||
iarg += 2;
|
||||
} else {
|
||||
if (iarg + 3 > narg) error->all(FLERR, "Illegal thermo_modify command");
|
||||
int icol = -1;
|
||||
if (utils::is_integer(arg[iarg + 1])) {
|
||||
icol = utils::inumeric(FLERR,arg[iarg + 1],false,lmp);
|
||||
if (icol < 0) icol = nfield_initial + icol + 1;
|
||||
icol--;
|
||||
} else {
|
||||
try {
|
||||
icol = key2col.at(arg[iarg + 1]);
|
||||
} catch (std::out_of_range &) {
|
||||
icol = -1;
|
||||
}
|
||||
}
|
||||
if ((icol < 0) || (icol >= nfield_initial)) error->all(FLERR, "Illegal thermo_modify command");
|
||||
keyword_user[icol] = arg[iarg+2];
|
||||
iarg += 3;
|
||||
}
|
||||
} else if (strcmp(arg[iarg], "format") == 0) {
|
||||
if (iarg + 2 > narg) error->all(FLERR, "Illegal thermo_modify command");
|
||||
|
||||
@ -630,7 +659,7 @@ void Thermo::modify_params(int narg, char **arg)
|
||||
format_int_user.clear();
|
||||
format_bigint_user.clear();
|
||||
format_float_user.clear();
|
||||
for (int i = 0; i < nfield_initial + 1; ++i) format_column_user[i].clear();
|
||||
for (auto item : format_column_user) item.clear();
|
||||
iarg += 2;
|
||||
continue;
|
||||
}
|
||||
@ -646,14 +675,24 @@ void Thermo::modify_params(int narg, char **arg)
|
||||
found = format_int_user.find('d', found);
|
||||
if (found == std::string::npos)
|
||||
error->all(FLERR, "Thermo_modify int format does not contain a d conversion character");
|
||||
format_bigint_user =
|
||||
format_int_user.replace(found, 1, std::string(BIGINT_FORMAT).substr(1));
|
||||
format_bigint_user = format_int_user.replace(found, 1, std::string(BIGINT_FORMAT).substr(1));
|
||||
} else if (strcmp(arg[iarg + 1], "float") == 0) {
|
||||
format_float_user = arg[iarg + 2];
|
||||
} else {
|
||||
int i = utils::inumeric(FLERR, arg[iarg + 1], false, lmp) - 1;
|
||||
if (i < 0 || i >= nfield_initial + 1) error->all(FLERR, "Illegal thermo_modify command");
|
||||
format_column_user[i] = arg[iarg + 2];
|
||||
int icol = -1;
|
||||
if (utils::is_integer(arg[iarg + 1])) {
|
||||
icol = utils::inumeric(FLERR, arg[iarg + 1], false, lmp);
|
||||
if (icol < 0) icol = nfield_initial + icol + 1;
|
||||
icol--;
|
||||
} else {
|
||||
try {
|
||||
icol = key2col.at(arg[iarg + 1]);
|
||||
} catch (std::out_of_range &) {
|
||||
icol = -1;
|
||||
}
|
||||
}
|
||||
if (icol < 0 || icol >= nfield_initial + 1) error->all(FLERR, "Illegal thermo_modify command");
|
||||
format_column_user[icol] = arg[iarg + 2];
|
||||
}
|
||||
iarg += 3;
|
||||
|
||||
@ -675,10 +714,12 @@ void Thermo::allocate()
|
||||
keyword.resize(n);
|
||||
format.resize(n);
|
||||
format_column_user.resize(n);
|
||||
keyword_user.resize(n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
keyword[i].clear();
|
||||
format[i].clear();
|
||||
format_column_user[i].clear();
|
||||
keyword_user[i].clear();
|
||||
}
|
||||
|
||||
vfunc = new FnPtr[n];
|
||||
@ -702,6 +743,12 @@ void Thermo::allocate()
|
||||
nvariable = 0;
|
||||
id_variable = new char *[n];
|
||||
variables = new int[n];
|
||||
|
||||
int i = 0;
|
||||
key2col.clear();
|
||||
for (auto item : utils::split_words(line)) {
|
||||
key2col[item] = i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#define LMP_THERMO_H
|
||||
|
||||
#include "pointers.h"
|
||||
#include <map>
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
@ -47,8 +48,9 @@ class Thermo : protected Pointers {
|
||||
int nfield, nfield_initial;
|
||||
int *vtype;
|
||||
std::string line;
|
||||
std::vector<std::string> keyword, format, format_column_user;
|
||||
std::vector<std::string> keyword, format, format_column_user, keyword_user;
|
||||
std::string format_line_user, format_float_user, format_int_user, format_bigint_user;
|
||||
std::map<std::string, int> key2col;
|
||||
|
||||
int normvalue; // use this for normflag unless natoms = 0
|
||||
int normuserflag; // 0 if user has not set, 1 if has
|
||||
|
||||
@ -7,6 +7,7 @@ EXAMPLES_DIR=os.path.abspath(os.path.join(__file__, '..', '..', '..', 'examples'
|
||||
DEFAULT_STYLE_EXAMPLE_LOG="melt/log.8Apr21.melt.g++.1"
|
||||
MULTI_STYLE_EXAMPLE_LOG="peptide/log.27Nov18.peptide.g++.1"
|
||||
AVG_CHUNK_FILE="VISCOSITY/profile.13Oct16.nemd.2d.g++.1"
|
||||
YAML_STYLE_EXAMPLE_LOG="yaml/log.7Apr22.yaml.g++.1"
|
||||
|
||||
class Logfiles(unittest.TestCase):
|
||||
def testLogFileNotFound(self):
|
||||
@ -58,6 +59,27 @@ class Logfiles(unittest.TestCase):
|
||||
|
||||
self.assertEqual(run0["Step"], list(range(0,350, 50)))
|
||||
|
||||
def testYamlLogFile(self):
|
||||
log = LogFile(os.path.join(EXAMPLES_DIR, YAML_STYLE_EXAMPLE_LOG))
|
||||
self.assertEqual(len(log.runs), 2)
|
||||
run = log.runs[0]
|
||||
self.assertEqual(len(run.keys()), 12)
|
||||
self.assertIn("Step", run)
|
||||
self.assertIn("Temp", run)
|
||||
self.assertIn("E_vdwl", run)
|
||||
self.assertIn("E_coul", run)
|
||||
self.assertIn("E_bond", run)
|
||||
self.assertIn("E_angle", run)
|
||||
self.assertIn("Press", run)
|
||||
self.assertEqual(len(run["Step"]), 11)
|
||||
self.assertEqual(len(run["Temp"]), 11)
|
||||
self.assertEqual(len(run["E_vdwl"]), 11)
|
||||
self.assertEqual(len(run["E_coul"]), 11)
|
||||
self.assertEqual(len(run["E_bond"]), 11)
|
||||
self.assertEqual(len(run["E_angle"]), 11)
|
||||
self.assertEqual(len(run["Press"]), 11)
|
||||
self.assertEqual(log.runs[0]["Step"], [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
|
||||
|
||||
|
||||
class AvgChunkFiles(unittest.TestCase):
|
||||
def testAvgChunkFileNotFound(self):
|
||||
|
||||
Reference in New Issue
Block a user