From d04f428c1af11ef6381e1fc940a7c777428294e6 Mon Sep 17 00:00:00 2001 From: Luthaf Date: Fri, 17 Dec 2021 10:54:43 +0100 Subject: [PATCH 01/13] netcdf: default to float variable for everything The standard convention require all values to be stored as float, users still have the ability to use double with `dump_modify double yes` --- src/NETCDF/dump_netcdf.cpp | 25 +++++++++++++------------ src/NETCDF/dump_netcdf.h | 2 +- src/NETCDF/dump_netcdf_mpiio.cpp | 24 +++++++++++++----------- src/NETCDF/dump_netcdf_mpiio.h | 2 +- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index 5f30c941ca..2ad952e885 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -181,7 +181,7 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : int_buffer = nullptr; double_buffer = nullptr; - double_precision = false; + type_nc_real = NC_FLOAT; thermo = false; thermovar = nullptr; @@ -381,14 +381,14 @@ void DumpNetCDF::openfile() NCERRX( nc_def_var(ncid, NC_CELL_ANGULAR_STR, NC_CHAR, 2, dims, &cell_angular_var), NC_CELL_ANGULAR_STR ); dims[0] = frame_dim; - NCERRX( nc_def_var(ncid, NC_TIME_STR, NC_DOUBLE, 1, dims, &time_var), NC_TIME_STR); + NCERRX( nc_def_var(ncid, NC_TIME_STR, type_nc_real, 1, dims, &time_var), NC_TIME_STR); dims[0] = frame_dim; dims[1] = cell_spatial_dim; - NCERRX( nc_def_var(ncid, NC_CELL_ORIGIN_STR, NC_DOUBLE, 2, dims, &cell_origin_var), NC_CELL_ORIGIN_STR ); - NCERRX( nc_def_var(ncid, NC_CELL_LENGTHS_STR, NC_DOUBLE, 2, dims, &cell_lengths_var), NC_CELL_LENGTHS_STR ); + NCERRX( nc_def_var(ncid, NC_CELL_ORIGIN_STR, type_nc_real, 2, dims, &cell_origin_var), NC_CELL_ORIGIN_STR ); + NCERRX( nc_def_var(ncid, NC_CELL_LENGTHS_STR, type_nc_real, 2, dims, &cell_lengths_var), NC_CELL_LENGTHS_STR ); dims[0] = frame_dim; dims[1] = cell_angular_dim; - NCERRX( nc_def_var(ncid, NC_CELL_ANGLES_STR, NC_DOUBLE, 2, dims, &cell_angles_var), NC_CELL_ANGLES_STR ); + NCERRX( nc_def_var(ncid, NC_CELL_ANGLES_STR, type_nc_real, 2, dims, &cell_angles_var), NC_CELL_ANGLES_STR ); // variables specified in the input file dims[0] = frame_dim; @@ -397,7 +397,6 @@ void DumpNetCDF::openfile() for (int i = 0; i < n_perat; i++) { nc_type xtype; - // Type mangling if (vtype[perat[i].field[0]] == Dump::INT) { xtype = NC_INT; @@ -406,10 +405,7 @@ void DumpNetCDF::openfile() } else if (vtype[perat[i].field[0]] == Dump::STRING) { error->all(FLERR,"Dump netcdf currently does not support dumping string properties"); } else { - if (double_precision) - xtype = NC_DOUBLE; - else - xtype = NC_FLOAT; + xtype = type_nc_real; } if (perat[i].constant) { @@ -437,7 +433,7 @@ void DumpNetCDF::openfile() Thermo *th = output->thermo; for (int i = 0; i < th->nfield; i++) { if (th->vtype[i] == Thermo::FLOAT) { - NCERRX( nc_def_var(ncid, th->keyword[i], NC_DOUBLE, 1, dims, + NCERRX( nc_def_var(ncid, th->keyword[i], type_nc_real, 1, dims, &thermovar[i]), th->keyword[i] ); } else if (th->vtype[i] == Thermo::INT) { NCERRX( nc_def_var(ncid, th->keyword[i], NC_INT, 1, dims, @@ -872,7 +868,12 @@ int DumpNetCDF::modify_param(int narg, char **arg) if (strcmp(arg[iarg],"double") == 0) { iarg++; if (iarg >= narg) error->all(FLERR,"expected 'yes' or 'no' after 'double' keyword."); - double_precision = utils::logical(FLERR,arg[iarg],false,lmp) == 1; + + if (utils::logical(FLERR,arg[iarg],false,lmp) == 1) + type_nc_real = NC_DOUBLE; + else + type_nc_real = NC_FLOAT; + iarg++; return 2; } else if (strcmp(arg[iarg],"at") == 0) { diff --git a/src/NETCDF/dump_netcdf.h b/src/NETCDF/dump_netcdf.h index dd9c50873e..b3bd055701 100644 --- a/src/NETCDF/dump_netcdf.h +++ b/src/NETCDF/dump_netcdf.h @@ -62,7 +62,7 @@ class DumpNetCDF : public DumpCustom { int *thermovar; // NetCDF variables for thermo output - bool double_precision; // write everything as double precision + int type_nc_real; // netcdf type to use for real variables: float or double bool thermo; // write thermo output to netcdf file bigint n_buffer; // size of buffer diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index 0a76203f96..8241d159ae 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -179,7 +179,7 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : int_buffer = nullptr; double_buffer = nullptr; - double_precision = false; + type_nc_real = NC_FLOAT; thermo = false; thermovar = nullptr; @@ -382,14 +382,14 @@ void DumpNetCDFMPIIO::openfile() NCERRX( ncmpi_def_var(ncid, NC_CELL_ANGULAR_STR, NC_CHAR, 2, dims, &cell_angular_var), NC_CELL_ANGULAR_STR ); dims[0] = frame_dim; - NCERRX( ncmpi_def_var(ncid, NC_TIME_STR, NC_DOUBLE, 1, dims, &time_var), NC_TIME_STR); + NCERRX( ncmpi_def_var(ncid, NC_TIME_STR, type_nc_real, 1, dims, &time_var), NC_TIME_STR); dims[0] = frame_dim; dims[1] = cell_spatial_dim; - NCERRX( ncmpi_def_var(ncid, NC_CELL_ORIGIN_STR, NC_DOUBLE, 2, dims, &cell_origin_var), NC_CELL_ORIGIN_STR ); - NCERRX( ncmpi_def_var(ncid, NC_CELL_LENGTHS_STR, NC_DOUBLE, 2, dims, &cell_lengths_var), NC_CELL_LENGTHS_STR ); + NCERRX( ncmpi_def_var(ncid, NC_CELL_ORIGIN_STR, type_nc_real, 2, dims, &cell_origin_var), NC_CELL_ORIGIN_STR ); + NCERRX( ncmpi_def_var(ncid, NC_CELL_LENGTHS_STR, type_nc_real, 2, dims, &cell_lengths_var), NC_CELL_LENGTHS_STR ); dims[0] = frame_dim; dims[1] = cell_angular_dim; - NCERRX( ncmpi_def_var(ncid, NC_CELL_ANGLES_STR, NC_DOUBLE, 2, dims, &cell_angles_var), NC_CELL_ANGLES_STR ); + NCERRX( ncmpi_def_var(ncid, NC_CELL_ANGLES_STR, type_nc_real, 2, dims, &cell_angles_var), NC_CELL_ANGLES_STR ); // variables specified in the input file dims[0] = frame_dim; @@ -405,10 +405,7 @@ void DumpNetCDFMPIIO::openfile() } else if (vtype[perat[i].field[0]] == Dump::BIGINT) { xtype = NC_INT64; } else { - if (double_precision) - xtype = NC_DOUBLE; - else - xtype = NC_FLOAT; + xtype = type_nc_real; } if (perat[i].dims == 1) { @@ -425,7 +422,7 @@ void DumpNetCDFMPIIO::openfile() Thermo *th = output->thermo; for (int i = 0; i < th->nfield; i++) { if (th->vtype[i] == Thermo::FLOAT) { - NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_DOUBLE, 1, dims, &thermovar[i]), th->keyword[i] ); + NCERRX( ncmpi_def_var(ncid, th->keyword[i], type_nc_real, 1, dims, &thermovar[i]), th->keyword[i] ); } else if (th->vtype[i] == Thermo::INT) { NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_INT, 1, dims, &thermovar[i]), th->keyword[i] ); } else if (th->vtype[i] == Thermo::BIGINT) { @@ -867,7 +864,12 @@ int DumpNetCDFMPIIO::modify_param(int narg, char **arg) if (strcmp(arg[iarg],"double") == 0) { iarg++; if (iarg >= narg) error->all(FLERR,"expected 'yes' or 'no' after 'double' keyword."); - double_precision = utils::logical(FLERR,arg[iarg],false,lmp) == 1; + + if (utils::logical(FLERR,arg[iarg],false,lmp) == 1) + type_nc_real = NC_DOUBLE; + else + type_nc_real = NC_FLOAT; + iarg++; return 2; } else if (strcmp(arg[iarg],"at") == 0) { diff --git a/src/NETCDF/dump_netcdf_mpiio.h b/src/NETCDF/dump_netcdf_mpiio.h index 56c07fc3d3..d1fb4fd364 100644 --- a/src/NETCDF/dump_netcdf_mpiio.h +++ b/src/NETCDF/dump_netcdf_mpiio.h @@ -61,7 +61,7 @@ class DumpNetCDFMPIIO : public DumpCustom { int *thermovar; // NetCDF variables for thermo output - bool double_precision; // write everything as double precision + int type_nc_real; // netcdf type to use for real variables: float or double bool thermo; // write thermo output to netcdf file bigint n_buffer; // size of buffer From 4bf065ed1c43e28fae33893aa122339639ab9e98 Mon Sep 17 00:00:00 2001 From: Luthaf Date: Fri, 17 Dec 2021 10:55:54 +0100 Subject: [PATCH 02/13] netcdf: use float values for scale factors instead of double --- src/NETCDF/dump_netcdf.cpp | 8 ++++---- src/NETCDF/dump_netcdf_mpiio.cpp | 9 ++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index 2ad952e885..37e99a1a58 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -341,7 +341,7 @@ void DumpNetCDF::openfile() int dims[NC_MAX_VAR_DIMS]; size_t index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; - double d[1]; + float d[1]; if (singlefile_opened) return; singlefile_opened = 1; @@ -489,11 +489,11 @@ void DumpNetCDF::openfile() NCERR( nc_put_att_text(ncid, cell_angles_var, NC_UNITS_STR,6, "degree") ); d[0] = update->dt; - NCERR( nc_put_att_double(ncid, time_var, NC_SCALE_FACTOR_STR,NC_DOUBLE, 1, d) ); + NCERR( nc_put_att_float(ncid, time_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); d[0] = 1.0; - NCERR( nc_put_att_double(ncid, cell_origin_var, NC_SCALE_FACTOR_STR,NC_DOUBLE, 1, d) ); + NCERR( nc_put_att_float(ncid, cell_origin_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); d[0] = 1.0; - NCERR( nc_put_att_double(ncid, cell_lengths_var, NC_SCALE_FACTOR_STR,NC_DOUBLE, 1, d) ); + NCERR( nc_put_att_float(ncid, cell_lengths_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); /* * Finished with definition diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index 8241d159ae..441cc97bd2 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -276,7 +276,6 @@ void DumpNetCDFMPIIO::openfile() error->all(FLERR, "cannot append to non-existent file {}", filecurrent); MPI_Offset index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; - double d[1]; if (singlefile_opened) return; singlefile_opened = 1; @@ -342,7 +341,7 @@ void DumpNetCDFMPIIO::openfile() int dims[NC_MAX_VAR_DIMS]; MPI_Offset index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; - double d[1]; + float d[1]; if (singlefile_opened) return; singlefile_opened = 1; @@ -474,11 +473,11 @@ void DumpNetCDFMPIIO::openfile() NCERR( ncmpi_put_att_text(ncid, cell_angles_var, NC_UNITS_STR, 6, "degree") ); d[0] = update->dt; - NCERR( ncmpi_put_att_double(ncid, time_var, NC_SCALE_FACTOR_STR, NC_DOUBLE, 1, d) ); + NCERR( ncmpi_put_att_float(ncid, time_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); d[0] = 1.0; - NCERR( ncmpi_put_att_double(ncid, cell_origin_var, NC_SCALE_FACTOR_STR, NC_DOUBLE, 1, d) ); + NCERR( ncmpi_put_att_float(ncid, cell_origin_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); d[0] = 1.0; - NCERR( ncmpi_put_att_double(ncid, cell_lengths_var, NC_SCALE_FACTOR_STR, NC_DOUBLE, 1, d) ); + NCERR( ncmpi_put_att_float(ncid, cell_lengths_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); /* * Finished with definition From dc9d539b6c59a84fbdc29079a377b9f341f6dde3 Mon Sep 17 00:00:00 2001 From: Luthaf Date: Fri, 17 Dec 2021 11:48:06 +0100 Subject: [PATCH 03/13] netcdf: fix spatial, cell_spatial and cell_angular variable definitions Dimension 0 refered to the frame dimension, but we need the spatial dimension instead --- src/NETCDF/dump_netcdf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index 37e99a1a58..d64ebc6581 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -373,10 +373,10 @@ void DumpNetCDF::openfile() } // default variables - dims[0] = 0; + dims[0] = vector_dim[3]; NCERRX( nc_def_var(ncid, NC_SPATIAL_STR, NC_CHAR, 1, dims, &spatial_var), NC_SPATIAL_STR ); NCERRX( nc_def_var(ncid, NC_CELL_SPATIAL_STR, NC_CHAR, 1, dims, &cell_spatial_var), NC_CELL_SPATIAL_STR ); - dims[0] = 0; + dims[0] = vector_dim[3]; dims[1] = label_dim; NCERRX( nc_def_var(ncid, NC_CELL_ANGULAR_STR, NC_CHAR, 2, dims, &cell_angular_var), NC_CELL_ANGULAR_STR ); From f8ee6dc680b5d291aae091db81605d2beb89c67d Mon Sep 17 00:00:00 2001 From: Luthaf Date: Fri, 17 Dec 2021 11:41:04 +0100 Subject: [PATCH 04/13] netcf: define units for all variable where this is possible --- src/NETCDF/dump_netcdf.cpp | 149 +++++++++++++++++++++++-------- src/NETCDF/dump_netcdf.h | 14 +++ src/NETCDF/dump_netcdf_mpiio.cpp | 136 +++++++++++++++++++++------- src/NETCDF/dump_netcdf_mpiio.h | 14 +++ 4 files changed, 243 insertions(+), 70 deletions(-) diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index d64ebc6581..8f5d6f9efd 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -101,6 +101,7 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : int idim = 0; int ndims = 1; std::string mangled = earg[i]; + Quantity quantity = Quantity::Unknown; bool constant = false; // name mangling @@ -109,26 +110,32 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : idim = mangled[0] - 'x'; ndims = 3; mangled = "coordinates"; + quantity = Quantity::Distance; } else if ((mangled == "vx") || (mangled == "vy") || (mangled == "vz")) { idim = mangled[1] - 'x'; ndims = 3; mangled = "velocities"; + quantity = Quantity::Velocity; } else if ((mangled == "xs") || (mangled == "ys") || (mangled == "zs")) { idim = mangled[0] - 'x'; ndims = 3; mangled = "scaled_coordinates"; + // no unit for scaled coordinates } else if ((mangled == "xu") || (mangled == "yu") || (mangled == "zu")) { idim = mangled[0] - 'x'; ndims = 3; mangled = "unwrapped_coordinates"; + quantity = Quantity::Distance; } else if ((mangled == "fx") || (mangled == "fy") || (mangled == "fz")) { idim = mangled[1] - 'x'; ndims = 3; mangled = "forces"; + quantity = Quantity::Force; } else if ((mangled == "mux") || (mangled == "muy") || (mangled == "muz")) { idim = mangled[2] - 'x'; ndims = 3; mangled = "mu"; + quantity = Quantity::DipoleMoment; } else if (utils::strmatch(mangled, "^c_")) { std::size_t found = mangled.find('['); if (found != std::string::npos) { @@ -175,6 +182,7 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : perat[inc].constant = constant; perat[inc].ndumped = 0; perat[inc].field[idim] = i; + perat[inc].quantity = quantity; } n_buffer = 0; @@ -341,7 +349,6 @@ void DumpNetCDF::openfile() int dims[NC_MAX_VAR_DIMS]; size_t index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; - float d[1]; if (singlefile_opened) return; singlefile_opened = 1; @@ -426,6 +433,11 @@ void DumpNetCDF::openfile() NCERRX( nc_def_var(ncid, perat[i].name, xtype, 3, dims, &perat[i].var), perat[i].name ); } } + + std::string unit = this->unit_of(perat[i].quantity); + if (!unit.empty()) { + NCERR( nc_put_att_text(ncid, perat[i].var, NC_UNITS_STR, unit.size(), unit.c_str()) ); + } } // perframe variables @@ -457,43 +469,18 @@ void DumpNetCDF::openfile() NCERR( nc_put_att_text(ncid, NC_GLOBAL, "program", 6, "LAMMPS") ); NCERR( nc_put_att_text(ncid, NC_GLOBAL, "programVersion",strlen(lmp->version), lmp->version) ); - // units - if (!strcmp(update->unit_style, "lj")) { - NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 2, "lj") ); - NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 2, "lj") ); - NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 2, "lj") ); - } else if (!strcmp(update->unit_style, "real")) { - NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 11, "femtosecond") ); - NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 8, "Angstrom") ); - NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 8, "Angstrom") ); - } else if (!strcmp(update->unit_style, "metal")) { - NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 10, "picosecond") ); - NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 8, "Angstrom") ); - NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 8, "Angstrom") ); - } else if (!strcmp(update->unit_style, "si")) { - NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 6, "second") ); - NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 5, "meter") ); - NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 5, "meter") ); - } else if (!strcmp(update->unit_style, "cgs")) { - NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 6, "second") ); - NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 10, "centimeter") ); - NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 10, "centimeter") ); - } else if (!strcmp(update->unit_style, "electron")) { - NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, 11, "femtosecond") ); - NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 4, "Bohr") ); - NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 4, "Bohr") ); - } else { - error->all(FLERR,"Unsupported unit style: {}", update->unit_style); - } + // units & scale + std::string unit = this->unit_of(Quantity::Time); + NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); - NCERR( nc_put_att_text(ncid, cell_angles_var, NC_UNITS_STR,6, "degree") ); + unit = this->unit_of(Quantity::Distance); + NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); + NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); - d[0] = update->dt; - NCERR( nc_put_att_float(ncid, time_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); - d[0] = 1.0; - NCERR( nc_put_att_float(ncid, cell_origin_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); - d[0] = 1.0; - NCERR( nc_put_att_float(ncid, cell_lengths_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); + NCERR( nc_put_att_text(ncid, cell_angles_var, NC_UNITS_STR, 6, "degree") ); + + float scale[1] = {static_cast(update->dt)}; + NCERR( nc_put_att_float(ncid, time_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, scale) ); /* * Finished with definition @@ -905,4 +892,94 @@ void DumpNetCDF::ncerr(int err, const char *descr, int line) } } +/* ---------------------------------------------------------------------- */ + +std::string DumpNetCDF::unit_of(Quantity quantity) { + if (!strcmp(update->unit_style, "lj")) { + if (quantity == Quantity::Unknown) { + return ""; + } else { + return "lj"; + } + } else if (!strcmp(update->unit_style, "real")) { + switch (quantity) { + case Quantity::Unknown: + return ""; + case Quantity::Time: + return "femtosecond"; + case Quantity::Distance: + return "Angstrom"; + case Quantity::Velocity: + return "Angstrom/femtosecond"; + case Quantity::Force: + return "(Kcal/mol)/Angstrom)"; + case Quantity::DipoleMoment: + return "e * Angstrom"; + } + } else if (!strcmp(update->unit_style, "metal")) { + switch (quantity) { + case Quantity::Unknown: + return ""; + case Quantity::Time: + return "picosecond"; + case Quantity::Distance: + return "Angstrom"; + case Quantity::Velocity: + return "Angstrom/picosecond"; + case Quantity::Force: + return "eV/Angstrom"; + case Quantity::DipoleMoment: + return "e * Angstrom"; + } + } else if (!strcmp(update->unit_style, "si")) { + switch (quantity) { + case Quantity::Unknown: + return ""; + case Quantity::Time: + return "second"; + case Quantity::Distance: + return "meter"; + case Quantity::Velocity: + return "meter/second"; + case Quantity::Force: + return "Newton"; + case Quantity::DipoleMoment: + return "Coulomb * meter"; + } + } else if (!strcmp(update->unit_style, "cgs")) { + switch (quantity) { + case Quantity::Unknown: + return ""; + case Quantity::Time: + return "second"; + case Quantity::Distance: + return "centimeter"; + case Quantity::Velocity: + return "centimeter/second"; + case Quantity::Force: + return "dynes"; + case Quantity::DipoleMoment: + return "statcoul * cm"; + } + } else if (!strcmp(update->unit_style, "electron")) { + switch (quantity) { + case Quantity::Unknown: + return ""; + case Quantity::Time: + return "second"; + case Quantity::Distance: + return "centimeter"; + case Quantity::Velocity: + return "centimeter/second"; + case Quantity::Force: + return "Hartrees/Bohr"; + case Quantity::DipoleMoment: + return "Debye"; + } + } + + error->all(FLERR, "Unsupported unit style: {}", update->unit_style); + return ""; +} + #endif /* defined(LMP_HAS_NETCDF) */ diff --git a/src/NETCDF/dump_netcdf.h b/src/NETCDF/dump_netcdf.h index b3bd055701..07c104c445 100644 --- a/src/NETCDF/dump_netcdf.h +++ b/src/NETCDF/dump_netcdf.h @@ -40,12 +40,26 @@ class DumpNetCDF : public DumpCustom { virtual void write(); private: + // type of quantity for per-atom values (used to get the unit) + enum Quantity { + Unknown = 0, + + Time, + Distance, + Velocity, + Force, + DipoleMoment, + }; + // get the name of the unit for the given quantity + std::string unit_of(Quantity quantity); + // per-atoms quantities (positions, velocities, etc.) struct nc_perat_t { int dims; // number of dimensions int field[DUMP_NC_MAX_DIMS]; // field indices corresponding to the dim. char name[NC_FIELD_NAME_MAX]; // field name int var; // NetCDF variable + Quantity quantity; // type of the quantity bool constant; // is this property per file (not per frame) int ndumped; // number of enties written for this prop. diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index 441cc97bd2..af0f965e3c 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -102,6 +102,7 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : int ndims = 1; std::string mangled = earg[i]; bool constant = false; + Quantity quantity = Quantity::Unknown; // name mangling // in the AMBER specification @@ -109,26 +110,32 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : idim = mangled[0] - 'x'; ndims = 3; mangled = "coordinates"; + quantity = Quantity::Distance; } else if ((mangled == "vx") || (mangled == "vy") || (mangled == "vz")) { idim = mangled[1] - 'x'; ndims = 3; mangled = "velocities"; + quantity = Quantity::Velocity; } else if ((mangled == "xs") || (mangled == "ys") || (mangled == "zs")) { idim = mangled[0] - 'x'; ndims = 3; mangled = "scaled_coordinates"; + // no quantity for scaled_coordinates } else if ((mangled == "xu") || (mangled == "yu") || (mangled == "zu")) { idim = mangled[0] - 'x'; ndims = 3; mangled = "unwrapped_coordinates"; + quantity = Quantity::Distance; } else if ((mangled == "fx") || (mangled == "fy") || (mangled == "fz")) { idim = mangled[1] - 'x'; ndims = 3; mangled = "forces"; + quantity = Quantity::Force; } else if ((mangled == "mux") || (mangled == "muy") || (mangled == "muz")) { idim = mangled[2] - 'x'; ndims = 3; mangled = "mu"; + quantity = Quantity::DipoleMoment; } else if (utils::strmatch(mangled, "^c_")) { std::size_t found = mangled.find('['); if (found != std::string::npos) { @@ -173,6 +180,7 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : } perat[inc].field[idim] = i; + perat[inc].quantity = quantity; } n_buffer = 0; @@ -414,6 +422,11 @@ void DumpNetCDFMPIIO::openfile() dims[2] = vector_dim[perat[i].dims]; NCERRX( ncmpi_def_var(ncid, perat[i].name, xtype, 3, dims, &perat[i].var), perat[i].name ); } + + std::string unit = this->unit_of(perat[i].quantity); + if (!unit.empty()) { + NCERR( ncmpi_put_att_text(ncid, perat[i].var, NC_UNITS_STR, unit.size(), unit.c_str()) ); + } } // perframe variables @@ -441,43 +454,18 @@ void DumpNetCDFMPIIO::openfile() NCERR( ncmpi_put_att_text(ncid, NC_GLOBAL, "program", 6, "LAMMPS") ); NCERR( ncmpi_put_att_text(ncid, NC_GLOBAL, "programVersion", strlen(lmp->version), lmp->version) ); - // units - if (!strcmp(update->unit_style, "lj")) { - NCERR( ncmpi_put_att_text(ncid, time_var, NC_UNITS_STR, 2, "lj") ); - NCERR( ncmpi_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 2, "lj") ); - NCERR( ncmpi_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 2, "lj") ); - } else if (!strcmp(update->unit_style, "real")) { - NCERR( ncmpi_put_att_text(ncid, time_var, NC_UNITS_STR, 11, "femtosecond") ); - NCERR( ncmpi_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 8, "Angstrom") ); - NCERR( ncmpi_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 8, "Angstrom") ); - } else if (!strcmp(update->unit_style, "metal")) { - NCERR( ncmpi_put_att_text(ncid, time_var, NC_UNITS_STR, 10, "picosecond") ); - NCERR( ncmpi_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 8, "Angstrom") ); - NCERR( ncmpi_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 8, "Angstrom") ); - } else if (!strcmp(update->unit_style, "si")) { - NCERR( ncmpi_put_att_text(ncid, time_var, NC_UNITS_STR, 6, "second") ); - NCERR( ncmpi_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 5, "meter") ); - NCERR( ncmpi_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 5, "meter") ); - } else if (!strcmp(update->unit_style, "cgs")) { - NCERR( ncmpi_put_att_text(ncid, time_var, NC_UNITS_STR, 6, "second") ); - NCERR( ncmpi_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 10, "centimeter") ); - NCERR( ncmpi_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 10, "centimeter") ); - } else if (!strcmp(update->unit_style, "electron")) { - NCERR( ncmpi_put_att_text(ncid, time_var, NC_UNITS_STR, 11, "femtosecond") ); - NCERR( ncmpi_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, 4, "Bohr") ); - NCERR( ncmpi_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, 4, "Bohr") ); - } else { - error->all(FLERR,"Unsupported unit style: {}", update->unit_style); - } + // units & scale + std::string unit = this->unit_of(Quantity::Time); + NCERR( ncmpi_put_att_text(ncid, time_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); + + unit = this->unit_of(Quantity::Distance); + NCERR( ncmpi_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); + NCERR( ncmpi_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); NCERR( ncmpi_put_att_text(ncid, cell_angles_var, NC_UNITS_STR, 6, "degree") ); - d[0] = update->dt; - NCERR( ncmpi_put_att_float(ncid, time_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); - d[0] = 1.0; - NCERR( ncmpi_put_att_float(ncid, cell_origin_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); - d[0] = 1.0; - NCERR( ncmpi_put_att_float(ncid, cell_lengths_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, d) ); + float scale[1] = {static_cast(update->dt)}; + NCERR( ncmpi_put_att_float(ncid, time_var, NC_SCALE_FACTOR_STR, NC_FLOAT, 1, scale) ); /* * Finished with definition @@ -900,4 +888,84 @@ void DumpNetCDFMPIIO::ncerr(int err, const char *descr, int line) } } +/* ---------------------------------------------------------------------- */ + +std::string DumpNetCDF::unit_of(Quantity quantity) { + if (quantity == Quantity::Unknown) { + return ""; + } + + if (!strcmp(update->unit_style, "lj")) { + return "lj"; + } else if (!strcmp(update->unit_style, "real")) { + switch (quantity) { + case Quantity::Time: + return "femtosecond"; + case Quantity::Distance: + return "Angstrom"; + case Quantity::Velocity: + return "Angstrom/femtosecond"; + case Quantity::Force: + return "(Kcal/mol)/Angstrom)"; + case Quantity::DipoleMoment: + return "e * Angstrom"; + } + } else if (!strcmp(update->unit_style, "metal")) { + switch (quantity) { + case Quantity::Time: + return "picosecond"; + case Quantity::Distance: + return "Angstrom"; + case Quantity::Velocity: + return "Angstrom/picosecond"; + case Quantity::Force: + return "eV/Angstrom"; + case Quantity::DipoleMoment: + return "e * Angstrom"; + } + } else if (!strcmp(update->unit_style, "si")) { + switch (quantity) { + case Quantity::Time: + return "second"; + case Quantity::Distance: + return "meter"; + case Quantity::Velocity: + return "meter/second"; + case Quantity::Force: + return "Newton"; + case Quantity::DipoleMoment: + return "Coulomb * meter"; + } + } else if (!strcmp(update->unit_style, "cgs")) { + switch (quantity) { + case Quantity::Time: + return "second"; + case Quantity::Distance: + return "centimeter"; + case Quantity::Velocity: + return "centimeter/second"; + case Quantity::Force: + return "dynes"; + case Quantity::DipoleMoment: + return "statcoul * cm"; + } + } else if (!strcmp(update->unit_style, "electron")) { + switch (quantity) { + case Quantity::Time: + return "second"; + case Quantity::Distance: + return "centimeter"; + case Quantity::Velocity: + return "centimeter/second"; + case Quantity::Force: + return "Hartrees/Bohr"; + case Quantity::DipoleMoment: + return "Debye"; + } + } + + error->all(FLERR, "Unsupported unit style: {}", update->unit_style); + return ""; +} + #endif /* defined(LMP_HAS_PNETCDF) */ diff --git a/src/NETCDF/dump_netcdf_mpiio.h b/src/NETCDF/dump_netcdf_mpiio.h index d1fb4fd364..eb2cfb7b90 100644 --- a/src/NETCDF/dump_netcdf_mpiio.h +++ b/src/NETCDF/dump_netcdf_mpiio.h @@ -40,12 +40,26 @@ class DumpNetCDFMPIIO : public DumpCustom { virtual void write(); private: + // type of quantity for per-atom values (used to get the unit) + enum Quantity { + Unknown = 0, + + Time, + Distance, + Velocity, + Force, + DipoleMoment, + }; + // get the name of the unit for the given quantity + std::string unit_of(Quantity quantity); + // per-atoms quantities (positions, velocities, etc.) struct nc_perat_t { int dims; // number of dimensions int field[DUMP_NC_MPIIO_MAX_DIMS]; // field indices corresponding to the dim. char name[NC_MPIIO_FIELD_NAME_MAX]; // field name int var; // NetCDF variable + Quantity quantity; // type of the quantity }; typedef void (DumpNetCDFMPIIO::*funcptr_t)(void *); From 1c25c96aaa9a990667b0f463b83cf3e2d444a521 Mon Sep 17 00:00:00 2001 From: Luthaf Date: Fri, 17 Dec 2021 17:13:29 +0100 Subject: [PATCH 05/13] netcdf: deduplicate gettings units as strings --- src/NETCDF/dump_netcdf.cpp | 109 +++-------------------- src/NETCDF/dump_netcdf.h | 14 +-- src/NETCDF/dump_netcdf_mpiio.cpp | 99 +++------------------ src/NETCDF/dump_netcdf_mpiio.h | 14 +-- src/NETCDF/netcdf_units.cpp | 143 +++++++++++++++++++++++++++++++ src/NETCDF/netcdf_units.h | 45 ++++++++++ 6 files changed, 210 insertions(+), 214 deletions(-) create mode 100644 src/NETCDF/netcdf_units.cpp create mode 100644 src/NETCDF/netcdf_units.h diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index 8f5d6f9efd..f67bf8c2ff 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -19,6 +19,7 @@ #if defined(LMP_HAS_NETCDF) #include "dump_netcdf.h" +#include "netcdf_units.h" #include "atom.h" #include "comm.h" @@ -101,7 +102,7 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : int idim = 0; int ndims = 1; std::string mangled = earg[i]; - Quantity quantity = Quantity::Unknown; + Quantity quantity = Quantity::UNKNOWN; bool constant = false; // name mangling @@ -110,12 +111,12 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : idim = mangled[0] - 'x'; ndims = 3; mangled = "coordinates"; - quantity = Quantity::Distance; + quantity = Quantity::DISTANCE; } else if ((mangled == "vx") || (mangled == "vy") || (mangled == "vz")) { idim = mangled[1] - 'x'; ndims = 3; mangled = "velocities"; - quantity = Quantity::Velocity; + quantity = Quantity::VELOCITY; } else if ((mangled == "xs") || (mangled == "ys") || (mangled == "zs")) { idim = mangled[0] - 'x'; ndims = 3; @@ -125,17 +126,17 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : idim = mangled[0] - 'x'; ndims = 3; mangled = "unwrapped_coordinates"; - quantity = Quantity::Distance; + quantity = Quantity::DISTANCE; } else if ((mangled == "fx") || (mangled == "fy") || (mangled == "fz")) { idim = mangled[1] - 'x'; ndims = 3; mangled = "forces"; - quantity = Quantity::Force; + quantity = Quantity::FORCE; } else if ((mangled == "mux") || (mangled == "muy") || (mangled == "muz")) { idim = mangled[2] - 'x'; ndims = 3; mangled = "mu"; - quantity = Quantity::DipoleMoment; + quantity = Quantity::DIPOLE_MOMENT; } else if (utils::strmatch(mangled, "^c_")) { std::size_t found = mangled.find('['); if (found != std::string::npos) { @@ -434,7 +435,7 @@ void DumpNetCDF::openfile() } } - std::string unit = this->unit_of(perat[i].quantity); + std::string unit = get_unit_for(update->unit_style, perat[i].quantity, error); if (!unit.empty()) { NCERR( nc_put_att_text(ncid, perat[i].var, NC_UNITS_STR, unit.size(), unit.c_str()) ); } @@ -470,10 +471,10 @@ void DumpNetCDF::openfile() NCERR( nc_put_att_text(ncid, NC_GLOBAL, "programVersion",strlen(lmp->version), lmp->version) ); // units & scale - std::string unit = this->unit_of(Quantity::Time); + std::string unit = get_unit_for(update->unit_style, Quantity::TIME, error); NCERR( nc_put_att_text(ncid, time_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); - unit = this->unit_of(Quantity::Distance); + unit = get_unit_for(update->unit_style, Quantity::DISTANCE, error); NCERR( nc_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); NCERR( nc_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); @@ -892,94 +893,4 @@ void DumpNetCDF::ncerr(int err, const char *descr, int line) } } -/* ---------------------------------------------------------------------- */ - -std::string DumpNetCDF::unit_of(Quantity quantity) { - if (!strcmp(update->unit_style, "lj")) { - if (quantity == Quantity::Unknown) { - return ""; - } else { - return "lj"; - } - } else if (!strcmp(update->unit_style, "real")) { - switch (quantity) { - case Quantity::Unknown: - return ""; - case Quantity::Time: - return "femtosecond"; - case Quantity::Distance: - return "Angstrom"; - case Quantity::Velocity: - return "Angstrom/femtosecond"; - case Quantity::Force: - return "(Kcal/mol)/Angstrom)"; - case Quantity::DipoleMoment: - return "e * Angstrom"; - } - } else if (!strcmp(update->unit_style, "metal")) { - switch (quantity) { - case Quantity::Unknown: - return ""; - case Quantity::Time: - return "picosecond"; - case Quantity::Distance: - return "Angstrom"; - case Quantity::Velocity: - return "Angstrom/picosecond"; - case Quantity::Force: - return "eV/Angstrom"; - case Quantity::DipoleMoment: - return "e * Angstrom"; - } - } else if (!strcmp(update->unit_style, "si")) { - switch (quantity) { - case Quantity::Unknown: - return ""; - case Quantity::Time: - return "second"; - case Quantity::Distance: - return "meter"; - case Quantity::Velocity: - return "meter/second"; - case Quantity::Force: - return "Newton"; - case Quantity::DipoleMoment: - return "Coulomb * meter"; - } - } else if (!strcmp(update->unit_style, "cgs")) { - switch (quantity) { - case Quantity::Unknown: - return ""; - case Quantity::Time: - return "second"; - case Quantity::Distance: - return "centimeter"; - case Quantity::Velocity: - return "centimeter/second"; - case Quantity::Force: - return "dynes"; - case Quantity::DipoleMoment: - return "statcoul * cm"; - } - } else if (!strcmp(update->unit_style, "electron")) { - switch (quantity) { - case Quantity::Unknown: - return ""; - case Quantity::Time: - return "second"; - case Quantity::Distance: - return "centimeter"; - case Quantity::Velocity: - return "centimeter/second"; - case Quantity::Force: - return "Hartrees/Bohr"; - case Quantity::DipoleMoment: - return "Debye"; - } - } - - error->all(FLERR, "Unsupported unit style: {}", update->unit_style); - return ""; -} - #endif /* defined(LMP_HAS_NETCDF) */ diff --git a/src/NETCDF/dump_netcdf.h b/src/NETCDF/dump_netcdf.h index 07c104c445..619aad9138 100644 --- a/src/NETCDF/dump_netcdf.h +++ b/src/NETCDF/dump_netcdf.h @@ -29,6 +29,7 @@ DumpStyle(netcdf,DumpNetCDF); #include "dump_custom.h" namespace LAMMPS_NS { +enum class Quantity; const int NC_FIELD_NAME_MAX = 100; const int DUMP_NC_MAX_DIMS = 100; @@ -40,19 +41,6 @@ class DumpNetCDF : public DumpCustom { virtual void write(); private: - // type of quantity for per-atom values (used to get the unit) - enum Quantity { - Unknown = 0, - - Time, - Distance, - Velocity, - Force, - DipoleMoment, - }; - // get the name of the unit for the given quantity - std::string unit_of(Quantity quantity); - // per-atoms quantities (positions, velocities, etc.) struct nc_perat_t { int dims; // number of dimensions diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index af0f965e3c..ba16b8c0e6 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -19,6 +19,7 @@ #if defined(LMP_HAS_PNETCDF) #include "dump_netcdf_mpiio.h" +#include "netcdf_units.h" #include "atom.h" #include "comm.h" @@ -102,7 +103,7 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : int ndims = 1; std::string mangled = earg[i]; bool constant = false; - Quantity quantity = Quantity::Unknown; + Quantity quantity = Quantity::UNKNOWN; // name mangling // in the AMBER specification @@ -110,12 +111,12 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : idim = mangled[0] - 'x'; ndims = 3; mangled = "coordinates"; - quantity = Quantity::Distance; + quantity = Quantity::DISTANCE; } else if ((mangled == "vx") || (mangled == "vy") || (mangled == "vz")) { idim = mangled[1] - 'x'; ndims = 3; mangled = "velocities"; - quantity = Quantity::Velocity; + quantity = Quantity::VELOCITY; } else if ((mangled == "xs") || (mangled == "ys") || (mangled == "zs")) { idim = mangled[0] - 'x'; ndims = 3; @@ -125,17 +126,17 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : idim = mangled[0] - 'x'; ndims = 3; mangled = "unwrapped_coordinates"; - quantity = Quantity::Distance; + quantity = Quantity::DISTANCE; } else if ((mangled == "fx") || (mangled == "fy") || (mangled == "fz")) { idim = mangled[1] - 'x'; ndims = 3; mangled = "forces"; - quantity = Quantity::Force; + quantity = Quantity::FORCE; } else if ((mangled == "mux") || (mangled == "muy") || (mangled == "muz")) { idim = mangled[2] - 'x'; ndims = 3; mangled = "mu"; - quantity = Quantity::DipoleMoment; + quantity = Quantity::DIPOLE_MOMENT; } else if (utils::strmatch(mangled, "^c_")) { std::size_t found = mangled.find('['); if (found != std::string::npos) { @@ -423,7 +424,7 @@ void DumpNetCDFMPIIO::openfile() NCERRX( ncmpi_def_var(ncid, perat[i].name, xtype, 3, dims, &perat[i].var), perat[i].name ); } - std::string unit = this->unit_of(perat[i].quantity); + std::string unit = get_unit_for(update->unit_style, perat[i].quantity, error); if (!unit.empty()) { NCERR( ncmpi_put_att_text(ncid, perat[i].var, NC_UNITS_STR, unit.size(), unit.c_str()) ); } @@ -455,10 +456,10 @@ void DumpNetCDFMPIIO::openfile() NCERR( ncmpi_put_att_text(ncid, NC_GLOBAL, "programVersion", strlen(lmp->version), lmp->version) ); // units & scale - std::string unit = this->unit_of(Quantity::Time); + std::string unit = get_unit_for(update->unit_style, Quantity::TIME, error); NCERR( ncmpi_put_att_text(ncid, time_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); - unit = this->unit_of(Quantity::Distance); + unit = get_unit_for(update->unit_style, Quantity::DISTANCE, error); NCERR( ncmpi_put_att_text(ncid, cell_origin_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); NCERR( ncmpi_put_att_text(ncid, cell_lengths_var, NC_UNITS_STR, unit.size(), unit.c_str()) ); @@ -888,84 +889,4 @@ void DumpNetCDFMPIIO::ncerr(int err, const char *descr, int line) } } -/* ---------------------------------------------------------------------- */ - -std::string DumpNetCDF::unit_of(Quantity quantity) { - if (quantity == Quantity::Unknown) { - return ""; - } - - if (!strcmp(update->unit_style, "lj")) { - return "lj"; - } else if (!strcmp(update->unit_style, "real")) { - switch (quantity) { - case Quantity::Time: - return "femtosecond"; - case Quantity::Distance: - return "Angstrom"; - case Quantity::Velocity: - return "Angstrom/femtosecond"; - case Quantity::Force: - return "(Kcal/mol)/Angstrom)"; - case Quantity::DipoleMoment: - return "e * Angstrom"; - } - } else if (!strcmp(update->unit_style, "metal")) { - switch (quantity) { - case Quantity::Time: - return "picosecond"; - case Quantity::Distance: - return "Angstrom"; - case Quantity::Velocity: - return "Angstrom/picosecond"; - case Quantity::Force: - return "eV/Angstrom"; - case Quantity::DipoleMoment: - return "e * Angstrom"; - } - } else if (!strcmp(update->unit_style, "si")) { - switch (quantity) { - case Quantity::Time: - return "second"; - case Quantity::Distance: - return "meter"; - case Quantity::Velocity: - return "meter/second"; - case Quantity::Force: - return "Newton"; - case Quantity::DipoleMoment: - return "Coulomb * meter"; - } - } else if (!strcmp(update->unit_style, "cgs")) { - switch (quantity) { - case Quantity::Time: - return "second"; - case Quantity::Distance: - return "centimeter"; - case Quantity::Velocity: - return "centimeter/second"; - case Quantity::Force: - return "dynes"; - case Quantity::DipoleMoment: - return "statcoul * cm"; - } - } else if (!strcmp(update->unit_style, "electron")) { - switch (quantity) { - case Quantity::Time: - return "second"; - case Quantity::Distance: - return "centimeter"; - case Quantity::Velocity: - return "centimeter/second"; - case Quantity::Force: - return "Hartrees/Bohr"; - case Quantity::DipoleMoment: - return "Debye"; - } - } - - error->all(FLERR, "Unsupported unit style: {}", update->unit_style); - return ""; -} - #endif /* defined(LMP_HAS_PNETCDF) */ diff --git a/src/NETCDF/dump_netcdf_mpiio.h b/src/NETCDF/dump_netcdf_mpiio.h index eb2cfb7b90..97fad9b805 100644 --- a/src/NETCDF/dump_netcdf_mpiio.h +++ b/src/NETCDF/dump_netcdf_mpiio.h @@ -29,6 +29,7 @@ DumpStyle(netcdf/mpiio,DumpNetCDFMPIIO); #include "dump_custom.h" namespace LAMMPS_NS { +enum class Quantity; const int NC_MPIIO_FIELD_NAME_MAX = 100; const int DUMP_NC_MPIIO_MAX_DIMS = 100; @@ -40,19 +41,6 @@ class DumpNetCDFMPIIO : public DumpCustom { virtual void write(); private: - // type of quantity for per-atom values (used to get the unit) - enum Quantity { - Unknown = 0, - - Time, - Distance, - Velocity, - Force, - DipoleMoment, - }; - // get the name of the unit for the given quantity - std::string unit_of(Quantity quantity); - // per-atoms quantities (positions, velocities, etc.) struct nc_perat_t { int dims; // number of dimensions diff --git a/src/NETCDF/netcdf_units.cpp b/src/NETCDF/netcdf_units.cpp new file mode 100644 index 0000000000..938512755a --- /dev/null +++ b/src/NETCDF/netcdf_units.cpp @@ -0,0 +1,143 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Lars Pastewka (University of Freiburg) +------------------------------------------------------------------------- */ + +#if defined(LMP_HAS_NETCDF) || defined(LMP_HAS_PNETCDF) + +#include "netcdf_units.h" + +#include "error.h" + +std::string LAMMPS_NS::get_unit_for(const char* unit_style, Quantity quantity, Error* error) { + if (!strcmp(unit_style, "lj")) { + if (quantity == Quantity::UNKNOWN) { + return ""; + } else { + return "lj"; + } + } else if (!strcmp(unit_style, "real")) { + switch (quantity) { + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "femtosecond"; + case Quantity::DISTANCE: + return "angstrom"; + case Quantity::VELOCITY: + return "angstrom/femtosecond"; + case Quantity::FORCE: + return "(Kcal/mol)/angstrom)"; + case Quantity::DIPOLE_MOMENT: + return "e * angstrom"; + } + } else if (!strcmp(unit_style, "metal")) { + switch (quantity) { + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "picosecond"; + case Quantity::DISTANCE: + return "angstrom"; + case Quantity::VELOCITY: + return "angstrom/picosecond"; + case Quantity::FORCE: + return "eV/angstrom"; + case Quantity::DIPOLE_MOMENT: + return "e * angstrom"; + } + } else if (!strcmp(unit_style, "si")) { + switch (quantity) { + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "second"; + case Quantity::DISTANCE: + return "meter"; + case Quantity::VELOCITY: + return "meter/second"; + case Quantity::FORCE: + return "Newton"; + case Quantity::DIPOLE_MOMENT: + return "Coulomb * meter"; + } + } else if (!strcmp(unit_style, "cgs")) { + switch (quantity) { + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "second"; + case Quantity::DISTANCE: + return "centimeter"; + case Quantity::VELOCITY: + return "centimeter/second"; + case Quantity::FORCE: + return "dynes"; + case Quantity::DIPOLE_MOMENT: + return "statcoul * cm"; + } + } else if (!strcmp(unit_style, "electron")) { + switch (quantity) { + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "femtoseconds"; + case Quantity::DISTANCE: + return "Bohr"; + case Quantity::VELOCITY: + return "Bohr/atomic time units"; + case Quantity::FORCE: + return "Hartree/Bohr"; + case Quantity::DIPOLE_MOMENT: + return "Debye"; + } + } else if (!strcmp(unit_style, "micro")) { + switch (quantity) { + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "microseconds"; + case Quantity::DISTANCE: + return "micrometers"; + case Quantity::VELOCITY: + return "micrometers/microsecond"; + case Quantity::FORCE: + return "picogram * micrometer/microsecond^2"; + case Quantity::DIPOLE_MOMENT: + return "picocoulomb * micrometer"; + } + } else if (!strcmp(unit_style, "nano")) { + switch (quantity) { + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "nanoseconds"; + case Quantity::DISTANCE: + return "nanometers"; + case Quantity::VELOCITY: + return "nanometers/nanosecond"; + case Quantity::FORCE: + return "attogram * nanometer/nanosecond^2"; + case Quantity::DIPOLE_MOMENT: + return "e * nanometer"; + } + } + + error->all(FLERR, "Unsupported unit style: {}", unit_style); + return ""; +} + +#endif diff --git a/src/NETCDF/netcdf_units.h b/src/NETCDF/netcdf_units.h new file mode 100644 index 0000000000..bb83d983c8 --- /dev/null +++ b/src/NETCDF/netcdf_units.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: Lars Pastewka (University of Freiburg), Guillaume Fraux (EPFL) +------------------------------------------------------------------------- */ + +#ifndef LMP_NETCDF_UNITS_H +#define LMP_NETCDF_UNITS_H + +#if defined(LMP_HAS_NETCDF) || defined(LMP_HAS_PNETCDF) + +#include + +namespace LAMMPS_NS { +class Error; + +// type of quantity for per-atom values (used to get the unit) +enum class Quantity { + UNKNOWN = 0, + TIME, + DISTANCE, + VELOCITY, + FORCE, + DIPOLE_MOMENT, +}; + +// get the name of the unit for the given `quantity` in the given LAMMPS +// `unit_style` any error will be reported through `error` +std::string get_unit_for(const char* unit_style, Quantity quantity, Error* error); + +} + +#endif +#endif From c780768e91e4a45c06f9997b9853992afbc7fefc Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 21 Dec 2021 13:16:23 -0500 Subject: [PATCH 06/13] put contents of netcdf_units into NetCDFUnits namespace --- src/NETCDF/dump_netcdf.cpp | 2 ++ src/NETCDF/dump_netcdf.h | 4 ++-- src/NETCDF/dump_netcdf_mpiio.cpp | 2 ++ src/NETCDF/dump_netcdf_mpiio.h | 4 ++-- src/NETCDF/netcdf_units.cpp | 4 +++- src/NETCDF/netcdf_units.h | 5 +++-- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index f67bf8c2ff..605b480da0 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -44,6 +44,8 @@ using namespace LAMMPS_NS; using namespace MathConst; +using NetCDFUnits::Quantity; +using NetCDFUnits::get_unit_for; static const char NC_FRAME_STR[] = "frame"; static const char NC_SPATIAL_STR[] = "spatial"; diff --git a/src/NETCDF/dump_netcdf.h b/src/NETCDF/dump_netcdf.h index 619aad9138..2e0a275425 100644 --- a/src/NETCDF/dump_netcdf.h +++ b/src/NETCDF/dump_netcdf.h @@ -29,7 +29,7 @@ DumpStyle(netcdf,DumpNetCDF); #include "dump_custom.h" namespace LAMMPS_NS { -enum class Quantity; +namespace NetCDFUnits {enum Quantity : int;} // forward declaration const int NC_FIELD_NAME_MAX = 100; const int DUMP_NC_MAX_DIMS = 100; @@ -47,7 +47,7 @@ class DumpNetCDF : public DumpCustom { int field[DUMP_NC_MAX_DIMS]; // field indices corresponding to the dim. char name[NC_FIELD_NAME_MAX]; // field name int var; // NetCDF variable - Quantity quantity; // type of the quantity + NetCDFUnits::Quantity quantity; // type of the quantity bool constant; // is this property per file (not per frame) int ndumped; // number of enties written for this prop. diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index ba16b8c0e6..eb117e1dc0 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -44,6 +44,8 @@ using namespace LAMMPS_NS; using namespace MathConst; +using NetCDFUnits::Quantity; +using NetCDFUnits::get_unit_for; static const char NC_FRAME_STR[] = "frame"; static const char NC_SPATIAL_STR[] = "spatial"; diff --git a/src/NETCDF/dump_netcdf_mpiio.h b/src/NETCDF/dump_netcdf_mpiio.h index 97fad9b805..da45887b88 100644 --- a/src/NETCDF/dump_netcdf_mpiio.h +++ b/src/NETCDF/dump_netcdf_mpiio.h @@ -29,7 +29,7 @@ DumpStyle(netcdf/mpiio,DumpNetCDFMPIIO); #include "dump_custom.h" namespace LAMMPS_NS { -enum class Quantity; +namespace NetCDFUnits {enum Quantity : int;} // forward declaration const int NC_MPIIO_FIELD_NAME_MAX = 100; const int DUMP_NC_MPIIO_MAX_DIMS = 100; @@ -47,7 +47,7 @@ class DumpNetCDFMPIIO : public DumpCustom { int field[DUMP_NC_MPIIO_MAX_DIMS]; // field indices corresponding to the dim. char name[NC_MPIIO_FIELD_NAME_MAX]; // field name int var; // NetCDF variable - Quantity quantity; // type of the quantity + NetCDFUnits::Quantity quantity; // type of the quantity }; typedef void (DumpNetCDFMPIIO::*funcptr_t)(void *); diff --git a/src/NETCDF/netcdf_units.cpp b/src/NETCDF/netcdf_units.cpp index 938512755a..907d0d7496 100644 --- a/src/NETCDF/netcdf_units.cpp +++ b/src/NETCDF/netcdf_units.cpp @@ -22,7 +22,9 @@ #include "error.h" -std::string LAMMPS_NS::get_unit_for(const char* unit_style, Quantity quantity, Error* error) { +using namespace LAMMPS_NS; + +std::string NetCDFUnits::get_unit_for(const char* unit_style, Quantity quantity, Error* error) { if (!strcmp(unit_style, "lj")) { if (quantity == Quantity::UNKNOWN) { return ""; diff --git a/src/NETCDF/netcdf_units.h b/src/NETCDF/netcdf_units.h index bb83d983c8..8ec47a96bf 100644 --- a/src/NETCDF/netcdf_units.h +++ b/src/NETCDF/netcdf_units.h @@ -25,8 +25,9 @@ namespace LAMMPS_NS { class Error; +namespace NetCDFUnits { // type of quantity for per-atom values (used to get the unit) -enum class Quantity { +enum Quantity : int { UNKNOWN = 0, TIME, DISTANCE, @@ -38,7 +39,7 @@ enum class Quantity { // get the name of the unit for the given `quantity` in the given LAMMPS // `unit_style` any error will be reported through `error` std::string get_unit_for(const char* unit_style, Quantity quantity, Error* error); - +} } #endif From 364d0be28c6c81ac74a390050f681af2675e1faa Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 21 Dec 2021 13:20:25 -0500 Subject: [PATCH 07/13] apply clang-format --- src/NETCDF/dump_netcdf.h | 18 ++-- src/NETCDF/dump_netcdf_mpiio.h | 8 +- src/NETCDF/netcdf_units.cpp | 172 ++++++++++++++++----------------- src/NETCDF/netcdf_units.h | 16 +-- 4 files changed, 109 insertions(+), 105 deletions(-) diff --git a/src/NETCDF/dump_netcdf.h b/src/NETCDF/dump_netcdf.h index 2e0a275425..0ee1f63d6d 100644 --- a/src/NETCDF/dump_netcdf.h +++ b/src/NETCDF/dump_netcdf.h @@ -29,7 +29,9 @@ DumpStyle(netcdf,DumpNetCDF); #include "dump_custom.h" namespace LAMMPS_NS { -namespace NetCDFUnits {enum Quantity : int;} // forward declaration +namespace NetCDFUnits { + enum Quantity : int; +} // namespace NetCDFUnits const int NC_FIELD_NAME_MAX = 100; const int DUMP_NC_MAX_DIMS = 100; @@ -43,11 +45,11 @@ class DumpNetCDF : public DumpCustom { private: // per-atoms quantities (positions, velocities, etc.) struct nc_perat_t { - int dims; // number of dimensions - int field[DUMP_NC_MAX_DIMS]; // field indices corresponding to the dim. - char name[NC_FIELD_NAME_MAX]; // field name - int var; // NetCDF variable - NetCDFUnits::Quantity quantity; // type of the quantity + int dims; // number of dimensions + int field[DUMP_NC_MAX_DIMS]; // field indices corresponding to the dim. + char name[NC_FIELD_NAME_MAX]; // field name + int var; // NetCDF variable + NetCDFUnits::Quantity quantity; // type of the quantity bool constant; // is this property per file (not per frame) int ndumped; // number of enties written for this prop. @@ -64,8 +66,8 @@ class DumpNetCDF : public DumpCustom { int *thermovar; // NetCDF variables for thermo output - int type_nc_real; // netcdf type to use for real variables: float or double - bool thermo; // write thermo output to netcdf file + int type_nc_real; // netcdf type to use for real variables: float or double + bool thermo; // write thermo output to netcdf file bigint n_buffer; // size of buffer bigint *int_buffer; // buffer for passing data to netcdf diff --git a/src/NETCDF/dump_netcdf_mpiio.h b/src/NETCDF/dump_netcdf_mpiio.h index da45887b88..1046b86c85 100644 --- a/src/NETCDF/dump_netcdf_mpiio.h +++ b/src/NETCDF/dump_netcdf_mpiio.h @@ -29,7 +29,9 @@ DumpStyle(netcdf/mpiio,DumpNetCDFMPIIO); #include "dump_custom.h" namespace LAMMPS_NS { -namespace NetCDFUnits {enum Quantity : int;} // forward declaration +namespace NetCDFUnits { + enum Quantity : int; +} // namespace NetCDFUnits const int NC_MPIIO_FIELD_NAME_MAX = 100; const int DUMP_NC_MPIIO_MAX_DIMS = 100; @@ -63,8 +65,8 @@ class DumpNetCDFMPIIO : public DumpCustom { int *thermovar; // NetCDF variables for thermo output - int type_nc_real; // netcdf type to use for real variables: float or double - bool thermo; // write thermo output to netcdf file + int type_nc_real; // netcdf type to use for real variables: float or double + bool thermo; // write thermo output to netcdf file bigint n_buffer; // size of buffer bigint *int_buffer; // buffer for passing data to netcdf diff --git a/src/NETCDF/netcdf_units.cpp b/src/NETCDF/netcdf_units.cpp index 907d0d7496..47ae184e42 100644 --- a/src/NETCDF/netcdf_units.cpp +++ b/src/NETCDF/netcdf_units.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -24,7 +23,8 @@ using namespace LAMMPS_NS; -std::string NetCDFUnits::get_unit_for(const char* unit_style, Quantity quantity, Error* error) { +std::string NetCDFUnits::get_unit_for(const char *unit_style, Quantity quantity, Error *error) +{ if (!strcmp(unit_style, "lj")) { if (quantity == Quantity::UNKNOWN) { return ""; @@ -33,108 +33,108 @@ std::string NetCDFUnits::get_unit_for(const char* unit_style, Quantity quantity, } } else if (!strcmp(unit_style, "real")) { switch (quantity) { - case Quantity::UNKNOWN: - return ""; - case Quantity::TIME: - return "femtosecond"; - case Quantity::DISTANCE: - return "angstrom"; - case Quantity::VELOCITY: - return "angstrom/femtosecond"; - case Quantity::FORCE: - return "(Kcal/mol)/angstrom)"; - case Quantity::DIPOLE_MOMENT: - return "e * angstrom"; + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "femtosecond"; + case Quantity::DISTANCE: + return "angstrom"; + case Quantity::VELOCITY: + return "angstrom/femtosecond"; + case Quantity::FORCE: + return "(Kcal/mol)/angstrom)"; + case Quantity::DIPOLE_MOMENT: + return "e * angstrom"; } } else if (!strcmp(unit_style, "metal")) { switch (quantity) { - case Quantity::UNKNOWN: - return ""; - case Quantity::TIME: - return "picosecond"; - case Quantity::DISTANCE: - return "angstrom"; - case Quantity::VELOCITY: - return "angstrom/picosecond"; - case Quantity::FORCE: - return "eV/angstrom"; - case Quantity::DIPOLE_MOMENT: - return "e * angstrom"; + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "picosecond"; + case Quantity::DISTANCE: + return "angstrom"; + case Quantity::VELOCITY: + return "angstrom/picosecond"; + case Quantity::FORCE: + return "eV/angstrom"; + case Quantity::DIPOLE_MOMENT: + return "e * angstrom"; } } else if (!strcmp(unit_style, "si")) { switch (quantity) { - case Quantity::UNKNOWN: - return ""; - case Quantity::TIME: - return "second"; - case Quantity::DISTANCE: - return "meter"; - case Quantity::VELOCITY: - return "meter/second"; - case Quantity::FORCE: - return "Newton"; - case Quantity::DIPOLE_MOMENT: - return "Coulomb * meter"; + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "second"; + case Quantity::DISTANCE: + return "meter"; + case Quantity::VELOCITY: + return "meter/second"; + case Quantity::FORCE: + return "Newton"; + case Quantity::DIPOLE_MOMENT: + return "Coulomb * meter"; } } else if (!strcmp(unit_style, "cgs")) { switch (quantity) { - case Quantity::UNKNOWN: - return ""; - case Quantity::TIME: - return "second"; - case Quantity::DISTANCE: - return "centimeter"; - case Quantity::VELOCITY: - return "centimeter/second"; - case Quantity::FORCE: - return "dynes"; - case Quantity::DIPOLE_MOMENT: - return "statcoul * cm"; + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "second"; + case Quantity::DISTANCE: + return "centimeter"; + case Quantity::VELOCITY: + return "centimeter/second"; + case Quantity::FORCE: + return "dynes"; + case Quantity::DIPOLE_MOMENT: + return "statcoul * cm"; } } else if (!strcmp(unit_style, "electron")) { switch (quantity) { - case Quantity::UNKNOWN: - return ""; - case Quantity::TIME: - return "femtoseconds"; - case Quantity::DISTANCE: - return "Bohr"; - case Quantity::VELOCITY: - return "Bohr/atomic time units"; - case Quantity::FORCE: - return "Hartree/Bohr"; - case Quantity::DIPOLE_MOMENT: - return "Debye"; + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "femtoseconds"; + case Quantity::DISTANCE: + return "Bohr"; + case Quantity::VELOCITY: + return "Bohr/atomic time units"; + case Quantity::FORCE: + return "Hartree/Bohr"; + case Quantity::DIPOLE_MOMENT: + return "Debye"; } } else if (!strcmp(unit_style, "micro")) { switch (quantity) { - case Quantity::UNKNOWN: - return ""; - case Quantity::TIME: - return "microseconds"; - case Quantity::DISTANCE: - return "micrometers"; - case Quantity::VELOCITY: - return "micrometers/microsecond"; - case Quantity::FORCE: - return "picogram * micrometer/microsecond^2"; - case Quantity::DIPOLE_MOMENT: - return "picocoulomb * micrometer"; + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "microseconds"; + case Quantity::DISTANCE: + return "micrometers"; + case Quantity::VELOCITY: + return "micrometers/microsecond"; + case Quantity::FORCE: + return "picogram * micrometer/microsecond^2"; + case Quantity::DIPOLE_MOMENT: + return "picocoulomb * micrometer"; } } else if (!strcmp(unit_style, "nano")) { switch (quantity) { - case Quantity::UNKNOWN: - return ""; - case Quantity::TIME: - return "nanoseconds"; - case Quantity::DISTANCE: - return "nanometers"; - case Quantity::VELOCITY: - return "nanometers/nanosecond"; - case Quantity::FORCE: - return "attogram * nanometer/nanosecond^2"; - case Quantity::DIPOLE_MOMENT: - return "e * nanometer"; + case Quantity::UNKNOWN: + return ""; + case Quantity::TIME: + return "nanoseconds"; + case Quantity::DISTANCE: + return "nanometers"; + case Quantity::VELOCITY: + return "nanometers/nanosecond"; + case Quantity::FORCE: + return "attogram * nanometer/nanosecond^2"; + case Quantity::DIPOLE_MOMENT: + return "e * nanometer"; } } diff --git a/src/NETCDF/netcdf_units.h b/src/NETCDF/netcdf_units.h index 8ec47a96bf..abba927d94 100644 --- a/src/NETCDF/netcdf_units.h +++ b/src/NETCDF/netcdf_units.h @@ -26,21 +26,21 @@ namespace LAMMPS_NS { class Error; namespace NetCDFUnits { -// type of quantity for per-atom values (used to get the unit) -enum Quantity : int { + // type of quantity for per-atom values (used to get the unit) + enum Quantity : int { UNKNOWN = 0, TIME, DISTANCE, VELOCITY, FORCE, DIPOLE_MOMENT, -}; + }; -// get the name of the unit for the given `quantity` in the given LAMMPS -// `unit_style` any error will be reported through `error` -std::string get_unit_for(const char* unit_style, Quantity quantity, Error* error); -} -} + // get the name of the unit for the given `quantity` in the given LAMMPS + // `unit_style` any error will be reported through `error` + std::string get_unit_for(const char *unit_style, Quantity quantity, Error *error); +} // namespace NetCDFUnits +} // namespace LAMMPS_NS #endif #endif From 0576d525ad1715c280c246e35809be365f040d51 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 21 Dec 2021 13:39:00 -0500 Subject: [PATCH 08/13] simplify and avoid redundant output --- src/NETCDF/dump_netcdf.cpp | 8 ++++---- src/NETCDF/dump_netcdf_mpiio.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index 605b480da0..bc715c7b1d 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -888,10 +888,10 @@ int DumpNetCDF::modify_param(int narg, char **arg) void DumpNetCDF::ncerr(int err, const char *descr, int line) { if (err != NC_NOERR) { - if (descr) error->one(FLERR,"NetCDF failed with error '{}' (while accessing '{}') " - " in line {} of {}.", nc_strerror(err), descr, line, __FILE__); - else error->one(FLERR,"NetCDF failed with error '{}' in line {} of {}.", - nc_strerror(err), line, __FILE__); + if (descr) error->one(__FILE__, line, "NetCDF failed with error '{}' (while accessing '{}') ", + nc_strerror(err), descr, line); + else error->one(__FILE__, line,"NetCDF failed with error '{}' in line {} of {}.", + nc_strerror(err)); } } diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index eb117e1dc0..de5c3e3e4a 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -884,10 +884,10 @@ int DumpNetCDFMPIIO::modify_param(int narg, char **arg) void DumpNetCDFMPIIO::ncerr(int err, const char *descr, int line) { if (err != NC_NOERR) { - if (descr) error->one(FLERR,"NetCDF failed with error '{}' (while accessing '{}') " - " in line {} of {}.", ncmpi_strerror(err), descr, line, __FILE__); - else error->one(FLERR,"NetCDF failed with error '{}' in line {} of {}.", - ncmpi_strerror(err), line, __FILE__); + if (descr) error->one(__FILE__, line, "NetCDF failed with error '{}' (while accessing '{}') ", + ncmpi_strerror(err), descr); + else error->one(__FILE__, line,"NetCDF failed with error '{}' in line {} of {}.", + ncmpi_strerror(err)); } } From 3b183bafbb952208a3701bd51ac7fbb9b99becca Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 22 Dec 2021 23:29:56 -0500 Subject: [PATCH 09/13] cosmetic changes (simplify, use constexpr, remove dead code, join wrapped lines) --- src/NETCDF/dump_netcdf.cpp | 5 ++--- src/NETCDF/dump_netcdf.h | 13 +++++------ src/NETCDF/dump_netcdf_mpiio.cpp | 38 ++++++++++++-------------------- src/NETCDF/dump_netcdf_mpiio.h | 13 ++++------- src/NETCDF/netcdf_units.cpp | 2 +- src/NETCDF/netcdf_units.h | 4 ++-- 6 files changed, 28 insertions(+), 47 deletions(-) diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index bc715c7b1d..f455678925 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -66,7 +66,6 @@ static const char NC_SCALE_FACTOR_STR[] = "scale_factor"; static constexpr int THIS_IS_A_FIX = -1; static constexpr int THIS_IS_A_COMPUTE = -2; static constexpr int THIS_IS_A_VARIABLE = -3; -static constexpr int THIS_IS_A_BIGINT = -4; /* ---------------------------------------------------------------------- */ @@ -104,8 +103,8 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : int idim = 0; int ndims = 1; std::string mangled = earg[i]; - Quantity quantity = Quantity::UNKNOWN; bool constant = false; + int quantity = Quantity::UNKNOWN; // name mangling // in the AMBER specification @@ -889,7 +888,7 @@ void DumpNetCDF::ncerr(int err, const char *descr, int line) { if (err != NC_NOERR) { if (descr) error->one(__FILE__, line, "NetCDF failed with error '{}' (while accessing '{}') ", - nc_strerror(err), descr, line); + nc_strerror(err), descr); else error->one(__FILE__, line,"NetCDF failed with error '{}' in line {} of {}.", nc_strerror(err)); } diff --git a/src/NETCDF/dump_netcdf.h b/src/NETCDF/dump_netcdf.h index 0ee1f63d6d..8e468692c5 100644 --- a/src/NETCDF/dump_netcdf.h +++ b/src/NETCDF/dump_netcdf.h @@ -24,17 +24,11 @@ DumpStyle(netcdf,DumpNetCDF); #else #ifndef LMP_DUMP_NETCDF_H -#define LMP_DUMP_NETCDFC_H +#define LMP_DUMP_NETCDF_H #include "dump_custom.h" namespace LAMMPS_NS { -namespace NetCDFUnits { - enum Quantity : int; -} // namespace NetCDFUnits - -const int NC_FIELD_NAME_MAX = 100; -const int DUMP_NC_MAX_DIMS = 100; class DumpNetCDF : public DumpCustom { public: @@ -43,13 +37,16 @@ class DumpNetCDF : public DumpCustom { virtual void write(); private: + static constexpr int NC_FIELD_NAME_MAX = 100; + static constexpr int DUMP_NC_MAX_DIMS = 100; + // per-atoms quantities (positions, velocities, etc.) struct nc_perat_t { int dims; // number of dimensions int field[DUMP_NC_MAX_DIMS]; // field indices corresponding to the dim. char name[NC_FIELD_NAME_MAX]; // field name int var; // NetCDF variable - NetCDFUnits::Quantity quantity; // type of the quantity + int quantity; // type of the quantity bool constant; // is this property per file (not per frame) int ndumped; // number of enties written for this prop. diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index de5c3e3e4a..6d381dcba2 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -66,7 +66,6 @@ static const char NC_SCALE_FACTOR_STR[] = "scale_factor"; static constexpr int THIS_IS_A_FIX = -1; static constexpr int THIS_IS_A_COMPUTE = -2; static constexpr int THIS_IS_A_VARIABLE = -3; -static constexpr int THIS_IS_A_BIGINT = -4; /* ---------------------------------------------------------------------- */ @@ -104,8 +103,7 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : int idim = 0; int ndims = 1; std::string mangled = earg[i]; - bool constant = false; - Quantity quantity = Quantity::UNKNOWN; + int quantity = Quantity::UNKNOWN; // name mangling // in the AMBER specification @@ -123,7 +121,7 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : idim = mangled[0] - 'x'; ndims = 3; mangled = "scaled_coordinates"; - // no quantity for scaled_coordinates + // no unit for scaled coordinates } else if ((mangled == "xu") || (mangled == "yu") || (mangled == "zu")) { idim = mangled[0] - 'x'; ndims = 3; @@ -222,8 +220,7 @@ void DumpNetCDFMPIIO::openfile() char *ptr = strchr(filestar,'*'); *ptr = '\0'; if (padflag == 0) - sprintf(filecurrent,"%s" BIGINT_FORMAT "%s", - filestar,update->ntimestep,ptr+1); + sprintf(filecurrent,"%s" BIGINT_FORMAT "%s", filestar,update->ntimestep,ptr+1); else { char bif[8],pad[16]; strcpy(bif,BIGINT_FORMAT); @@ -286,8 +283,6 @@ void DumpNetCDFMPIIO::openfile() if (!platform::file_is_readable(filecurrent)) error->all(FLERR, "cannot append to non-existent file {}", filecurrent); - MPI_Offset index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; - if (singlefile_opened) return; singlefile_opened = 1; @@ -352,7 +347,6 @@ void DumpNetCDFMPIIO::openfile() int dims[NC_MAX_VAR_DIMS]; MPI_Offset index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; - float d[1]; if (singlefile_opened) return; singlefile_opened = 1; @@ -367,18 +361,18 @@ void DumpNetCDFMPIIO::openfile() NCERRX( ncmpi_def_dim(ncid, NC_LABEL_STR, 10, &label_dim), NC_LABEL_STR ); for (int i = 0; i < n_perat; i++) { - int dims = perat[i].dims; - if (vector_dim[dims] < 0) { + int dim = perat[i].dims; + if (vector_dim[dim] < 0) { char dimstr[1024]; - if (dims == 3) { + if (dim == 3) { strcpy(dimstr, NC_SPATIAL_STR); - } else if (dims == 6) { + } else if (dim == 6) { strcpy(dimstr, NC_VOIGT_STR); } else { - sprintf(dimstr, "vec%i", dims); + sprintf(dimstr, "vec%i", dim); } - if (dims != 1) { - NCERRX( ncmpi_def_dim(ncid, dimstr, dims, &vector_dim[dims]), dimstr ); + if (dim != 1) { + NCERRX( ncmpi_def_dim(ncid, dimstr, dim, &vector_dim[dim]), dimstr ); } } } @@ -489,16 +483,13 @@ void DumpNetCDFMPIIO::openfile() index[1] = 0; count[0] = 1; count[1] = 5; - NCERR( ncmpi_put_vara_text(ncid, cell_angular_var, index, count, - "alpha") ); + NCERR( ncmpi_put_vara_text(ncid, cell_angular_var, index, count, "alpha") ); index[0] = 1; count[1] = 4; - NCERR( ncmpi_put_vara_text(ncid, cell_angular_var, index, count, - "beta") ); + NCERR( ncmpi_put_vara_text(ncid, cell_angular_var, index, count, "beta") ); index[0] = 2; count[1] = 5; - NCERR( ncmpi_put_vara_text(ncid, cell_angular_var, index, count, - "gamma") ); + NCERR( ncmpi_put_vara_text(ncid, cell_angular_var, index, count, "gamma") ); } NCERR( ncmpi_end_indep_data(ncid) ); @@ -886,8 +877,7 @@ void DumpNetCDFMPIIO::ncerr(int err, const char *descr, int line) if (err != NC_NOERR) { if (descr) error->one(__FILE__, line, "NetCDF failed with error '{}' (while accessing '{}') ", ncmpi_strerror(err), descr); - else error->one(__FILE__, line,"NetCDF failed with error '{}' in line {} of {}.", - ncmpi_strerror(err)); + else error->one(__FILE__, line,"NetCDF failed with error '{}'.", ncmpi_strerror(err)); } } diff --git a/src/NETCDF/dump_netcdf_mpiio.h b/src/NETCDF/dump_netcdf_mpiio.h index 1046b86c85..ec6cbaec04 100644 --- a/src/NETCDF/dump_netcdf_mpiio.h +++ b/src/NETCDF/dump_netcdf_mpiio.h @@ -29,12 +29,6 @@ DumpStyle(netcdf/mpiio,DumpNetCDFMPIIO); #include "dump_custom.h" namespace LAMMPS_NS { -namespace NetCDFUnits { - enum Quantity : int; -} // namespace NetCDFUnits - -const int NC_MPIIO_FIELD_NAME_MAX = 100; -const int DUMP_NC_MPIIO_MAX_DIMS = 100; class DumpNetCDFMPIIO : public DumpCustom { public: @@ -43,17 +37,18 @@ class DumpNetCDFMPIIO : public DumpCustom { virtual void write(); private: + static constexpr int NC_MPIIO_FIELD_NAME_MAX = 100; + static constexpr int DUMP_NC_MPIIO_MAX_DIMS = 100; + // per-atoms quantities (positions, velocities, etc.) struct nc_perat_t { int dims; // number of dimensions int field[DUMP_NC_MPIIO_MAX_DIMS]; // field indices corresponding to the dim. char name[NC_MPIIO_FIELD_NAME_MAX]; // field name int var; // NetCDF variable - NetCDFUnits::Quantity quantity; // type of the quantity + int quantity; // type of the quantity }; - typedef void (DumpNetCDFMPIIO::*funcptr_t)(void *); - int framei; // current frame index int blocki; // current block index int ndata; // number of data blocks to expect diff --git a/src/NETCDF/netcdf_units.cpp b/src/NETCDF/netcdf_units.cpp index 47ae184e42..0ee0ebbde0 100644 --- a/src/NETCDF/netcdf_units.cpp +++ b/src/NETCDF/netcdf_units.cpp @@ -23,7 +23,7 @@ using namespace LAMMPS_NS; -std::string NetCDFUnits::get_unit_for(const char *unit_style, Quantity quantity, Error *error) +std::string NetCDFUnits::get_unit_for(const char *unit_style, int quantity, Error *error) { if (!strcmp(unit_style, "lj")) { if (quantity == Quantity::UNKNOWN) { diff --git a/src/NETCDF/netcdf_units.h b/src/NETCDF/netcdf_units.h index abba927d94..abb48965ef 100644 --- a/src/NETCDF/netcdf_units.h +++ b/src/NETCDF/netcdf_units.h @@ -27,7 +27,7 @@ class Error; namespace NetCDFUnits { // type of quantity for per-atom values (used to get the unit) - enum Quantity : int { + enum Quantity { UNKNOWN = 0, TIME, DISTANCE, @@ -38,7 +38,7 @@ namespace NetCDFUnits { // get the name of the unit for the given `quantity` in the given LAMMPS // `unit_style` any error will be reported through `error` - std::string get_unit_for(const char *unit_style, Quantity quantity, Error *error); + std::string get_unit_for(const char *unit_style, int quantity, Error *error); } // namespace NetCDFUnits } // namespace LAMMPS_NS From 30af0cb3256f91878818c2d89ac603408bdda65f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 26 Dec 2021 17:15:13 -0500 Subject: [PATCH 10/13] define and use LMP_MAX_VAR_DIMS instead of NC_MAX_VAR_DIMS to avoid stack overflows --- src/NETCDF/dump_netcdf.cpp | 27 ++++++++++++++------------- src/NETCDF/dump_netcdf_mpiio.cpp | 32 ++++++++++++++++++-------------- src/NETCDF/netcdf_units.h | 3 +++ 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index f455678925..137d6368c2 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -46,6 +46,7 @@ using namespace LAMMPS_NS; using namespace MathConst; using NetCDFUnits::Quantity; using NetCDFUnits::get_unit_for; +using NetCDFUnits::LMP_MAX_VAR_DIMS; static const char NC_FRAME_STR[] = "frame"; static const char NC_SPATIAL_STR[] = "spatial"; @@ -206,7 +207,7 @@ DumpNetCDF::~DumpNetCDF() closefile(); delete[] perat; - if (thermovar) delete[] thermovar; + delete[] thermovar; if (int_buffer) memory->sfree(int_buffer); if (double_buffer) memory->sfree(double_buffer); @@ -234,7 +235,7 @@ void DumpNetCDF::openfile() } if (thermo && !singlefile_opened) { - if (thermovar) delete[] thermovar; + delete[] thermovar; thermovar = new int[output->thermo->nfield]; } @@ -300,18 +301,18 @@ void DumpNetCDF::openfile() NCERRX( nc_inq_dimid(ncid, NC_LABEL_STR, &label_dim), NC_LABEL_STR ); for (int i = 0; i < n_perat; i++) { - int dims = perat[i].dims; - if (vector_dim[dims] < 0) { + int dim = perat[i].dims; + if (vector_dim[dim] < 0) { char dimstr[1024]; - if (dims == 3) { + if (dim == 3) { strcpy(dimstr, NC_SPATIAL_STR); - } else if (dims == 6) { + } else if (dim == 6) { strcpy(dimstr, NC_VOIGT_STR); } else { - sprintf(dimstr, "vec%i", dims); + sprintf(dimstr, "vec%i", dim); } - if (dims != 1) { - NCERRX( nc_inq_dimid(ncid, dimstr, &vector_dim[dims]), dimstr ); + if (dim != 1) { + NCERRX( nc_inq_dimid(ncid, dimstr, &vector_dim[dim]), dimstr ); } } } @@ -349,8 +350,8 @@ void DumpNetCDF::openfile() if (framei != 0 && !multifile) error->all(FLERR,"at keyword requires use of 'append yes'"); - int dims[NC_MAX_VAR_DIMS]; - size_t index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; + int dims[LMP_MAX_VAR_DIMS]; + size_t index[LMP_MAX_VAR_DIMS], count[LMP_MAX_VAR_DIMS]; if (singlefile_opened) return; singlefile_opened = 1; @@ -720,8 +721,8 @@ void DumpNetCDF::write_header(bigint n) void DumpNetCDF::write_data(int n, double *mybuf) { - size_t start[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; - ptrdiff_t stride[NC_MAX_VAR_DIMS]; + size_t start[LMP_MAX_VAR_DIMS], count[LMP_MAX_VAR_DIMS]; + ptrdiff_t stride[LMP_MAX_VAR_DIMS]; if (!int_buffer) { n_buffer = n; diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index 6d381dcba2..a1c9d20e61 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -46,6 +46,7 @@ using namespace LAMMPS_NS; using namespace MathConst; using NetCDFUnits::Quantity; using NetCDFUnits::get_unit_for; +using NetCDFUnits::LMP_MAX_VAR_DIMS; static const char NC_FRAME_STR[] = "frame"; static const char NC_SPATIAL_STR[] = "spatial"; @@ -203,7 +204,7 @@ DumpNetCDFMPIIO::~DumpNetCDFMPIIO() closefile(); delete[] perat; - if (thermovar) delete[] thermovar; + delete[] thermovar; if (int_buffer) memory->sfree(int_buffer); if (double_buffer) memory->sfree(double_buffer); @@ -231,7 +232,7 @@ void DumpNetCDFMPIIO::openfile() } if (thermo && !singlefile_opened) { - if (thermovar) delete[] thermovar; + delete[] thermovar; thermovar = new int[output->thermo->nfield]; } @@ -296,18 +297,18 @@ void DumpNetCDFMPIIO::openfile() NCERRX( ncmpi_inq_dimid(ncid, NC_LABEL_STR, &label_dim), NC_LABEL_STR ); for (int i = 0; i < n_perat; i++) { - int dims = perat[i].dims; - if (vector_dim[dims] < 0) { + int dim = perat[i].dims; + if (vector_dim[dim] < 0) { char dimstr[1024]; - if (dims == 3) { + if (dim == 3) { strcpy(dimstr, NC_SPATIAL_STR); - } else if (dims == 6) { + } else if (dim == 6) { strcpy(dimstr, NC_VOIGT_STR); } else { - sprintf(dimstr, "vec%i", dims); + sprintf(dimstr, "vec%i", dim); } - if (dims != 1) { - NCERRX( ncmpi_inq_dimid(ncid, dimstr, &vector_dim[dims]), dimstr ); + if (dim != 1) { + NCERRX( ncmpi_inq_dimid(ncid, dimstr, &vector_dim[dim]), dimstr ); } } } @@ -345,8 +346,8 @@ void DumpNetCDFMPIIO::openfile() if (framei != 0 && !multifile) error->all(FLERR,"at keyword requires use of 'append yes'"); - int dims[NC_MAX_VAR_DIMS]; - MPI_Offset index[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; + int dims[LMP_MAX_VAR_DIMS]; + MPI_Offset index[LMP_MAX_VAR_DIMS], count[LMP_MAX_VAR_DIMS]; if (singlefile_opened) return; singlefile_opened = 1; @@ -360,6 +361,11 @@ void DumpNetCDFMPIIO::openfile() NCERRX( ncmpi_def_dim(ncid, NC_CELL_ANGULAR_STR, 3, &cell_angular_dim), NC_CELL_ANGULAR_STR ); NCERRX( ncmpi_def_dim(ncid, NC_LABEL_STR, 10, &label_dim), NC_LABEL_STR ); + if (vector_dim[3] < 0) + NCERRX( ncmpi_def_dim(ncid, NC_SPATIAL_STR, 3, &vector_dim[3]), NC_SPATIAL_STR ); + if (vector_dim[6] < 0) + NCERRX( ncmpi_def_dim(ncid, NC_VOIGT_STR, 6, &vector_dim[6]), NC_VOIGT_STR ); + for (int i = 0; i < n_perat; i++) { int dim = perat[i].dims; if (vector_dim[dim] < 0) { @@ -384,7 +390,6 @@ void DumpNetCDFMPIIO::openfile() dims[0] = vector_dim[3]; dims[1] = label_dim; NCERRX( ncmpi_def_var(ncid, NC_CELL_ANGULAR_STR, NC_CHAR, 2, dims, &cell_angular_var), NC_CELL_ANGULAR_STR ); - dims[0] = frame_dim; NCERRX( ncmpi_def_var(ncid, NC_TIME_STR, type_nc_real, 1, dims, &time_var), NC_TIME_STR); dims[0] = frame_dim; @@ -731,8 +736,7 @@ void DumpNetCDFMPIIO::write_time_and_cell() void DumpNetCDFMPIIO::write_data(int n, double *mybuf) { - MPI_Offset start[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; - MPI_Offset stride[NC_MAX_VAR_DIMS]; + MPI_Offset start[LMP_MAX_VAR_DIMS], count[LMP_MAX_VAR_DIMS], stride[LMP_MAX_VAR_DIMS]; if (!int_buffer) { n_buffer = std::max(1, n); diff --git a/src/NETCDF/netcdf_units.h b/src/NETCDF/netcdf_units.h index abb48965ef..85f9b05888 100644 --- a/src/NETCDF/netcdf_units.h +++ b/src/NETCDF/netcdf_units.h @@ -36,6 +36,9 @@ namespace NetCDFUnits { DIPOLE_MOMENT, }; + // for compatibility with older NetCDF versions + static constexpr int LMP_MAX_VAR_DIMS = 1024; + // get the name of the unit for the given `quantity` in the given LAMMPS // `unit_style` any error will be reported through `error` std::string get_unit_for(const char *unit_style, int quantity, Error *error); From 091f6164c81d72b81d5ce5d58ed2a2655a16972c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 26 Dec 2021 23:22:53 -0500 Subject: [PATCH 11/13] add minimal unit test for netcdf dumps --- unittest/formats/CMakeLists.txt | 8 ++ unittest/formats/test_dump_netcdf.cpp | 158 ++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 unittest/formats/test_dump_netcdf.cpp diff --git a/unittest/formats/CMakeLists.txt b/unittest/formats/CMakeLists.txt index a17707fdf1..18bd7d1195 100644 --- a/unittest/formats/CMakeLists.txt +++ b/unittest/formats/CMakeLists.txt @@ -116,6 +116,14 @@ target_link_libraries(test_dump_local PRIVATE lammps GTest::GMock) add_test(NAME DumpLocal COMMAND test_dump_local WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(DumpLocal PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") +if(PKG_NETCDF) + find_program(NCDUMP NAMES ncdump REQUIRED) + add_executable(test_dump_netcdf test_dump_netcdf.cpp) + target_link_libraries(test_dump_netcdf PRIVATE lammps GTest::GMock) + add_test(NAME DumpNetCDF COMMAND test_dump_netcdf WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + set_tests_properties(DumpNetCDF PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};NCDUMP_BINARY=${NCDUMP}") +endif() + if(BUILD_TOOLS) set_tests_properties(DumpAtom PROPERTIES ENVIRONMENT "BINARY2TXT_BINARY=$") set_tests_properties(DumpCustom PROPERTIES ENVIRONMENT "BINARY2TXT_BINARY=$") diff --git a/unittest/formats/test_dump_netcdf.cpp b/unittest/formats/test_dump_netcdf.cpp new file mode 100644 index 0000000000..3aa65fa112 --- /dev/null +++ b/unittest/formats/test_dump_netcdf.cpp @@ -0,0 +1,158 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, 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 "../testing/core.h" +#include "../testing/systems/melt.h" +#include "../testing/utils.h" +#include "fmt/format.h" +#include "library.h" +#include "output.h" +#include "thermo.h" +#include "utils.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include + +using ::testing::Eq; + +char *NCDUMP_BINARY = nullptr; +bool verbose = false; + +class DumpNetCDFTest : public MeltTest { + std::string dump_style = "netcdf"; + +public: + void set_style(const std::string &new_style) { dump_style = new_style; } + + void enable_triclinic() + { + BEGIN_HIDE_OUTPUT(); + command("change_box all triclinic"); + END_HIDE_OUTPUT(); + } + + std::string dump_filename(std::string ident) + { + return fmt::format("dump_{}_{}.nc", dump_style, ident); + } + + void generate_dump(std::string dump_file, std::string fields, std::string dump_modify_options, + int ntimesteps) + { + BEGIN_HIDE_OUTPUT(); + command(fmt::format("dump id all {} 1 {} {}", dump_style, dump_file, fields)); + + if (!dump_modify_options.empty()) { + command(fmt::format("dump_modify id {}", dump_modify_options)); + } + + command(fmt::format("run {} post no", ntimesteps)); + END_HIDE_OUTPUT(); + } + + void continue_dump(int ntimesteps) + { + BEGIN_HIDE_OUTPUT(); + command(fmt::format("run {} pre no post no", ntimesteps)); + END_HIDE_OUTPUT(); + } + + void close_dump() + { + BEGIN_HIDE_OUTPUT(); + command("undump id"); + END_HIDE_OUTPUT(); + } + + std::string convert_binary_to_text(std::string binary_file) + { + BEGIN_HIDE_OUTPUT(); + std::string cmdline = fmt::format("{0} {1} > {1}.txt", NCDUMP_BINARY, binary_file); + system(cmdline.c_str()); + END_HIDE_OUTPUT(); + return fmt::format("{}.txt", binary_file); + } +}; + +TEST_F(DumpNetCDFTest, run0_plain) +{ + if (!lammps_has_style(lmp, "dump", "netcdf")) GTEST_SKIP(); + auto dump_file = dump_filename("run0"); + auto fields = "id type proc procp1 mass x y z ix iy iz xu yu zu vx vy vz fx fy fz"; + set_style("netcdf"); + generate_dump(dump_file, fields, "", 0); + + ASSERT_FILE_EXISTS(dump_file); + if (NCDUMP_BINARY) { + auto converted_file = convert_binary_to_text(dump_file); + auto lines = read_lines(converted_file); + auto words = utils::split_words(lines[0]); + ASSERT_EQ(lines.size(), 233); + ASSERT_THAT(words[0], Eq("netcdf")); + ASSERT_THAT(words[1]+".nc", Eq(dump_file)); + words = utils::split_words(lines[3]); + ASSERT_THAT(words[0], Eq("atom")); + ASSERT_THAT(words[2], Eq("32")); + delete_file(converted_file); + } + delete_file(dump_file); +} + +TEST_F(DumpNetCDFTest, run0_mpi) +{ + if (!lammps_has_style(lmp, "dump", "netcdf/mpiio")) GTEST_SKIP(); + auto dump_file = dump_filename("run0"); + auto fields = "id type proc procp1 mass x y z ix iy iz xu yu zu vx vy vz fx fy fz"; + set_style("netcdf/mpiio"); + generate_dump(dump_file, fields, "", 0); + + ASSERT_FILE_EXISTS(dump_file); + if (NCDUMP_BINARY) { + auto converted_file = convert_binary_to_text(dump_file); + auto lines = read_lines(converted_file); + auto words = utils::split_words(lines[0]); + ASSERT_EQ(lines.size(), 234); + ASSERT_THAT(words[0], Eq("netcdf")); + ASSERT_THAT(words[1]+".nc", Eq(dump_file)); + words = utils::split_words(lines[3]); + ASSERT_THAT(words[0], Eq("atom")); + ASSERT_THAT(words[2], Eq("32")); + delete_file(converted_file); + } + delete_file(dump_file); +} + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + ::testing::InitGoogleMock(&argc, argv); + + // handle arguments passed via environment variable + if (const char *var = getenv("TEST_ARGS")) { + std::vector env = utils::split_words(var); + for (auto arg : env) { + if (arg == "-v") { + verbose = true; + } + } + } + + NCDUMP_BINARY = getenv("NCDUMP_BINARY"); + + if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; + + int rv = RUN_ALL_TESTS(); + MPI_Finalize(); + return rv; +} From 3262140b65f84509f0586d684a13948f7a8d9485 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 27 Dec 2021 10:35:38 -0500 Subject: [PATCH 12/13] more detailed unit tests. do not fail if ncdump is missing. --- unittest/formats/CMakeLists.txt | 6 +- unittest/formats/test_dump_netcdf.cpp | 280 ++++++++++++++++++++++++-- 2 files changed, 271 insertions(+), 15 deletions(-) diff --git a/unittest/formats/CMakeLists.txt b/unittest/formats/CMakeLists.txt index 18bd7d1195..be8e055adb 100644 --- a/unittest/formats/CMakeLists.txt +++ b/unittest/formats/CMakeLists.txt @@ -117,11 +117,13 @@ add_test(NAME DumpLocal COMMAND test_dump_local WORKING_DIRECTORY ${CMAKE_CURREN set_tests_properties(DumpLocal PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") if(PKG_NETCDF) - find_program(NCDUMP NAMES ncdump REQUIRED) + find_program(NCDUMP NAMES ncdump ncdump.exe) add_executable(test_dump_netcdf test_dump_netcdf.cpp) target_link_libraries(test_dump_netcdf PRIVATE lammps GTest::GMock) add_test(NAME DumpNetCDF COMMAND test_dump_netcdf WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_tests_properties(DumpNetCDF PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};NCDUMP_BINARY=${NCDUMP}") + if(NOT (NCDUMP STREQUAL "NCDUMP-NOTFOUND")) + set_tests_properties(DumpNetCDF PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};NCDUMP_BINARY=${NCDUMP}") + endif() endif() if(BUILD_TOOLS) diff --git a/unittest/formats/test_dump_netcdf.cpp b/unittest/formats/test_dump_netcdf.cpp index 3aa65fa112..8b4110b352 100644 --- a/unittest/formats/test_dump_netcdf.cpp +++ b/unittest/formats/test_dump_netcdf.cpp @@ -19,9 +19,11 @@ #include "output.h" #include "thermo.h" #include "utils.h" +#include "version.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include #include using ::testing::Eq; @@ -97,13 +99,139 @@ TEST_F(DumpNetCDFTest, run0_plain) if (NCDUMP_BINARY) { auto converted_file = convert_binary_to_text(dump_file); auto lines = read_lines(converted_file); - auto words = utils::split_words(lines[0]); + auto header = utils::split_words(lines[0]); ASSERT_EQ(lines.size(), 233); - ASSERT_THAT(words[0], Eq("netcdf")); - ASSERT_THAT(words[1]+".nc", Eq(dump_file)); - words = utils::split_words(lines[3]); - ASSERT_THAT(words[0], Eq("atom")); - ASSERT_THAT(words[2], Eq("32")); + ASSERT_THAT(header[0], Eq("netcdf")); + ASSERT_THAT(header[1] + ".nc", Eq(dump_file)); + + // check dimensions section + auto section = std::find(lines.begin(), lines.end(), "dimensions:"); + for (auto line = ++section; line < lines.end(); ++line) { + auto words = utils::split_words(*line); + if ((words.size() < 1) || (words[0] == "variables:")) break; + if (words[0] == "atom") ASSERT_THAT(words[2], Eq("32")); + if (words[0] == "label") ASSERT_THAT(words[2], Eq("10")); + if (words[0] == "Voigt") ASSERT_THAT(words[2], Eq("6")); + if (words[0] == "spatial") ASSERT_THAT(words[2], Eq("3")); + } + + // check variables section + section = std::find(lines.begin(), lines.end(), "variables:"); + for (auto line = ++section; line < lines.end(); ++line) { + auto words = utils::split_words(*line); + if ((words.size() < 2) || (words[0] == "data:")) break; + if (words[0] == "time:units") ASSERT_THAT(words[2], Eq("lj")); + if (words[0] == "time:scale_factor") ASSERT_THAT(words[2], Eq("0.005f")); + if (words[0] == "cell_origin:units") ASSERT_THAT(words[2], Eq("lj")); + if (words[0] == "cell_angles:units") ASSERT_THAT(words[2], Eq("degree")); + if (words[1] == "id(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "type(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "proc(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "procp1(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "mass(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "ix(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "iy(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "iz(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[0] == ":Conventions") ASSERT_THAT(words[2], Eq("AMBER")); + if (words[0] == ":ConventionVersion") ASSERT_THAT(words[2], Eq("1.0")); + if (words[0] == ":program") ASSERT_THAT(words[2], Eq("LAMMPS")); + if (words[0] == ":programVersion") ASSERT_THAT(words[2], Eq(LAMMPS_VERSION)); + } + + // check data section + section = std::find(lines.begin(), lines.end(), "data:"); + for (auto line = ++section; line < lines.end(); ++line) { + auto words = utils::split_words(*line); + if (words.size() > 0) { + if (words[0] == "spatial") ASSERT_THAT(words[2], Eq("xyz")); + if (words[0] == "cell_spatial") ASSERT_THAT(words[2], Eq("abc")); + if (words[0] == "cell_origin") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0,")); + ASSERT_THAT(words[1], Eq("0,")); + ASSERT_THAT(words[2], Eq("0")); + } + if (words[0] == "cell_lengths") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("3.359192,")); + ASSERT_THAT(words[1], Eq("3.359192,")); + ASSERT_THAT(words[2], Eq("3.359192")); + } + if (words[0] == "cell_angles") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("90,")); + ASSERT_THAT(words[1], Eq("90,")); + ASSERT_THAT(words[2], Eq("90")); + } + if (words[0] == "id") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("1,")); + ASSERT_THAT(words[1], Eq("2,")); + ASSERT_THAT(words[2], Eq("3,")); + ASSERT_THAT(words[3], Eq("4,")); + ASSERT_THAT(words[4], Eq("5,")); + ASSERT_THAT(words[5], Eq("6,")); + ASSERT_THAT(words[6], Eq("7,")); + ASSERT_THAT(words[7], Eq("8,")); + ASSERT_THAT(words[8], Eq("9,")); + ASSERT_THAT(words[9], Eq("10,")); + } + if (words[0] == "mass") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("1,")); + ASSERT_THAT(words[1], Eq("1,")); + ASSERT_THAT(words[2], Eq("1,")); + ASSERT_THAT(words[3], Eq("1,")); + ASSERT_THAT(words[4], Eq("1,")); + ASSERT_THAT(words[5], Eq("1,")); + ASSERT_THAT(words[6], Eq("1,")); + ASSERT_THAT(words[7], Eq("1,")); + ASSERT_THAT(words[8], Eq("1,")); + ASSERT_THAT(words[9], Eq("1,")); + } + if (words[0] == "coordinates") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0,")); + ASSERT_THAT(words[1], Eq("0,")); + ASSERT_THAT(words[2], Eq("0,")); + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0.8397981,")); + ASSERT_THAT(words[1], Eq("0.8397981,")); + ASSERT_THAT(words[2], Eq("0,")); + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0.8397981,")); + ASSERT_THAT(words[1], Eq("0,")); + ASSERT_THAT(words[2], Eq("0.8397981,")); + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0,")); + ASSERT_THAT(words[1], Eq("0.8397981,")); + ASSERT_THAT(words[2], Eq("0.8397981,")); + } + if (words[0] == "ix") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0,")); + ASSERT_THAT(words[1], Eq("0,")); + ASSERT_THAT(words[2], Eq("0,")); + ASSERT_THAT(words[3], Eq("0,")); + ASSERT_THAT(words[4], Eq("0,")); + ASSERT_THAT(words[5], Eq("0,")); + ASSERT_THAT(words[6], Eq("0,")); + ASSERT_THAT(words[7], Eq("0,")); + ASSERT_THAT(words[8], Eq("0,")); + ASSERT_THAT(words[9], Eq("0,")); + } + } + } delete_file(converted_file); } delete_file(dump_file); @@ -112,7 +240,7 @@ TEST_F(DumpNetCDFTest, run0_plain) TEST_F(DumpNetCDFTest, run0_mpi) { if (!lammps_has_style(lmp, "dump", "netcdf/mpiio")) GTEST_SKIP(); - auto dump_file = dump_filename("run0"); + auto dump_file = dump_filename("mpi0"); auto fields = "id type proc procp1 mass x y z ix iy iz xu yu zu vx vy vz fx fy fz"; set_style("netcdf/mpiio"); generate_dump(dump_file, fields, "", 0); @@ -121,13 +249,139 @@ TEST_F(DumpNetCDFTest, run0_mpi) if (NCDUMP_BINARY) { auto converted_file = convert_binary_to_text(dump_file); auto lines = read_lines(converted_file); - auto words = utils::split_words(lines[0]); + auto header = utils::split_words(lines[0]); ASSERT_EQ(lines.size(), 234); - ASSERT_THAT(words[0], Eq("netcdf")); - ASSERT_THAT(words[1]+".nc", Eq(dump_file)); - words = utils::split_words(lines[3]); - ASSERT_THAT(words[0], Eq("atom")); - ASSERT_THAT(words[2], Eq("32")); + ASSERT_THAT(header[0], Eq("netcdf")); + ASSERT_THAT(header[1] + ".nc", Eq(dump_file)); + + // check dimensions section + auto section = std::find(lines.begin(), lines.end(), "dimensions:"); + for (auto line = ++section; line < lines.end(); ++line) { + auto words = utils::split_words(*line); + if ((words.size() < 1) || (words[0] == "variables:")) break; + if (words[0] == "atom") ASSERT_THAT(words[2], Eq("32")); + if (words[0] == "label") ASSERT_THAT(words[2], Eq("10")); + if (words[0] == "Voigt") ASSERT_THAT(words[2], Eq("6")); + if (words[0] == "spatial") ASSERT_THAT(words[2], Eq("3")); + } + + // check variables section + section = std::find(lines.begin(), lines.end(), "variables:"); + for (auto line = ++section; line < lines.end(); ++line) { + auto words = utils::split_words(*line); + if ((words.size() < 2) || (words[0] == "data:")) break; + if (words[0] == "time:units") ASSERT_THAT(words[2], Eq("lj")); + if (words[0] == "time:scale_factor") ASSERT_THAT(words[2], Eq("0.005f")); + if (words[0] == "cell_origin:units") ASSERT_THAT(words[2], Eq("lj")); + if (words[0] == "cell_angles:units") ASSERT_THAT(words[2], Eq("degree")); + if (words[1] == "id(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "type(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "proc(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "procp1(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "mass(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "ix(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "iy(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[1] == "iz(frame,") ASSERT_THAT(words[2], Eq("atom)")); + if (words[0] == ":Conventions") ASSERT_THAT(words[2], Eq("AMBER")); + if (words[0] == ":ConventionVersion") ASSERT_THAT(words[2], Eq("1.0")); + if (words[0] == ":program") ASSERT_THAT(words[2], Eq("LAMMPS")); + if (words[0] == ":programVersion") ASSERT_THAT(words[2], Eq(LAMMPS_VERSION)); + } + + // check data section + section = std::find(lines.begin(), lines.end(), "data:"); + for (auto line = ++section; line < lines.end(); ++line) { + auto words = utils::split_words(*line); + if (words.size() > 0) { + if (words[0] == "spatial") ASSERT_THAT(words[2], Eq("xyz")); + if (words[0] == "cell_spatial") ASSERT_THAT(words[2], Eq("abc")); + if (words[0] == "cell_origin") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0,")); + ASSERT_THAT(words[1], Eq("0,")); + ASSERT_THAT(words[2], Eq("0")); + } + if (words[0] == "cell_lengths") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("3.359192,")); + ASSERT_THAT(words[1], Eq("3.359192,")); + ASSERT_THAT(words[2], Eq("3.359192")); + } + if (words[0] == "cell_angles") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("90,")); + ASSERT_THAT(words[1], Eq("90,")); + ASSERT_THAT(words[2], Eq("90")); + } + if (words[0] == "id") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("1,")); + ASSERT_THAT(words[1], Eq("2,")); + ASSERT_THAT(words[2], Eq("3,")); + ASSERT_THAT(words[3], Eq("4,")); + ASSERT_THAT(words[4], Eq("5,")); + ASSERT_THAT(words[5], Eq("6,")); + ASSERT_THAT(words[6], Eq("7,")); + ASSERT_THAT(words[7], Eq("8,")); + ASSERT_THAT(words[8], Eq("9,")); + ASSERT_THAT(words[9], Eq("10,")); + } + if (words[0] == "mass") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("1,")); + ASSERT_THAT(words[1], Eq("1,")); + ASSERT_THAT(words[2], Eq("1,")); + ASSERT_THAT(words[3], Eq("1,")); + ASSERT_THAT(words[4], Eq("1,")); + ASSERT_THAT(words[5], Eq("1,")); + ASSERT_THAT(words[6], Eq("1,")); + ASSERT_THAT(words[7], Eq("1,")); + ASSERT_THAT(words[8], Eq("1,")); + ASSERT_THAT(words[9], Eq("1,")); + } + if (words[0] == "coordinates") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0,")); + ASSERT_THAT(words[1], Eq("0,")); + ASSERT_THAT(words[2], Eq("0,")); + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0.8397981,")); + ASSERT_THAT(words[1], Eq("0.8397981,")); + ASSERT_THAT(words[2], Eq("0,")); + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0.8397981,")); + ASSERT_THAT(words[1], Eq("0,")); + ASSERT_THAT(words[2], Eq("0.8397981,")); + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0,")); + ASSERT_THAT(words[1], Eq("0.8397981,")); + ASSERT_THAT(words[2], Eq("0.8397981,")); + } + if (words[0] == "ix") { + ++line; + words = utils::split_words(*line); + ASSERT_THAT(words[0], Eq("0,")); + ASSERT_THAT(words[1], Eq("0,")); + ASSERT_THAT(words[2], Eq("0,")); + ASSERT_THAT(words[3], Eq("0,")); + ASSERT_THAT(words[4], Eq("0,")); + ASSERT_THAT(words[5], Eq("0,")); + ASSERT_THAT(words[6], Eq("0,")); + ASSERT_THAT(words[7], Eq("0,")); + ASSERT_THAT(words[8], Eq("0,")); + ASSERT_THAT(words[9], Eq("0,")); + } + } + } delete_file(converted_file); } delete_file(dump_file); From 47b0c8b33edf14cf60f95bbb8fe2959b0653a6ba Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 27 Dec 2021 11:31:01 -0500 Subject: [PATCH 13/13] whitespace --- src/NETCDF/dump_netcdf.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/NETCDF/dump_netcdf.h b/src/NETCDF/dump_netcdf.h index 8e468692c5..f3a4e81d9c 100644 --- a/src/NETCDF/dump_netcdf.h +++ b/src/NETCDF/dump_netcdf.h @@ -37,16 +37,16 @@ class DumpNetCDF : public DumpCustom { virtual void write(); private: - static constexpr int NC_FIELD_NAME_MAX = 100; - static constexpr int DUMP_NC_MAX_DIMS = 100; + static constexpr int NC_FIELD_NAME_MAX = 100; + static constexpr int DUMP_NC_MAX_DIMS = 100; // per-atoms quantities (positions, velocities, etc.) struct nc_perat_t { - int dims; // number of dimensions - int field[DUMP_NC_MAX_DIMS]; // field indices corresponding to the dim. - char name[NC_FIELD_NAME_MAX]; // field name - int var; // NetCDF variable - int quantity; // type of the quantity + int dims; // number of dimensions + int field[DUMP_NC_MAX_DIMS]; // field indices corresponding to the dim. + char name[NC_FIELD_NAME_MAX]; // field name + int var; // NetCDF variable + int quantity; // type of the quantity bool constant; // is this property per file (not per frame) int ndumped; // number of enties written for this prop.