Skip to content
Snippets Groups Projects
Commit d51cee1b authored by Lars Pastewka's avatar Lars Pastewka
Browse files

MAINT: Turned 'global' options into a 'thermo yes'/'thermo no' option that...

MAINT: Turned 'global' options into a 'thermo yes'/'thermo no' option that enables dumping of thermo data to the netcdf file (for parallel NetCDF/MPIIO variant).
parent be476c9e
No related branches found
No related tags found
No related merge requests found
...@@ -55,11 +55,13 @@ ...@@ -55,11 +55,13 @@
#include "universe.h" #include "universe.h"
#include "variable.h" #include "variable.h"
#include "force.h" #include "force.h"
#include "output.h"
#include "thermo.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
using namespace MathConst; using namespace MathConst;
enum{INT,DOUBLE}; // same as in dump_custom.cpp enum{INT,FLOAT,BIGINT}; // same as in thermo.cpp
const char NC_FRAME_STR[] = "frame"; const char NC_FRAME_STR[] = "frame";
const char NC_SPATIAL_STR[] = "spatial"; const char NC_SPATIAL_STR[] = "spatial";
...@@ -201,15 +203,15 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : ...@@ -201,15 +203,15 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) :
perat[inc].field[idim] = i; perat[inc].field[idim] = i;
} }
n_perframe = 0;
perframe = NULL;
n_buffer = 0; n_buffer = 0;
int_buffer = NULL; int_buffer = NULL;
double_buffer = NULL; double_buffer = NULL;
double_precision = false; double_precision = false;
thermo = false;
thermovar = NULL;
framei = 0; framei = 0;
} }
...@@ -220,8 +222,7 @@ DumpNetCDFMPIIO::~DumpNetCDFMPIIO() ...@@ -220,8 +222,7 @@ DumpNetCDFMPIIO::~DumpNetCDFMPIIO()
closefile(); closefile();
delete [] perat; delete [] perat;
if (n_perframe > 0) if (thermovar) delete [] thermovar;
delete [] perframe;
if (int_buffer) memory->sfree(int_buffer); if (int_buffer) memory->sfree(int_buffer);
if (double_buffer) memory->sfree(double_buffer); if (double_buffer) memory->sfree(double_buffer);
...@@ -231,6 +232,11 @@ DumpNetCDFMPIIO::~DumpNetCDFMPIIO() ...@@ -231,6 +232,11 @@ DumpNetCDFMPIIO::~DumpNetCDFMPIIO()
void DumpNetCDFMPIIO::openfile() void DumpNetCDFMPIIO::openfile()
{ {
if (thermo && !singlefile_opened) {
if (thermovar) delete [] thermovar;
thermovar = new int[output->thermo->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
// for the size of vector quantities // for the size of vector quantities
for (int i = 0; i < n_perat; i++) { for (int i = 0; i < n_perat; i++) {
...@@ -330,9 +336,12 @@ void DumpNetCDFMPIIO::openfile() ...@@ -330,9 +336,12 @@ void DumpNetCDFMPIIO::openfile()
} }
// perframe variables // perframe variables
for (int i = 0; i < n_perframe; i++) { if (thermo) {
NCERRX( ncmpi_inq_varid(ncid, perframe[i].name, &perframe[i].var), Thermo *th = output->thermo;
perframe[i].name ); for (int i = 0; i < th->nfield; i++) {
NCERRX( ncmpi_inq_varid(ncid, th->keyword[i], &thermovar[i]),
th->keyword[i] );
}
} }
MPI_Offset nframes; MPI_Offset nframes;
...@@ -439,14 +448,21 @@ void DumpNetCDFMPIIO::openfile() ...@@ -439,14 +448,21 @@ void DumpNetCDFMPIIO::openfile()
} }
// perframe variables // perframe variables
for (int i = 0; i < n_perframe; i++) { if (thermo) {
if (perframe[i].type == THIS_IS_A_BIGINT) { Thermo *th = output->thermo;
NCERRX( ncmpi_def_var(ncid, perframe[i].name, NC_INT, 1, dims, for (int i = 0; i < th->nfield; i++) {
&perframe[i].var), perframe[i].name ); if (th->vtype[i] == FLOAT) {
} NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_DOUBLE, 1, dims,
else { &thermovar[i]), th->keyword[i] );
NCERRX( ncmpi_def_var(ncid, perframe[i].name, NC_DOUBLE, 1, dims, }
&perframe[i].var), perframe[i].name ); else if (th->vtype[i] == INT) {
NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_INT, 1, dims,
&thermovar[i]), th->keyword[i] );
}
else if (th->vtype[i] == BIGINT) {
NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_LONG, 1, dims,
&thermovar[i]), th->keyword[i] );
}
} }
} }
...@@ -600,50 +616,34 @@ void DumpNetCDFMPIIO::write() ...@@ -600,50 +616,34 @@ void DumpNetCDFMPIIO::write()
NCERR( ncmpi_begin_indep_data(ncid) ); NCERR( ncmpi_begin_indep_data(ncid) );
for (int i = 0; i < n_perframe; i++) { if (thermo) {
Thermo *th = output->thermo;
if (perframe[i].type == THIS_IS_A_BIGINT) { for (int i = 0; i < th->nfield; i++) {
bigint data; th->call_vfunc(i);
(this->*perframe[i].compute)((void*) &data); if (filewriter) {
if (th->vtype[i] == FLOAT) {
if (filewriter) NCERRX( ncmpi_put_var1_double(ncid, thermovar[i], start,
&th->dvalue),
th->keyword[i] );
}
else if (th->vtype[i] == INT) {
NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &th->ivalue),
th->keyword[i] );
}
else if (th->vtype[i] == BIGINT) {
#if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG) #if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG)
NCERR( ncmpi_put_var1_long(ncid, perframe[i].var, start, &data) ); NCERRX( ncmpi_put_var1_long(ncid, thermovar[i], start, &th->bivalue),
th->keyword[i] );
#else #else
NCERR( ncmpi_put_var1_int(ncid, perframe[i].var, start, &data) ); NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &th->bivalue),
th->keyword[i] );
#endif #endif
}
else {
double data;
int j = perframe[i].index;
int idim = perframe[i].dim;
if (perframe[i].type == THIS_IS_A_COMPUTE) {
if (idim >= 0) {
modify->compute[j]->compute_vector();
data = modify->compute[j]->vector[idim];
} }
else
data = modify->compute[j]->compute_scalar();
} }
else if (perframe[i].type == THIS_IS_A_FIX) {
if (idim >= 0) {
data = modify->fix[j]->compute_vector(idim);
}
else
data = modify->fix[j]->compute_scalar();
}
else if (perframe[i].type == THIS_IS_A_VARIABLE) {
j = input->variable->find(perframe[i].id);
data = input->variable->compute_equal(j);
}
if (filewriter)
NCERR( ncmpi_put_var1_double(ncid, perframe[i].var, start, &data) );
} }
} }
// write timestep header // write timestep header
write_time_and_cell(); write_time_and_cell();
...@@ -903,126 +903,19 @@ int DumpNetCDFMPIIO::modify_param(int narg, char **arg) ...@@ -903,126 +903,19 @@ int DumpNetCDFMPIIO::modify_param(int narg, char **arg)
iarg++; iarg++;
return 2; return 2;
} }
else if (strcmp(arg[iarg],"global") == 0) { else if (strcmp(arg[iarg],"thermo") == 0) {
// "perframe" quantities, i.e. not per-atom stuff
iarg++; iarg++;
if (iarg >= narg)
n_perframe = narg-iarg; error->all(FLERR,"expected 'yes' or 'no' after 'thermo' keyword.");
perframe = new nc_perframe_t[n_perframe]; if (strcmp(arg[iarg],"yes") == 0) {
thermo = true;
for (int i = 0; iarg < narg; iarg++, i++) {
int n;
char *suffix;
if (!strcmp(arg[iarg],"step")) {
perframe[i].type = THIS_IS_A_BIGINT;
perframe[i].compute = &DumpNetCDFMPIIO::compute_step;
strcpy(perframe[i].name, arg[iarg]);
}
else if (!strcmp(arg[iarg],"elapsed")) {
perframe[i].type = THIS_IS_A_BIGINT;
perframe[i].compute = &DumpNetCDFMPIIO::compute_elapsed;
strcpy(perframe[i].name, arg[iarg]);
}
else if (!strcmp(arg[iarg],"elaplong")) {
perframe[i].type = THIS_IS_A_BIGINT;
perframe[i].compute = &DumpNetCDFMPIIO::compute_elapsed_long;
strcpy(perframe[i].name, arg[iarg]);
}
else {
n = strlen(arg[iarg]);
if (n > 2) {
suffix = new char[n-1];
strcpy(suffix, arg[iarg]+2);
}
else {
char errstr[1024];
sprintf(errstr, "perframe quantity '%s' must thermo quantity or "
"compute, fix or variable", arg[iarg]);
error->all(FLERR,errstr);
}
if (!strncmp(arg[iarg], "c_", 2)) {
int idim = -1;
char *ptr = strchr(suffix, '[');
if (ptr) {
if (suffix[strlen(suffix)-1] != ']')
error->all(FLERR,"Missing ']' in dump modify command");
*ptr = '\0';
idim = ptr[1] - '1';
}
n = modify->find_compute(suffix);
if (n < 0)
error->all(FLERR,"Could not find dump modify compute ID");
if (modify->compute[n]->peratom_flag != 0)
error->all(FLERR,"Dump modify compute ID computes per-atom info");
if (idim >= 0 && modify->compute[n]->vector_flag == 0)
error->all(FLERR,"Dump modify compute ID does not compute vector");
if (idim < 0 && modify->compute[n]->scalar_flag == 0)
error->all(FLERR,"Dump modify compute ID does not compute scalar");
perframe[i].type = THIS_IS_A_COMPUTE;
perframe[i].dim = idim;
perframe[i].index = n;
strcpy(perframe[i].name, arg[iarg]);
}
else if (!strncmp(arg[iarg], "f_", 2)) {
int idim = -1;
char *ptr = strchr(suffix, '[');
if (ptr) {
if (suffix[strlen(suffix)-1] != ']')
error->all(FLERR,"Missing ']' in dump modify command");
*ptr = '\0';
idim = ptr[1] - '1';
}
n = modify->find_fix(suffix);
if (n < 0)
error->all(FLERR,"Could not find dump modify fix ID");
if (modify->fix[n]->peratom_flag != 0)
error->all(FLERR,"Dump modify fix ID computes per-atom info");
if (idim >= 0 && modify->fix[n]->vector_flag == 0)
error->all(FLERR,"Dump modify fix ID does not compute vector");
if (idim < 0 && modify->fix[n]->scalar_flag == 0)
error->all(FLERR,"Dump modify fix ID does not compute vector");
perframe[i].type = THIS_IS_A_FIX;
perframe[i].dim = idim;
perframe[i].index = n;
strcpy(perframe[i].name, arg[iarg]);
}
else if (!strncmp(arg[iarg], "v_", 2)) {
n = input->variable->find(suffix);
if (n < 0)
error->all(FLERR,"Could not find dump modify variable ID");
if (!input->variable->equalstyle(n))
error->all(FLERR,"Dump modify variable must be of style equal");
perframe[i].type = THIS_IS_A_VARIABLE;
perframe[i].dim = 1;
perframe[i].index = n;
strcpy(perframe[i].name, arg[iarg]);
strcpy(perframe[i].id, suffix);
}
else {
char errstr[1024];
sprintf(errstr, "perframe quantity '%s' must be compute, fix or "
"variable", arg[iarg]);
error->all(FLERR,errstr);
}
delete [] suffix;
}
} }
else if (strcmp(arg[iarg],"no") == 0) {
return narg; thermo = false;
}
else error->all(FLERR,"expected 'yes' or 'no' after 'thermo' keyword.");
iarg++;
return 2;
} else return 0; } else return 0;
} }
...@@ -1044,31 +937,4 @@ void DumpNetCDFMPIIO::ncerr(int err, const char *descr, int line) ...@@ -1044,31 +937,4 @@ void DumpNetCDFMPIIO::ncerr(int err, const char *descr, int line)
} }
} }
/* ----------------------------------------------------------------------
one method for every keyword thermo can output
called by compute() or evaluate_keyword()
compute will have already been called
set ivalue/dvalue/bivalue if value is int/double/bigint
customize a new keyword by adding a method
------------------------------------------------------------------------- */
void DumpNetCDFMPIIO::compute_step(void *r)
{
*((bigint *) r) = update->ntimestep;
}
/* ---------------------------------------------------------------------- */
void DumpNetCDFMPIIO::compute_elapsed(void *r)
{
*((bigint *) r) = update->ntimestep - update->firststep;
}
/* ---------------------------------------------------------------------- */
void DumpNetCDFMPIIO::compute_elapsed_long(void *r)
{
*((bigint *) r) = update->ntimestep - update->beginstep;
}
#endif /* defined(LMP_HAS_PNETCDF) */ #endif /* defined(LMP_HAS_PNETCDF) */
...@@ -68,20 +68,6 @@ class DumpNetCDFMPIIO : public DumpCustom { ...@@ -68,20 +68,6 @@ class DumpNetCDFMPIIO : public DumpCustom {
typedef void (DumpNetCDFMPIIO::*funcptr_t)(void *); typedef void (DumpNetCDFMPIIO::*funcptr_t)(void *);
// per-frame quantities (variables, fixes or computes)
struct nc_perframe_t {
char name[NC_MPIIO_FIELD_NAME_MAX]; // field name
int var; // NetCDF variable
int type; // variable, fix, compute or callback
int index; // index in fix/compute list
funcptr_t compute; // compute function
int dim; // dimension
char id[NC_MPIIO_FIELD_NAME_MAX]; // variable id
bigint bigint_data; // actual data
double double_data; // actual data
};
int framei; // current frame index int framei; // current frame index
int blocki; // current block index int blocki; // current block index
int ndata; // number of data blocks to expect int ndata; // number of data blocks to expect
...@@ -91,10 +77,10 @@ class DumpNetCDFMPIIO : public DumpCustom { ...@@ -91,10 +77,10 @@ class DumpNetCDFMPIIO : public DumpCustom {
int n_perat; // # of netcdf per-atom properties int n_perat; // # of netcdf per-atom properties
nc_perat_t *perat; // per-atom properties nc_perat_t *perat; // per-atom properties
int n_perframe; // # of global netcdf (not per-atom) fix props int *thermovar; // NetCDF variables for thermo output
nc_perframe_t *perframe; // global properties
bool double_precision; // write everything as double precision bool double_precision; // write everything as double precision
bool thermo; // write thermo output to netcdf file
bigint n_buffer; // size of buffer bigint n_buffer; // size of buffer
int *int_buffer; // buffer for passing data to netcdf int *int_buffer; // buffer for passing data to netcdf
...@@ -128,10 +114,6 @@ class DumpNetCDFMPIIO : public DumpCustom { ...@@ -128,10 +114,6 @@ class DumpNetCDFMPIIO : public DumpCustom {
virtual int modify_param(int, char **); virtual int modify_param(int, char **);
void ncerr(int, const char *, int); void ncerr(int, const char *, int);
void compute_step(void *);
void compute_elapsed(void *);
void compute_elapsed_long(void *);
}; };
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment