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