Merge pull request #1672 from akohlmey/dump-with-unit

Add ITEM: UNITS line to native text format dumps
This commit is contained in:
Axel Kohlmeyer 2019-09-19 10:31:13 -04:00 committed by GitHub
commit d4dbc32ba2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 347 additions and 63 deletions

View File

@ -21,7 +21,8 @@ dump ID group-ID style N file args :pre
ID = user-assigned name for the dump :ulb,l
group-ID = ID of the group of atoms to be dumped :l
style = {atom} or {atom/gz} or {atom/mpiio} or {cfg} or {cfg/gz} or {cfg/mpiio} or {custom} or {custom/gz} or {custom/mpiio} or {dcd} or {h5md} or {image} or {local} or {molfile} or {movie} or {netcdf} or {netcdf/mpiio} or {vtk} or {xtc} or {xyz} or {xyz/gz} or {xyz/mpiio} :l
style = {atom} or {atom/gz} or {atom/mpiio} or {cfg} or {cfg/gz} or
{cfg/mpiio} or {custom} or {custom/gz} or {custom/mpiio} or {dcd} or {h5md} or {image} or {local} or {local/gz} or {molfile} or {movie} or {netcdf} or {netcdf/mpiio} or {vtk} or {xtc} or {xyz} or {xyz/gz} or {xyz/mpiio} :l
N = dump every this many timesteps :l
file = name of file to write dump info to :l
args = list of arguments for a particular style :l

View File

@ -50,6 +50,7 @@ keyword = {append} or {at} or {buffer} or {delay} or {element} or {every} or {fi
{sfactor} arg = coordinate scaling factor (> 0.0)
{thermo} arg = {yes} or {no}
{tfactor} arg = time scaling factor (> 0.0)
{units} arg = {yes} or {no}
{sort} arg = {off} or {id} or N or -N
off = no sorting of per-atom lines within a snapshot
id = sort per-atom lines by atom ID
@ -620,6 +621,21 @@ threshold criterion is met. Otherwise it is not met.
:line
The {units} keyword only applies to the dump {atom}, {custom}, and
{local} styles (and their COMPRESS package versions {atom/gz},
{custom/gz} and {local/gz}). If set to {yes}, each individual dump
file will contain two extra lines at the very beginning with:
ITEM: UNITS
\<units style\> :pre
This will output the current selected "units"_units.html style
to the dump file and thus allows visualization and post-processing
tools to determine the choice of units of the data in the dump file.
The default setting is {no}.
:line
The {unwrap} keyword only applies to the dump {dcd} and {xtc} styles.
If set to {yes}, coordinates will be written "unwrapped" by the image
flags for each atom. Unwrapped means that if the atom has passed through
@ -924,6 +940,7 @@ scale = yes
sort = off for dump styles {atom}, {custom}, {cfg}, and {local}
sort = id for dump styles {dcd}, {xtc}, and {xyz}
thresh = none
units = no
unwrap = no :ul
acolor = * red/green/blue/yellow/aqua/cyan

View File

@ -108,27 +108,26 @@ void DumpAtomGZ::openfile()
void DumpAtomGZ::write_header(bigint ndump)
{
if ((multiproc) || (!multiproc && me == 0)) {
if (unit_flag && !unit_count) {
++unit_count;
gzprintf(gzFp,"ITEM: UNITS\n%s\n",update->unit_style);
}
gzprintf(gzFp,"ITEM: TIMESTEP\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",update->ntimestep);
gzprintf(gzFp,"ITEM: NUMBER OF ATOMS\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",ndump);
if (domain->triclinic == 0) {
gzprintf(gzFp,"ITEM: TIMESTEP\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",update->ntimestep);
gzprintf(gzFp,"ITEM: NUMBER OF ATOMS\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",ndump);
gzprintf(gzFp,"ITEM: BOX BOUNDS %s\n",boundstr);
gzprintf(gzFp,"%g %g\n",boxxlo,boxxhi);
gzprintf(gzFp,"%g %g\n",boxylo,boxyhi);
gzprintf(gzFp,"%g %g\n",boxzlo,boxzhi);
gzprintf(gzFp,"ITEM: ATOMS %s\n",columns);
} else {
gzprintf(gzFp,"ITEM: TIMESTEP\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",update->ntimestep);
gzprintf(gzFp,"ITEM: NUMBER OF ATOMS\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",ndump);
gzprintf(gzFp,"ITEM: BOX BOUNDS xy xz yz %s\n",boundstr);
gzprintf(gzFp,"%g %g %g\n",boxxlo,boxxhi,boxxy);
gzprintf(gzFp,"%g %g %g\n",boxylo,boxyhi,boxxz);
gzprintf(gzFp,"%g %g %g\n",boxzlo,boxzhi,boxyz);
gzprintf(gzFp,"ITEM: ATOMS %s\n",columns);
}
gzprintf(gzFp,"ITEM: ATOMS %s\n",columns);
}
}

View File

@ -108,27 +108,26 @@ void DumpCustomGZ::openfile()
void DumpCustomGZ::write_header(bigint ndump)
{
if ((multiproc) || (!multiproc && me == 0)) {
if (unit_flag && !unit_count) {
++unit_count;
gzprintf(gzFp,"ITEM: UNITS\n%s\n",update->unit_style);
}
gzprintf(gzFp,"ITEM: TIMESTEP\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",update->ntimestep);
gzprintf(gzFp,"ITEM: NUMBER OF ATOMS\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",ndump);
if (domain->triclinic == 0) {
gzprintf(gzFp,"ITEM: TIMESTEP\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",update->ntimestep);
gzprintf(gzFp,"ITEM: NUMBER OF ATOMS\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",ndump);
gzprintf(gzFp,"ITEM: BOX BOUNDS %s\n",boundstr);
gzprintf(gzFp,"%-1.16g %-1.16g\n",boxxlo,boxxhi);
gzprintf(gzFp,"%-1.16g %-1.16g\n",boxylo,boxyhi);
gzprintf(gzFp,"%-1.16g %-1.16g\n",boxzlo,boxzhi);
gzprintf(gzFp,"ITEM: ATOMS %s\n",columns);
} else {
gzprintf(gzFp,"ITEM: TIMESTEP\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",update->ntimestep);
gzprintf(gzFp,"ITEM: NUMBER OF ATOMS\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",ndump);
gzprintf(gzFp,"ITEM: BOX BOUNDS xy xz yz %s\n",boundstr);
gzprintf(gzFp,"%-1.16g %-1.16g %-1.16g\n",boxxlo,boxxhi,boxxy);
gzprintf(gzFp,"%-1.16g %-1.16g %-1.16g\n",boxylo,boxyhi,boxxz);
gzprintf(gzFp,"%-1.16g %-1.16g %-1.16g\n",boxzlo,boxzhi,boxyz);
gzprintf(gzFp,"ITEM: ATOMS %s\n",columns);
}
gzprintf(gzFp,"ITEM: ATOMS %s\n",columns);
}
}

View File

@ -0,0 +1,171 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "dump_local_gz.h"
#include "domain.h"
#include "error.h"
#include "update.h"
#include <cstring>
using namespace LAMMPS_NS;
DumpLocalGZ::DumpLocalGZ(LAMMPS *lmp, int narg, char **arg) :
DumpLocal(lmp, narg, arg)
{
gzFp = NULL;
if (!compressed)
error->all(FLERR,"Dump local/gz only writes compressed files");
}
/* ---------------------------------------------------------------------- */
DumpLocalGZ::~DumpLocalGZ()
{
if (gzFp) gzclose(gzFp);
gzFp = NULL;
fp = NULL;
}
/* ----------------------------------------------------------------------
generic opening of a dump file
ASCII or binary or gzipped
some derived classes override this function
------------------------------------------------------------------------- */
void DumpLocalGZ::openfile()
{
// single file, already opened, so just return
if (singlefile_opened) return;
if (multifile == 0) singlefile_opened = 1;
// if one file per timestep, replace '*' with current timestep
char *filecurrent = filename;
if (multiproc) filecurrent = multiname;
if (multifile) {
char *filestar = filecurrent;
filecurrent = new char[strlen(filestar) + 16];
char *ptr = strchr(filestar,'*');
*ptr = '\0';
if (padflag == 0)
sprintf(filecurrent,"%s" BIGINT_FORMAT "%s",
filestar,update->ntimestep,ptr+1);
else {
char bif[8],pad[16];
strcpy(bif,BIGINT_FORMAT);
sprintf(pad,"%%s%%0%d%s%%s",padflag,&bif[1]);
sprintf(filecurrent,pad,filestar,update->ntimestep,ptr+1);
}
*ptr = '*';
if (maxfiles > 0) {
if (numfiles < maxfiles) {
nameslist[numfiles] = new char[strlen(filecurrent)+1];
strcpy(nameslist[numfiles],filecurrent);
++numfiles;
} else {
remove(nameslist[fileidx]);
delete[] nameslist[fileidx];
nameslist[fileidx] = new char[strlen(filecurrent)+1];
strcpy(nameslist[fileidx],filecurrent);
fileidx = (fileidx + 1) % maxfiles;
}
}
}
// each proc with filewriter = 1 opens a file
if (filewriter) {
if (append_flag) {
gzFp = gzopen(filecurrent,"ab9");
} else {
gzFp = gzopen(filecurrent,"wb9");
}
if (gzFp == NULL) error->one(FLERR,"Cannot open dump file");
} else gzFp = NULL;
// delete string with timestep replaced
if (multifile) delete [] filecurrent;
}
void DumpLocalGZ::write_header(bigint ndump)
{
if ((multiproc) || (!multiproc && me == 0)) {
if (unit_flag && !unit_count) {
++unit_count;
gzprintf(gzFp,"ITEM: UNITS\n%s\n",update->unit_style);
}
gzprintf(gzFp,"ITEM: TIMESTEP\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",update->ntimestep);
gzprintf(gzFp,"ITEM: NUMBER OF ATOMS\n");
gzprintf(gzFp,BIGINT_FORMAT "\n",ndump);
if (domain->triclinic == 0) {
gzprintf(gzFp,"ITEM: BOX BOUNDS %s\n",boundstr);
gzprintf(gzFp,"%-1.16g %-1.16g\n",boxxlo,boxxhi);
gzprintf(gzFp,"%-1.16g %-1.16g\n",boxylo,boxyhi);
gzprintf(gzFp,"%-1.16g %-1.16g\n",boxzlo,boxzhi);
} else {
gzprintf(gzFp,"ITEM: BOX BOUNDS xy xz yz %s\n",boundstr);
gzprintf(gzFp,"%-1.16g %-1.16g %-1.16g\n",boxxlo,boxxhi,boxxy);
gzprintf(gzFp,"%-1.16g %-1.16g %-1.16g\n",boxylo,boxyhi,boxxz);
gzprintf(gzFp,"%-1.16g %-1.16g %-1.16g\n",boxzlo,boxzhi,boxyz);
}
gzprintf(gzFp,"ITEM: %s %s\n",label,columns);
}
}
/* ---------------------------------------------------------------------- */
void DumpLocalGZ::write_data(int n, double *mybuf)
{
if (buffer_flag == 1) {
gzwrite(gzFp,mybuf,sizeof(char)*n);
} else {
int i,j;
int m = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < size_one; j++) {
if (vtype[j] == INT)
gzprintf(gzFp,vformat[j],static_cast<int> (mybuf[m]));
else gzprintf(gzFp,vformat[j],mybuf[m]);
m++;
}
gzprintf(gzFp,"\n");
}
}
}
/* ---------------------------------------------------------------------- */
void DumpLocalGZ::write()
{
DumpLocal::write();
if (filewriter) {
if (multifile) {
gzclose(gzFp);
gzFp = NULL;
} else {
if (flush_flag)
gzflush(gzFp,Z_SYNC_FLUSH);
}
}
}

View File

@ -0,0 +1,57 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef DUMP_CLASS
DumpStyle(local/gz,DumpLocalGZ)
#else
#ifndef LMP_DUMP_LOCAL_GZ_H
#define LMP_DUMP_LOCAL_GZ_H
#include "dump_local.h"
#include <zlib.h>
namespace LAMMPS_NS {
class DumpLocalGZ : public DumpLocal {
public:
DumpLocalGZ(class LAMMPS *, int, char **);
virtual ~DumpLocalGZ();
protected:
gzFile gzFp; // file pointer for the compressed output stream
virtual void openfile();
virtual void write_header(bigint);
virtual void write_data(int, double *);
virtual void write();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Dump local/gz only writes compressed files
The dump local/gz output file name must have a .gz suffix.
E: Cannot open dump file
Self-explanatory.
*/

View File

@ -87,6 +87,8 @@ Dump::Dump(LAMMPS *lmp, int /*narg*/, char **arg) : Pointers(lmp)
buffer_flag = 0;
padflag = 0;
pbcflag = 0;
unit_flag = 0;
unit_count = 0;
delay_flag = 0;
maxfiles = -1;
@ -545,6 +547,8 @@ void Dump::openfile()
if (singlefile_opened) return;
if (multifile == 0) singlefile_opened = 1;
unit_count = 0;
// if one file per timestep, replace '*' with current timestep
char *filecurrent = filename;
@ -1119,6 +1123,13 @@ void Dump::modify_params(int narg, char **arg)
}
iarg += 2;
} else if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command");
if (strcmp(arg[iarg+1],"yes") == 0) unit_flag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) unit_flag = 0;
else error->all(FLERR,"Illegal dump_modify command");
iarg += 2;
} else {
int n = modify_param(narg-iarg,&arg[iarg]);
if (n == 0) error->all(FLERR,"Illegal dump_modify command");

View File

@ -75,6 +75,8 @@ class Dump : protected Pointers {
int sortcol; // 0 to sort on ID, 1-N on columns
int sortcolm1; // sortcol - 1
int sortorder; // ASCEND or DESCEND
int unit_flag; // 1 if dump should contain unit information
int unit_count; // # of times the unit information was written
int delay_flag; // 1 if delay output until delaystep
bigint delaystep;

View File

@ -209,6 +209,10 @@ void DumpAtom::header_binary_triclinic(bigint ndump)
void DumpAtom::header_item(bigint ndump)
{
if (unit_flag && !unit_count) {
++unit_count;
fprintf(fp,"ITEM: UNITS\n%s\n",update->unit_style);
}
fprintf(fp,"ITEM: TIMESTEP\n");
fprintf(fp,BIGINT_FORMAT "\n",update->ntimestep);
fprintf(fp,"ITEM: NUMBER OF ATOMS\n");
@ -224,6 +228,10 @@ void DumpAtom::header_item(bigint ndump)
void DumpAtom::header_item_triclinic(bigint ndump)
{
if (unit_flag && !unit_count) {
++unit_count;
fprintf(fp,"ITEM: UNITS\n%s\n",update->unit_style);
}
fprintf(fp,"ITEM: TIMESTEP\n");
fprintf(fp,BIGINT_FORMAT "\n",update->ntimestep);
fprintf(fp,"ITEM: NUMBER OF ATOMS\n");

View File

@ -420,6 +420,10 @@ void DumpCustom::header_binary_triclinic(bigint ndump)
void DumpCustom::header_item(bigint ndump)
{
if (unit_flag && !unit_count) {
++unit_count;
fprintf(fp,"ITEM: UNITS\n%s\n",update->unit_style);
}
fprintf(fp,"ITEM: TIMESTEP\n");
fprintf(fp,BIGINT_FORMAT "\n",update->ntimestep);
fprintf(fp,"ITEM: NUMBER OF ATOMS\n");
@ -435,6 +439,10 @@ void DumpCustom::header_item(bigint ndump)
void DumpCustom::header_item_triclinic(bigint ndump)
{
if (unit_flag && !unit_count) {
++unit_count;
fprintf(fp,"ITEM: UNITS\n%s\n",update->unit_style);
}
fprintf(fp,"ITEM: TIMESTEP\n");
fprintf(fp,BIGINT_FORMAT "\n",update->ntimestep);
fprintf(fp,"ITEM: NUMBER OF ATOMS\n");

View File

@ -256,6 +256,10 @@ int DumpLocal::modify_param(int narg, char **arg)
void DumpLocal::write_header(bigint ndump)
{
if (me == 0) {
if (unit_flag && !unit_count) {
++unit_count;
fprintf(fp,"ITEM: UNITS\n%s\n",update->unit_style);
}
fprintf(fp,"ITEM: TIMESTEP\n");
fprintf(fp,BIGINT_FORMAT "\n",update->ntimestep);
fprintf(fp,"ITEM: NUMBER OF %s\n",label);

View File

@ -29,7 +29,7 @@ class DumpLocal : public Dump {
DumpLocal(LAMMPS *, int, char **);
virtual ~DumpLocal();
private:
protected:
int nevery; // dump frequency to check Fix against
char *label; // string for dump file header
@ -55,11 +55,11 @@ class DumpLocal : public Dump {
void init_style();
int modify_param(int, char **);
void write_header(bigint);
virtual void write_header(bigint);
int count();
void pack(tagint *);
int convert_string(int, double *);
void write_data(int, double *);
virtual void write_data(int, double *);
void parse_fields(int, char **);
int add_compute(char *);

View File

@ -56,12 +56,19 @@ int ReaderNative::read_time(bigint &ntimestep)
char *eof = fgets(line,MAXLINE,fp);
if (eof == NULL) return 1;
// skip over unit information, if present.
if (strstr(line,"ITEM: UNITS") == line)
read_lines(2);
if (strstr(line,"ITEM: TIMESTEP") != line)
error->one(FLERR,"Dump file is incorrectly formatted");
read_lines(1);
int rv = sscanf(line,BIGINT_FORMAT,&ntimestep);
if (rv != 1)
error->one(FLERR,"Dump file is incorrectly formatted");
return 0;
}

View File

@ -99,9 +99,9 @@ int main(int narg, char **arg)
// detect end-of-file
if (feof(fp)) {
fclose(fp);
fclose(fptxt);
break;
fclose(fp);
fclose(fptxt);
break;
}
fread(&natoms,sizeof(bigint),1,fp);
@ -114,13 +114,13 @@ int main(int narg, char **arg)
fread(&zlo,sizeof(double),1,fp);
fread(&zhi,sizeof(double),1,fp);
if (triclinic) {
fread(&xy,sizeof(double),1,fp);
fread(&xz,sizeof(double),1,fp);
fread(&yz,sizeof(double),1,fp);
fread(&xy,sizeof(double),1,fp);
fread(&xz,sizeof(double),1,fp);
fread(&yz,sizeof(double),1,fp);
}
fread(&size_one,sizeof(int),1,fp);
fread(&nchunk,sizeof(int),1,fp);
fprintf(fptxt,"ITEM: TIMESTEP\n");
fprintf(fptxt,BIGINT_FORMAT "\n",ntimestep);
fprintf(fptxt,"ITEM: NUMBER OF ATOMS\n");
@ -128,26 +128,26 @@ int main(int narg, char **arg)
m = 0;
for (int idim = 0; idim < 3; idim++) {
for (int iside = 0; iside < 2; iside++) {
if (boundary[idim][iside] == 0) boundstr[m++] = 'p';
else if (boundary[idim][iside] == 1) boundstr[m++] = 'f';
else if (boundary[idim][iside] == 2) boundstr[m++] = 's';
else if (boundary[idim][iside] == 3) boundstr[m++] = 'm';
}
boundstr[m++] = ' ';
for (int iside = 0; iside < 2; iside++) {
if (boundary[idim][iside] == 0) boundstr[m++] = 'p';
else if (boundary[idim][iside] == 1) boundstr[m++] = 'f';
else if (boundary[idim][iside] == 2) boundstr[m++] = 's';
else if (boundary[idim][iside] == 3) boundstr[m++] = 'm';
}
boundstr[m++] = ' ';
}
boundstr[8] = '\0';
if (!triclinic) {
fprintf(fptxt,"ITEM: BOX BOUNDS %s\n",boundstr);
fprintf(fptxt,"%g %g\n",xlo,xhi);
fprintf(fptxt,"%g %g\n",ylo,yhi);
fprintf(fptxt,"%g %g\n",zlo,zhi);
fprintf(fptxt,"ITEM: BOX BOUNDS %s\n",boundstr);
fprintf(fptxt,"%g %g\n",xlo,xhi);
fprintf(fptxt,"%g %g\n",ylo,yhi);
fprintf(fptxt,"%g %g\n",zlo,zhi);
} else {
fprintf(fptxt,"ITEM: BOX BOUNDS %s xy xz yz\n",boundstr);
fprintf(fptxt,"%g %g %g\n",xlo,xhi,xy);
fprintf(fptxt,"%g %g %g\n",ylo,yhi,xz);
fprintf(fptxt,"%g %g %g\n",zlo,zhi,yz);
fprintf(fptxt,"ITEM: BOX BOUNDS %s xy xz yz\n",boundstr);
fprintf(fptxt,"%g %g %g\n",xlo,xhi,xy);
fprintf(fptxt,"%g %g %g\n",ylo,yhi,xz);
fprintf(fptxt,"%g %g %g\n",zlo,zhi,yz);
}
fprintf(fptxt,"ITEM: ATOMS\n");
@ -156,25 +156,25 @@ int main(int narg, char **arg)
// loop over processor chunks in file
for (i = 0; i < nchunk; i++) {
fread(&n,sizeof(int),1,fp);
fread(&n,sizeof(int),1,fp);
// extend buffer to fit chunk size
if (n > maxbuf) {
if (buf) delete [] buf;
buf = new double[n];
maxbuf = n;
}
// extend buffer to fit chunk size
// read chunk and write as size_one values per line
if (n > maxbuf) {
if (buf) delete [] buf;
buf = new double[n];
maxbuf = n;
}
fread(buf,sizeof(double),n,fp);
n /= size_one;
m = 0;
for (j = 0; j < n; j++) {
for (k = 0; k < size_one; k++) fprintf(fptxt,"%g ",buf[m++]);
fprintf(fptxt,"\n");
}
// read chunk and write as size_one values per line
fread(buf,sizeof(double),n,fp);
n /= size_one;
m = 0;
for (j = 0; j < n; j++) {
for (k = 0; k < size_one; k++) fprintf(fptxt,"%g ",buf[m++]);
fprintf(fptxt,"\n");
}
}
printf(" " BIGINT_FORMAT,ntimestep);