switch dump yaml/netcdf thermo output to use new caching API. remove old API.

This commit is contained in:
Axel Kohlmeyer
2023-06-06 22:40:13 -04:00
parent 14acb3e0ca
commit b81b1f5ecc
6 changed files with 87 additions and 93 deletions

View File

@ -753,9 +753,12 @@ run, this option is ignored since the output is already balanced.
----------
The *thermo* keyword only applies the dump styles *netcdf* and *yaml*.
It triggers writing of :doc:`thermo <thermo>` information to the dump file
alongside per-atom data. The values included in the dump file are
identical to the values specified by :doc:`thermo_style <thermo_style>`.
It triggers writing of :doc:`thermo <thermo>` information to the dump
file alongside per-atom data. The values included in the dump file are
cached values from the last thermo output and include the exact same the
values as specified by the :doc:`thermo_style <thermo_style>` command.
Because these are cached values, they are only up-to-date when dump
output is on a timestep that also has thermo output.
----------

View File

@ -60,21 +60,26 @@ void DumpYAML::write_header(bigint ndump)
std::string thermo_data;
if (thermo) {
Thermo *th = output->thermo;
thermo_data += "thermo:\n - keywords: [ ";
for (int i = 0; i < th->nfield; ++i) thermo_data += fmt::format("{}, ", th->keyword[i]);
thermo_data += "]\n - data: [ ";
// output thermo data only on timesteps where it was computed
if (update->ntimestep == th->get_timestep()) {
for (int i = 0; i < th->nfield; ++i) {
th->call_vfunc(i);
if (th->vtype[i] == Thermo::FLOAT)
thermo_data += fmt::format("{}, ", th->dvalue);
else if (th->vtype[i] == Thermo::INT)
thermo_data += fmt::format("{}, ", th->ivalue);
else if (th->vtype[i] == Thermo::BIGINT)
thermo_data += fmt::format("{}, ", th->bivalue);
thermo_data += "thermo:\n - keywords: [ ";
for (auto key : th->get_keywords()) thermo_data += fmt::format("{}, ", key);
thermo_data += "]\n - data: [ ";
for (auto val : th->get_fields()) {
if (val.type == multitype::DOUBLE)
thermo_data += fmt::format("{}, ", val.data.d);
else if (val.type == multitype::INT)
thermo_data += fmt::format("{}, ", val.data.i);
else if (val.type == multitype::BIGINT)
thermo_data += fmt::format("{}, ", val.data.b);
else
thermo_data += ", ";
}
thermo_data += "]\n";
MPI_Barrier(world);
}
thermo_data += "]\n";
MPI_Barrier(world);
}
if (comm->me == 0) {

View File

@ -223,7 +223,7 @@ void DumpNetCDF::openfile()
if (thermo && !singlefile_opened) {
delete[] thermovar;
thermovar = new int[output->thermo->nfield];
thermovar = new int[output->thermo->get_keywords().size()];
}
// now the computes and fixes have been initialized, so we can query
@ -320,9 +320,10 @@ void DumpNetCDF::openfile()
// perframe variables
if (thermo) {
Thermo *th = output->thermo;
for (int i = 0; i < th->nfield; i++) {
NCERRX( nc_inq_varid(ncid, th->keyword[i].c_str(), &thermovar[i]), th->keyword[i].c_str() );
auto keywords = output->thermo->get_keywords();
int nfield = keywords.size();
for (int i = 0; i < nfield; i++) {
NCERRX( nc_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() );
}
}
@ -432,22 +433,16 @@ void DumpNetCDF::openfile()
// perframe variables
if (thermo) {
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].c_str(), type_nc_real, 1, dims,
&thermovar[i]), th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::INT) {
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_INT, 1, dims,
&thermovar[i]), th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::BIGINT) {
#if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG)
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_INT64, 1, dims,
&thermovar[i]), th->keyword[i].c_str() );
#else
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_LONG, 1, dims,
&thermovar[i]), th->keyword[i].c_str() );
#endif
auto fields = output->thermo->get_fields();
auto keywords = output->thermo->get_keywords();
int nfield = fields.size();
for (int i = 0; i < nfield; i++) {
if (fields[i].type == multitype::DOUBLE) {
NCERRX( nc_def_var(ncid, keywords[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), keywords[i].c_str() );
} else if (fields[i].type == multitype::INT) {
NCERRX( nc_def_var(ncid, keywords[i].c_str(), NC_INT, 1, dims, &thermovar[i]), keywords[i].c_str() );
} else if (fields[i].type == multitype::BIGINT) {
NCERRX( nc_def_var(ncid, keywords[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), keywords[i].c_str() );
}
}
}
@ -605,20 +600,17 @@ void DumpNetCDF::write()
start[1] = 0;
if (thermo) {
Thermo *th = output->thermo;
for (int i = 0; i < th->nfield; i++) {
th->call_vfunc(i);
auto keywords = output->thermo->get_keywords();
auto fields = output->thermo->get_fields();
int nfield = fields.size();
for (int i = 0; i < nfield; i++) {
if (filewriter) {
if (th->vtype[i] == Thermo::FLOAT) {
NCERRX( nc_put_var1_double(ncid, thermovar[i], start,
&th->dvalue),
th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::INT) {
NCERRX( nc_put_var1_int(ncid, thermovar[i], start, &th->ivalue),
th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::BIGINT) {
NCERRX( nc_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue),
th->keyword[i].c_str() );
if (fields[i].type == multitype::DOUBLE) {
NCERRX( nc_put_var1_double(ncid, thermovar[i], start, &fields[i].data.d), keywords[i].c_str() );
} else if (fields[i].type == multitype::INT) {
NCERRX( nc_put_var1_int(ncid, thermovar[i], start, &fields[i].data.i), keywords[i].c_str() );
} else if (fields[i].type == multitype::BIGINT) {
NCERRX( nc_put_var1_bigint(ncid, thermovar[i], start, &fields[i].data.b), keywords[i].c_str() );
}
}
}

View File

@ -220,7 +220,7 @@ void DumpNetCDFMPIIO::openfile()
if (thermo && !singlefile_opened) {
delete[] thermovar;
thermovar = new int[output->thermo->nfield];
thermovar = new int[output->thermo->get_keywords().size()];
}
// now the computes and fixes have been initialized, so we can query
@ -318,9 +318,10 @@ void DumpNetCDFMPIIO::openfile()
// perframe variables
if (thermo) {
Thermo *th = output->thermo;
for (int i = 0; i < th->nfield; i++) {
NCERRX( ncmpi_inq_varid(ncid, th->keyword[i].c_str(), &thermovar[i]), th->keyword[i].c_str() );
auto keywords = output->thermo->get_keywords();
int nfield = keywords.size();
for (int i = 0; i < nfield; i++) {
NCERRX( ncmpi_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() );
}
}
@ -422,18 +423,16 @@ void DumpNetCDFMPIIO::openfile()
// perframe variables
if (thermo) {
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].c_str(), type_nc_real, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::INT) {
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_INT, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::BIGINT) {
#if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG)
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
#else
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_LONG, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
#endif
auto fields = output->thermo->get_fields();
auto keywords = output->thermo->get_keywords();
int nfield = fields.size();
for (int i = 0; i < nfield; i++) {
if (fields[i].type == multitype::DOUBLE) {
NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), keywords[i].c_str() );
} else if (fields[i].type == multitype::INT) {
NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), NC_INT, 1, dims, &thermovar[i]), keywords[i].c_str() );
} else if (fields[i].type == multitype::BIGINT) {
NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), keywords[i].c_str() );
}
}
}
@ -594,20 +593,17 @@ void DumpNetCDFMPIIO::write()
NCERR( ncmpi_begin_indep_data(ncid) );
if (thermo) {
Thermo *th = output->thermo;
for (int i = 0; i < th->nfield; i++) {
th->call_vfunc(i);
auto keywords = output->thermo->get_keywords();
auto fields = output->thermo->get_fields();
int nfield = fields.size();
for (int i = 0; i < nfield; i++) {
if (filewriter) {
if (th->vtype[i] == Thermo::FLOAT) {
NCERRX( ncmpi_put_var1_double(ncid, thermovar[i], start,
&th->dvalue),
th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::INT) {
NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &th->ivalue),
th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::BIGINT) {
NCERRX( ncmpi_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue),
th->keyword[i].c_str() );
if (fields[i].type == multitype::DOUBLE) {
NCERRX( ncmpi_put_var1_double(ncid, thermovar[i], start, &fields[i].data.d), keywords[i].c_str() );
} else if (fields[i].type == multitype::INT) {
NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &fields[i].data.i), keywords[i].c_str() );
} else if (fields[i].type == multitype::BIGINT) {
NCERRX( ncmpi_put_var1_bigint(ncid, thermovar[i], start, &fields[i].data.b), keywords[i].c_str() );
}
}
}

View File

@ -361,7 +361,7 @@ void Thermo::compute(int flag)
int i;
firststep = flag;
bigint ntimestep = update->ntimestep;
ntimestep = update->ntimestep;
// check for lost atoms
// turn off normflag if natoms = 0 to avoid divide by 0
@ -405,18 +405,23 @@ void Thermo::compute(int flag)
}
// add each thermo value to line with its specific format
field_data.clear();
field_data.resize(nfield);
for (ifield = 0; ifield < nfield; ifield++) {
(this->*vfunc[ifield])();
if (vtype[ifield] == FLOAT) {
snprintf(fmtbuf, sizeof(fmtbuf), format[ifield].c_str(), dvalue);
line += fmtbuf;
field_data[ifield] = dvalue;
} else if (vtype[ifield] == INT) {
snprintf(fmtbuf, sizeof(fmtbuf), format[ifield].c_str(), ivalue);
line += fmtbuf;
field_data[ifield] = ivalue;
} else if (vtype[ifield] == BIGINT) {
snprintf(fmtbuf, sizeof(fmtbuf), format[ifield].c_str(), bivalue);
line += fmtbuf;
field_data[ifield] = bivalue;
}
}
@ -433,16 +438,6 @@ void Thermo::compute(int flag)
firststep = 1;
}
/* ----------------------------------------------------------------------
call function to compute property
------------------------------------------------------------------------- */
void Thermo::call_vfunc(int ifield_in)
{
ifield = ifield_in;
(this->*vfunc[ifield])();
}
/* ----------------------------------------------------------------------
check for lost atoms, return current number of atoms
also could number of warnings across MPI ranks and update total

View File

@ -21,9 +21,6 @@ namespace LAMMPS_NS {
class Thermo : protected Pointers {
friend class MinCG; // accesses compute_pe
friend class DumpNetCDF; // accesses thermo properties
friend class DumpNetCDFMPIIO; // accesses thermo properties
friend class DumpYAML; // accesses thermo properties
public:
char *style;
@ -45,6 +42,11 @@ class Thermo : protected Pointers {
void compute(int);
int evaluate_keyword(const std::string &, double *);
// for accessing cached thermo data
bigint get_timestep() const { return ntimestep; }
const std::vector<multitype> &get_fields() const { return field_data; }
const std::vector<std::string> &get_keywords() const { return keyword; }
private:
int nfield, nfield_initial;
int *vtype;
@ -52,6 +54,7 @@ class Thermo : protected Pointers {
std::vector<std::string> keyword, format, format_column_user, keyword_user;
std::string format_line_user, format_float_user, format_int_user, format_bigint_user;
std::map<std::string, int> key2col;
std::vector<multitype> field_data;
int normvalue; // use this for normflag unless natoms = 0
int normuserflag; // 0 if user has not set, 1 if has
@ -66,6 +69,7 @@ class Thermo : protected Pointers {
bigint last_step;
bigint natoms;
bigint ntimestep;
// data used by routines that compute single values
int ivalue; // integer value to print
@ -114,7 +118,6 @@ class Thermo : protected Pointers {
typedef void (Thermo::*FnPtr)();
void addfield(const char *, FnPtr, int);
FnPtr *vfunc; // list of ptrs to functions
void call_vfunc(int ifield);
void compute_compute(); // functions that compute a single value
void compute_fix(); // via calls to Compute,Fix,Variable classes