add API to library interface to access last thermo data
This commit is contained in:
@ -61,8 +61,8 @@ void DumpYAML::write_header(bigint ndump)
|
|||||||
if (thermo) {
|
if (thermo) {
|
||||||
Thermo *th = output->thermo;
|
Thermo *th = output->thermo;
|
||||||
// output thermo data only on timesteps where it was computed
|
// output thermo data only on timesteps where it was computed
|
||||||
if (update->ntimestep == th->get_timestep()) {
|
if (update->ntimestep == *th->get_timestep()) {
|
||||||
int nfield = th->get_nfield();
|
int nfield = *th->get_nfield();
|
||||||
const auto &keywords = th->get_keywords();
|
const auto &keywords = th->get_keywords();
|
||||||
const auto &fields = th->get_fields();
|
const auto &fields = th->get_fields();
|
||||||
|
|
||||||
|
|||||||
@ -224,7 +224,7 @@ void DumpNetCDF::openfile()
|
|||||||
|
|
||||||
if (thermo && !singlefile_opened) {
|
if (thermo && !singlefile_opened) {
|
||||||
delete[] thermovar;
|
delete[] thermovar;
|
||||||
thermovar = new int[output->thermo->get_nfield()];
|
thermovar = new int[*output->thermo->get_nfield()];
|
||||||
}
|
}
|
||||||
|
|
||||||
// now the computes and fixes have been initialized, so we can query
|
// now the computes and fixes have been initialized, so we can query
|
||||||
@ -323,7 +323,7 @@ void DumpNetCDF::openfile()
|
|||||||
if (thermo) {
|
if (thermo) {
|
||||||
Thermo *th = output->thermo;
|
Thermo *th = output->thermo;
|
||||||
const auto &keywords = th->get_keywords();
|
const auto &keywords = th->get_keywords();
|
||||||
const int nfield = th->get_nfield();
|
const int nfield = *th->get_nfield();
|
||||||
|
|
||||||
for (int i = 0; i < nfield; i++) {
|
for (int i = 0; i < nfield; i++) {
|
||||||
NCERRX( nc_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() );
|
NCERRX( nc_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() );
|
||||||
@ -439,7 +439,7 @@ void DumpNetCDF::openfile()
|
|||||||
Thermo *th = output->thermo;
|
Thermo *th = output->thermo;
|
||||||
const auto &fields = th->get_fields();
|
const auto &fields = th->get_fields();
|
||||||
const auto &keywords = th->get_keywords();
|
const auto &keywords = th->get_keywords();
|
||||||
const int nfield = th->get_nfield();
|
const int nfield = *th->get_nfield();
|
||||||
|
|
||||||
for (int i = 0; i < nfield; i++) {
|
for (int i = 0; i < nfield; i++) {
|
||||||
if (fields[i].type == multitype::DOUBLE) {
|
if (fields[i].type == multitype::DOUBLE) {
|
||||||
@ -610,18 +610,18 @@ void DumpNetCDF::write()
|
|||||||
// will output current thermo data only on timesteps where it was computed.
|
// will output current thermo data only on timesteps where it was computed.
|
||||||
// warn (once) about using cached copy from old timestep.
|
// warn (once) about using cached copy from old timestep.
|
||||||
|
|
||||||
if (thermo_warn && (update->ntimestep != th->get_timestep())) {
|
if (thermo_warn && (update->ntimestep != *th->get_timestep())) {
|
||||||
thermo_warn = false;
|
thermo_warn = false;
|
||||||
if (comm->me == 0) {
|
if (comm->me == 0) {
|
||||||
error->warning(FLERR, "Dump {} output on incompatible timestep with thermo output: {} vs {} \n"
|
error->warning(FLERR, "Dump {} output on incompatible timestep with thermo output: {} vs {} \n"
|
||||||
" Dump netcdf always stores thermo data from last thermo output",
|
" Dump netcdf always stores thermo data from last thermo output",
|
||||||
id, th->get_timestep(), update->ntimestep);
|
id, *th->get_timestep(), update->ntimestep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &keywords = th->get_keywords();
|
const auto &keywords = th->get_keywords();
|
||||||
const auto &fields = th->get_fields();
|
const auto &fields = th->get_fields();
|
||||||
int nfield = th->get_nfield();
|
int nfield = *th->get_nfield();
|
||||||
for (int i = 0; i < nfield; i++) {
|
for (int i = 0; i < nfield; i++) {
|
||||||
if (filewriter) {
|
if (filewriter) {
|
||||||
if (fields[i].type == multitype::DOUBLE) {
|
if (fields[i].type == multitype::DOUBLE) {
|
||||||
|
|||||||
@ -221,7 +221,7 @@ void DumpNetCDFMPIIO::openfile()
|
|||||||
|
|
||||||
if (thermo && !singlefile_opened) {
|
if (thermo && !singlefile_opened) {
|
||||||
delete[] thermovar;
|
delete[] thermovar;
|
||||||
thermovar = new int[output->thermo->get_nfield()];
|
thermovar = new int[*output->thermo->get_nfield()];
|
||||||
}
|
}
|
||||||
|
|
||||||
// now the computes and fixes have been initialized, so we can query
|
// now the computes and fixes have been initialized, so we can query
|
||||||
@ -321,7 +321,7 @@ void DumpNetCDFMPIIO::openfile()
|
|||||||
if (thermo) {
|
if (thermo) {
|
||||||
Thermo *th = output->thermo;
|
Thermo *th = output->thermo;
|
||||||
const auto &keywords = th->get_keywords();
|
const auto &keywords = th->get_keywords();
|
||||||
const int nfield = th->get_nfield();
|
const int nfield = *th->get_nfield();
|
||||||
|
|
||||||
for (int i = 0; i < nfield; i++) {
|
for (int i = 0; i < nfield; i++) {
|
||||||
NCERRX( ncmpi_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() );
|
NCERRX( ncmpi_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() );
|
||||||
@ -429,7 +429,7 @@ void DumpNetCDFMPIIO::openfile()
|
|||||||
Thermo *th = output->thermo;
|
Thermo *th = output->thermo;
|
||||||
const auto &fields = th->get_fields();
|
const auto &fields = th->get_fields();
|
||||||
const auto &keywords = th->get_keywords();
|
const auto &keywords = th->get_keywords();
|
||||||
const int nfield = th->get_nfield();
|
const int nfield = *th->get_nfield();
|
||||||
|
|
||||||
for (int i = 0; i < nfield; i++) {
|
for (int i = 0; i < nfield; i++) {
|
||||||
if (fields[i].type == multitype::DOUBLE) {
|
if (fields[i].type == multitype::DOUBLE) {
|
||||||
@ -603,18 +603,18 @@ void DumpNetCDFMPIIO::write()
|
|||||||
// will output current thermo data only on timesteps where it was computed.
|
// will output current thermo data only on timesteps where it was computed.
|
||||||
// warn (once) about using cached copy from old timestep.
|
// warn (once) about using cached copy from old timestep.
|
||||||
|
|
||||||
if (thermo_warn && (update->ntimestep != th->get_timestep())) {
|
if (thermo_warn && (update->ntimestep != *th->get_timestep())) {
|
||||||
thermo_warn = false;
|
thermo_warn = false;
|
||||||
if (comm->me == 0) {
|
if (comm->me == 0) {
|
||||||
error->warning(FLERR, "Dump {} output on incompatible timestep with thermo output: {} vs {} \n"
|
error->warning(FLERR, "Dump {} output on incompatible timestep with thermo output: {} vs {} \n"
|
||||||
" Dump netcdf/mpiio always stores thermo data from last thermo output",
|
" Dump netcdf/mpiio always stores thermo data from last thermo output",
|
||||||
id, th->get_timestep(), update->ntimestep);
|
id, *th->get_timestep(), update->ntimestep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &keywords = th->get_keywords();
|
const auto &keywords = th->get_keywords();
|
||||||
const auto &fields = th->get_fields();
|
const auto &fields = th->get_fields();
|
||||||
int nfield = th->get_nfield();
|
int nfield = *th->get_nfield();
|
||||||
for (int i = 0; i < nfield; i++) {
|
for (int i = 0; i < nfield; i++) {
|
||||||
if (filewriter) {
|
if (filewriter) {
|
||||||
if (fields[i].type == multitype::DOUBLE) {
|
if (fields[i].type == multitype::DOUBLE) {
|
||||||
|
|||||||
@ -719,7 +719,7 @@ double lammps_get_natoms(void *handle)
|
|||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
/** Get current value of a thermo keyword.
|
/** Evaluate a thermo keyword.
|
||||||
*
|
*
|
||||||
\verbatim embed:rst
|
\verbatim embed:rst
|
||||||
|
|
||||||
@ -750,6 +750,103 @@ double lammps_get_thermo(void *handle, const char *keyword)
|
|||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/** Access cached data from last thermo output
|
||||||
|
*
|
||||||
|
\verbatim embed:rst
|
||||||
|
|
||||||
|
This function provides access to cached data from the last thermo
|
||||||
|
output. This differs from :cpp:func:`lammps_get_thermo` in that it does
|
||||||
|
not trigger an evaluation. It provides direct access to a a read-only
|
||||||
|
location of the last thermo output data and the corresponding keyword
|
||||||
|
strings. The output depends on the value of the *what* argument string.
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:header-rows: 1
|
||||||
|
:widths: auto
|
||||||
|
|
||||||
|
* - Value of *what
|
||||||
|
- Description of return value
|
||||||
|
- Data type
|
||||||
|
- Uses index
|
||||||
|
* - step
|
||||||
|
- timestep when the last thermo output was generated or -1 when no data available
|
||||||
|
- pointer to bigint cast to void pointer
|
||||||
|
- no
|
||||||
|
* - num
|
||||||
|
- number of fields in thermo output
|
||||||
|
- pointer to int cast to void pointer
|
||||||
|
- no
|
||||||
|
* - keyword
|
||||||
|
- column keyword for thermo output
|
||||||
|
- const char pointer cast to void pointer
|
||||||
|
- yes
|
||||||
|
* - type
|
||||||
|
- data type of thermo output column. LAMMPS_INT, LAMMPS_DOUBLE, or LAMMPS_INT64
|
||||||
|
- const int cast to void pointer
|
||||||
|
- yes
|
||||||
|
* - data
|
||||||
|
- actual field data for column
|
||||||
|
- pointer to either int, int64_t or double cast to void pointer
|
||||||
|
- yes
|
||||||
|
|
||||||
|
\endverbatim
|
||||||
|
*
|
||||||
|
* \param handle pointer to a previously created LAMMPS instance
|
||||||
|
* \param what string with the kind of data requested
|
||||||
|
* \param idx integer with index into data arrays, ignored for scalar data
|
||||||
|
* \return pointer to location of requested data cast to void or NULL */
|
||||||
|
|
||||||
|
void *lammps_last_thermo(void *handle, const char *what, int idx)
|
||||||
|
{
|
||||||
|
auto lmp = (LAMMPS *) handle;
|
||||||
|
void *val = nullptr;
|
||||||
|
Thermo *th = lmp->output->thermo;
|
||||||
|
if (!th) return nullptr;
|
||||||
|
const int nfield = *th->get_nfield();
|
||||||
|
|
||||||
|
BEGIN_CAPTURE
|
||||||
|
{
|
||||||
|
if (strcmp(what, "step") == 0) {
|
||||||
|
val = (void *) th->get_timestep();
|
||||||
|
|
||||||
|
} else if (strcmp(what, "num") == 0) {
|
||||||
|
val = (void *) th->get_nfield();
|
||||||
|
|
||||||
|
} else if (strcmp(what, "keyword") == 0) {
|
||||||
|
if ((idx < 0) || (idx >= nfield)) return nullptr;
|
||||||
|
const auto &keywords = th->get_keywords();
|
||||||
|
val = (void *) keywords[idx].c_str();
|
||||||
|
|
||||||
|
} else if (strcmp(what, "type") == 0) {
|
||||||
|
if ((idx < 0) || (idx >= nfield)) return nullptr;
|
||||||
|
const auto &field = th->get_fields()[idx];
|
||||||
|
if (field.type == multitype::INT) {
|
||||||
|
val = (void *) LAMMPS_INT;
|
||||||
|
} else if (field.type == multitype::BIGINT) {
|
||||||
|
val = (void *) LAMMPS_INT64;
|
||||||
|
} else if (field.type == multitype::DOUBLE) {
|
||||||
|
val = (void *) LAMMPS_DOUBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (strcmp(what, "data") == 0) {
|
||||||
|
if ((idx < 0) || (idx >= nfield)) return nullptr;
|
||||||
|
const auto &field = th->get_fields()[idx];
|
||||||
|
if (field.type == multitype::INT) {
|
||||||
|
val = (void *) &field.data.i;
|
||||||
|
} else if (field.type == multitype::BIGINT) {
|
||||||
|
val = (void *) &field.data.b;
|
||||||
|
} else if (field.type == multitype::DOUBLE) {
|
||||||
|
val = (void *) &field.data.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else val = nullptr;
|
||||||
|
}
|
||||||
|
END_CAPTURE
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
/** Extract simulation box parameters.
|
/** Extract simulation box parameters.
|
||||||
*
|
*
|
||||||
\verbatim embed:rst
|
\verbatim embed:rst
|
||||||
|
|||||||
@ -148,6 +148,7 @@ void lammps_commands_string(void *handle, const char *str);
|
|||||||
|
|
||||||
double lammps_get_natoms(void *handle);
|
double lammps_get_natoms(void *handle);
|
||||||
double lammps_get_thermo(void *handle, const char *keyword);
|
double lammps_get_thermo(void *handle, const char *keyword);
|
||||||
|
void *lammps_last_thermo(void *handle, const char *what, int idx);
|
||||||
|
|
||||||
void lammps_extract_box(void *handle, double *boxlo, double *boxhi, double *xy, double *yz,
|
void lammps_extract_box(void *handle, double *boxlo, double *boxhi, double *xy, double *yz,
|
||||||
double *xz, int *pflags, int *boxflag);
|
double *xz, int *pflags, int *boxflag);
|
||||||
|
|||||||
@ -111,6 +111,7 @@ Thermo::Thermo(LAMMPS *_lmp, int narg, char **arg) :
|
|||||||
lostflag = lostbond = Thermo::ERROR;
|
lostflag = lostbond = Thermo::ERROR;
|
||||||
lostbefore = warnbefore = 0;
|
lostbefore = warnbefore = 0;
|
||||||
flushflag = 0;
|
flushflag = 0;
|
||||||
|
ntimestep = -1;
|
||||||
|
|
||||||
// set style and corresponding lineflag
|
// set style and corresponding lineflag
|
||||||
// custom style builds its own line of keywords, including wildcard expansion
|
// custom style builds its own line of keywords, including wildcard expansion
|
||||||
|
|||||||
@ -43,8 +43,8 @@ class Thermo : protected Pointers {
|
|||||||
int evaluate_keyword(const std::string &, double *);
|
int evaluate_keyword(const std::string &, double *);
|
||||||
|
|
||||||
// for accessing cached thermo data
|
// for accessing cached thermo data
|
||||||
int get_nfield() const { return nfield; }
|
const int *get_nfield() const { return &nfield; }
|
||||||
bigint get_timestep() const { return ntimestep; }
|
const bigint *get_timestep() const { return &ntimestep; }
|
||||||
const std::vector<multitype> &get_fields() const { return field_data; }
|
const std::vector<multitype> &get_fields() const { return field_data; }
|
||||||
const std::vector<std::string> &get_keywords() const { return keyword; }
|
const std::vector<std::string> &get_keywords() const { return keyword; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user