git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@11095 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2013-12-06 22:32:32 +00:00
parent 6831bc9d32
commit 6bfbfa78f4
6 changed files with 691 additions and 389 deletions

View File

@ -15,7 +15,6 @@
#include "mpi.h"
#include "string.h"
#include "stdlib.h"
//#include "sys/types.h"
#include "dirent.h"
#include "read_restart.h"
#include "atom.h"
@ -43,21 +42,24 @@ using namespace LAMMPS_NS;
// same as write_restart.cpp
#define MAGIC_STRING "LammpS RestartT"
#define ENDIAN 0x0001
#define ENDIANSWAP 0x1000
#define VERSION_NUMERIC 0
enum{VERSION,SMALLINT,TAGINT,BIGINT,
UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2,
NEWTON_PAIR,NEWTON_BOND,XPERIODIC,YPERIODIC,ZPERIODIC,
BOUNDARY_00,BOUNDARY_01,BOUNDARY_10,BOUNDARY_11,BOUNDARY_20,BOUNDARY_21,
ATOM_STYLE,NATOMS,NTYPES,
NBONDS,NBONDTYPES,BOND_PER_ATOM,
NANGLES,NANGLETYPES,ANGLE_PER_ATOM,
NDIHEDRALS,NDIHEDRALTYPES,DIHEDRAL_PER_ATOM,
NIMPROPERS,NIMPROPERTYPES,IMPROPER_PER_ATOM,
BOXLO_0,BOXHI_0,BOXLO_1,BOXHI_1,BOXLO_2,BOXHI_2,
SPECIAL_LJ_1,SPECIAL_LJ_2,SPECIAL_LJ_3,
SPECIAL_COUL_1,SPECIAL_COUL_2,SPECIAL_COUL_3,
XY,XZ,YZ};
enum{MASS};
enum{PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER};
UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID,
NEWTON_PAIR,NEWTON_BOND,
XPERIODIC,YPERIODIC,ZPERIODIC,BOUNDARY,
ATOM_STYLE,NATOMS,NTYPES,
NBONDS,NBONDTYPES,BOND_PER_ATOM,
NANGLES,NANGLETYPES,ANGLE_PER_ATOM,
NDIHEDRALS,NDIHEDRALTYPES,DIHEDRAL_PER_ATOM,
NIMPROPERS,NIMPROPERTYPES,IMPROPER_PER_ATOM,
TRICLINIC,BOXLO,BOXHI,XY,XZ,YZ,
SPECIAL_LJ,SPECIAL_COUL,
MASS,PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER,
MULTIPROC,MPIIO,PROCSPERFILE,PERPROC};
#define LB_FACTOR 1.1
@ -90,14 +92,18 @@ void ReadRestart::command(int narg, char **arg)
MPI_Bcast(file,n,MPI_CHAR,0,world);
} else strcpy(file,arg[0]);
// check if filename contains "%"
// check for multiproc files and an MPI-IO filename
int multiproc;
if (strchr(file,'%')) multiproc = 1;
if (strchr(arg[0],'%')) multiproc = 1;
else multiproc = 0;
if (strstr(arg[0],".mpi")) mpiio = 1;
else mpiio = 0;
if (multiproc && mpiio)
error->all(FLERR,
"Read restart MPI-IO output not allowed with '%' in filename");
// open single restart file or base file for multiproc case
// auto-detect whether byte swapping needs to be done as file is read
if (me == 0) {
if (screen) fprintf(screen,"Reading restart file ...\n");
@ -115,15 +121,18 @@ void ReadRestart::command(int narg, char **arg)
sprintf(str,"Cannot open restart file %s",hfile);
error->one(FLERR,str);
}
swapflag = autodetect(&fp,hfile);
if (multiproc) delete [] hfile;
}
MPI_Bcast(&swapflag,1,MPI_INT,0,world);
// read magic string, endian flag, numeric version
// read header info and create atom style and simulation box
magic_string();
endian();
int outofdate = version_numeric();
header();
// read header info which creates simulation box
header(outofdate);
domain->box_exist = 1;
// problem setup using info from header
@ -153,12 +162,19 @@ void ReadRestart::command(int narg, char **arg)
atom->nextra_store = nextra;
memory->create(atom->extra,n,nextra,"atom:extra");
// read file layout info
file_layout();
// all done with reading header info
if (me == 0) fclose(fp);
// single file:
// nprocs_file = # of chunks in file
// proc 0 reads chunks one at a time and bcasts it to other procs
// proc 0 reads a chunk and bcasts it to other procs
// each proc unpacks the atoms, saving ones in it's sub-domain
// check for atom in sub-domain differs for orthogonal vs triclinic box
// close restart file when done
AtomVec *avec = atom->avec;
@ -167,6 +183,7 @@ void ReadRestart::command(int narg, char **arg)
int m;
if (multiproc == 0) {
int triclinic = domain->triclinic;
double *x,lamda[3];
double *coord,*sublo,*subhi;
@ -179,17 +196,16 @@ void ReadRestart::command(int narg, char **arg)
}
for (int iproc = 0; iproc < nprocs_file; iproc++) {
if (read_int() != PERPROC)
error->all(FLERR,"Invalid flag in peratom section of restart file");
n = read_int();
if (n > maxbuf) {
maxbuf = n;
memory->destroy(buf);
memory->create(buf,maxbuf,"read_restart:buf");
}
if (n > 0) {
if (me == 0) nread_double(buf,n,fp);
MPI_Bcast(buf,n,MPI_DOUBLE,0,world);
}
read_double_vec(n,buf);
m = 0;
while (m < n) {
@ -210,42 +226,166 @@ void ReadRestart::command(int narg, char **arg)
if (me == 0) fclose(fp);
// one file per proc:
// nprocs_file = # of files
// each proc reads 1/P fraction of files, keeping all atoms in the files
// perform irregular comm to migrate atoms to correct procs
// close restart file when done
// multiple files with procs <= files
// # of files = multiproc_file
// each proc reads a subset of files, striding by nprocs
// each proc keeps all atoms in all perproc chunks in its files
} else {
if (me == 0) fclose(fp);
char *perproc = new char[strlen(file) + 16];
} else if (nprocs <= multiproc_file) {
char *procfile = new char[strlen(file) + 16];
char *ptr = strchr(file,'%');
for (int iproc = me; iproc < nprocs_file; iproc += nprocs) {
for (int iproc = me; iproc < multiproc_file; iproc += nprocs) {
*ptr = '\0';
sprintf(perproc,"%s%d%s",file,iproc,ptr+1);
sprintf(procfile,"%s%d%s",file,iproc,ptr+1);
*ptr = '%';
fp = fopen(perproc,"rb");
fp = fopen(procfile,"rb");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open restart file %s",perproc);
sprintf(str,"Cannot open restart file %s",procfile);
error->one(FLERR,str);
}
nread_int(&n,1,fp);
if (n > maxbuf) {
maxbuf = n;
memory->destroy(buf);
memory->create(buf,maxbuf,"read_restart:buf");
}
if (n > 0) nread_double(buf,n,fp);
int flag;
fread(&flag,sizeof(int),1,fp);
if (flag != PROCSPERFILE)
error->one(FLERR,"Invalid flag in peratom section of restart file");
int procsperfile;
fread(&procsperfile,sizeof(int),1,fp);
for (int i = 0; i < procsperfile; i++) {
fread(&flag,sizeof(int),1,fp);
if (flag != PERPROC)
error->one(FLERR,"Invalid flag in peratom section of restart file");
fread(&n,sizeof(int),1,fp);
if (n > maxbuf) {
maxbuf = n;
memory->destroy(buf);
memory->create(buf,maxbuf,"read_restart:buf");
}
fread(buf,sizeof(double),n,fp);
m = 0;
while (m < n) m += avec->unpack_restart(&buf[m]);
}
m = 0;
while (m < n) m += avec->unpack_restart(&buf[m]);
fclose(fp);
}
delete [] perproc;
delete [] procfile;
// multiple files with procs > files
// # of files = multiproc_file
// cluster procs based on # of files
// 1st proc in each cluster reads per-proc chunks from file
// sends chunks round-robin to other procs in its cluster
// each proc keeps all atoms in its perproc chunks in file
} else {
// nclusterprocs = # of procs in my cluster that read from one file
// filewriter = 1 if this proc reads file, else 0
// fileproc = ID of proc in my cluster who reads from file
// clustercomm = MPI communicator within my cluster of procs
int nfile = multiproc_file;
int icluster = static_cast<int> ((bigint) me * nfile/nprocs);
int fileproc = static_cast<int> ((bigint) icluster * nprocs/nfile);
int fcluster = static_cast<int> ((bigint) fileproc * nfile/nprocs);
if (fcluster < icluster) fileproc++;
int fileprocnext =
static_cast<int> ((bigint) (icluster+1) * nprocs/nfile);
fcluster = static_cast<int> ((bigint) fileprocnext * nfile/nprocs);
if (fcluster < icluster+1) fileprocnext++;
int nclusterprocs = fileprocnext - fileproc;
int filereader = 0;
if (me == fileproc) filereader = 1;
MPI_Comm clustercomm;
MPI_Comm_split(world,icluster,0,&clustercomm);
if (filereader) {
char *procfile = new char[strlen(file) + 16];
char *ptr = strchr(file,'%');
*ptr = '\0';
sprintf(procfile,"%s%d%s",file,icluster,ptr+1);
*ptr = '%';
fp = fopen(procfile,"rb");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open restart file %s",procfile);
error->one(FLERR,str);
}
delete [] procfile;
}
int flag,procsperfile;
if (filereader) {
fread(&flag,sizeof(int),1,fp);
if (flag != PROCSPERFILE)
error->one(FLERR,"Invalid flag in peratom section of restart file");
fread(&procsperfile,sizeof(int),1,fp);
}
MPI_Bcast(&procsperfile,1,MPI_INT,0,clustercomm);
int tmp,iproc;
MPI_Status status;
MPI_Request request;
for (int i = 0; i < procsperfile; i++) {
if (filereader) {
fread(&flag,sizeof(int),1,fp);
if (flag != PERPROC)
error->one(FLERR,"Invalid flag in peratom section of restart file");
fread(&n,sizeof(int),1,fp);
if (n > maxbuf) {
maxbuf = n;
memory->destroy(buf);
memory->create(buf,maxbuf,"read_restart:buf");
}
fread(buf,sizeof(double),n,fp);
if (i % nclusterprocs) {
iproc = me + (i % nclusterprocs);
MPI_Send(&n,1,MPI_INT,iproc,0,world);
MPI_Recv(&tmp,0,MPI_INT,iproc,0,world,&status);
MPI_Rsend(buf,n,MPI_DOUBLE,iproc,0,world);
}
} else if (i % nclusterprocs == me - fileproc) {
MPI_Recv(&n,1,MPI_INT,fileproc,0,world,&status);
if (n > maxbuf) {
maxbuf = n;
memory->destroy(buf);
memory->create(buf,maxbuf,"read_restart:buf");
}
MPI_Irecv(buf,n,MPI_DOUBLE,fileproc,0,world,&request);
MPI_Send(&tmp,0,MPI_INT,fileproc,0,world);
MPI_Wait(&request,&status);
}
if (i % nclusterprocs == me - fileproc) {
m = 0;
while (m < n) m += avec->unpack_restart(&buf[m]);
}
}
if (filereader) fclose(fp);
MPI_Comm_free(&clustercomm);
}
// clean-up memory
delete [] file;
memory->destroy(buf);
// for multiproc files:
// perform irregular comm to migrate atoms to correct procs
if (multiproc) {
// create a temporary fix to hold and migrate extra atom info
// necessary b/c irregular will migrate atoms
@ -294,11 +434,6 @@ void ReadRestart::command(int narg, char **arg)
}
}
// clean-up memory
delete [] file;
memory->destroy(buf);
// check that all atoms were assigned to procs
bigint natoms;
@ -451,13 +586,13 @@ void ReadRestart::file_search(char *infile, char *outfile)
read header of restart file
------------------------------------------------------------------------- */
void ReadRestart::header()
void ReadRestart::header(int outofdate)
{
int px,py,pz;
int xperiodic,yperiodic,zperiodic;
int boundary[3][2];
// read flags and values until flag = -1
// read flags and fields until flag = -1
int flag = read_int();
while (flag >= 0) {
@ -465,16 +600,16 @@ void ReadRestart::header()
// check restart file version, warn if different
if (flag == VERSION) {
char *version = read_char();
if (strcmp(version,universe->version) != 0 && me == 0) {
error->warning(FLERR,
"Restart file version does not match LAMMPS version");
char *version = read_string();
if (me == 0) {
if (screen) fprintf(screen," restart file = %s, LAMMPS = %s\n",
version,universe->version);
}
if (outofdate)
error->all(FLERR,"Restart file too old for current version to read");
delete [] version;
// check lmptype.h sizes, error if different
// check lmptype.h sizes, error if different
} else if (flag == SMALLINT) {
int size = read_int();
@ -489,18 +624,18 @@ void ReadRestart::header()
if (size != sizeof(bigint))
error->all(FLERR,"Bigint setting in lmptype.h is not compatible");
// reset unit_style only if different
// so that timestep,neighbor-skin are not changed
// reset unit_style only if different
// so that timestep,neighbor-skin are not changed
} else if (flag == UNITS) {
char *style = read_char();
char *style = read_string();
if (strcmp(style,update->unit_style) != 0) update->set_units(style);
delete [] style;
} else if (flag == NTIMESTEP) {
update->ntimestep = read_bigint();
// set dimension from restart file
// set dimension from restart file
} else if (flag == DIMENSION) {
int dimension = read_int();
@ -509,24 +644,23 @@ void ReadRestart::header()
error->all(FLERR,
"Cannot run 2d simulation with nonperiodic Z dimension");
// read nprocs from restart file, warn if different
// read nprocs from restart file, warn if different
} else if (flag == NPROCS) {
nprocs_file = read_int();
if (nprocs_file != comm->nprocs && me == 0)
error->warning(FLERR,"Restart file used different # of processors");
// don't set procgrid, warn if different
// don't set procgrid, warn if different
} else if (flag == PROCGRID_0) {
px = read_int();
} else if (flag == PROCGRID_1) {
py = read_int();
} else if (flag == PROCGRID_2) {
pz = read_int();
} else if (flag == PROCGRID) {
int procgrid[3];
read_int();
read_int_vec(3,procgrid);
if (comm->user_procgrid[0] != 0 &&
(px != comm->user_procgrid[0] || py != comm->user_procgrid[1] ||
pz != comm->user_procgrid[2]) && me == 0)
(procgrid[0] != comm->user_procgrid[0] ||
procgrid[1] != comm->user_procgrid[1] ||
procgrid[2] != comm->user_procgrid[2]) && me == 0)
error->warning(FLERR,"Restart file used different 3d processor grid");
// don't set newton_pair, leave input script value unchanged
@ -562,18 +696,10 @@ void ReadRestart::header()
yperiodic = read_int();
} else if (flag == ZPERIODIC) {
zperiodic = read_int();
} else if (flag == BOUNDARY_00) {
boundary[0][0] = read_int();
} else if (flag == BOUNDARY_01) {
boundary[0][1] = read_int();
} else if (flag == BOUNDARY_10) {
boundary[1][0] = read_int();
} else if (flag == BOUNDARY_11) {
boundary[1][1] = read_int();
} else if (flag == BOUNDARY_20) {
boundary[2][0] = read_int();
} else if (flag == BOUNDARY_21) {
boundary[2][1] = read_int();
} else if (flag == BOUNDARY) {
int boundary[3][2];
read_int();
read_int_vec(6,&boundary[0][0]);
if (domain->boundary[0][0] || domain->boundary[0][1] ||
domain->boundary[1][0] || domain->boundary[1][1] ||
@ -611,11 +737,11 @@ void ReadRestart::header()
domain->nonperiodic = 2;
}
// create new AtomVec class
// if style = hybrid, read additional sub-class arguments
// create new AtomVec class
// if style = hybrid, read additional sub-class arguments
} else if (flag == ATOM_STYLE) {
char *style = read_char();
char *style = read_string();
int nwords = 0;
char **words = NULL;
@ -623,7 +749,7 @@ void ReadRestart::header()
if (strcmp(style,"hybrid") == 0) {
nwords = read_int();
words = new char*[nwords];
for (int i = 0; i < nwords; i++) words[i] = read_char();
for (int i = 0; i < nwords; i++) words[i] = read_string();
}
atom->create_avec(style,nwords,words);
@ -662,42 +788,28 @@ void ReadRestart::header()
} else if (flag == IMPROPER_PER_ATOM) {
atom->improper_per_atom = read_int();
} else if (flag == BOXLO_0) {
domain->boxlo[0] = read_double();
} else if (flag == BOXHI_0) {
domain->boxhi[0] = read_double();
} else if (flag == BOXLO_1) {
domain->boxlo[1] = read_double();
} else if (flag == BOXHI_1) {
domain->boxhi[1] = read_double();
} else if (flag == BOXLO_2) {
domain->boxlo[2] = read_double();
} else if (flag == BOXHI_2) {
domain->boxhi[2] = read_double();
} else if (flag == SPECIAL_LJ_1) {
force->special_lj[1] = read_double();
} else if (flag == SPECIAL_LJ_2) {
force->special_lj[2] = read_double();
} else if (flag == SPECIAL_LJ_3) {
force->special_lj[3] = read_double();
} else if (flag == SPECIAL_COUL_1) {
force->special_coul[1] = read_double();
} else if (flag == SPECIAL_COUL_2) {
force->special_coul[2] = read_double();
} else if (flag == SPECIAL_COUL_3) {
force->special_coul[3] = read_double();
} else if (flag == TRICLINIC) {
domain->triclinic = read_int();
} else if (flag == BOXLO) {
read_int();
read_double_vec(3,domain->boxlo);
} else if (flag == BOXHI) {
read_int();
read_double_vec(3,domain->boxhi);
} else if (flag == XY) {
domain->triclinic = 1;
domain->xy = read_double();
} else if (flag == XZ) {
domain->triclinic = 1;
domain->xz = read_double();
} else if (flag == YZ) {
domain->triclinic = 1;
domain->yz = read_double();
} else if (flag == SPECIAL_LJ) {
read_int();
read_double_vec(3,&force->special_lj[1]);
} else if (flag == SPECIAL_COUL) {
read_int();
read_double_vec(3,&force->special_coul[1]);
} else error->all(FLERR,"Invalid flag in header section of restart file");
flag = read_int();
@ -712,9 +824,9 @@ void ReadRestart::type_arrays()
while (flag >= 0) {
if (flag == MASS) {
read_int();
double *mass = new double[atom->ntypes+1];
if (me == 0) nread_double(&mass[1],atom->ntypes,fp);
MPI_Bcast(&mass[1],atom->ntypes,MPI_DOUBLE,0,world);
read_double_vec(atom->ntypes,&mass[1]);
atom->set_mass(mass);
delete [] mass;
@ -736,55 +848,31 @@ void ReadRestart::force_fields()
while (flag >= 0) {
if (flag == PAIR) {
n = read_int();
style = new char[n];
if (me == 0) nread_char(style,n,fp);
MPI_Bcast(style,n,MPI_CHAR,0,world);
style = read_string();
force->create_pair(style);
delete [] style;
if (force->pair->restartinfo) force->pair->read_restart(fp);
else {
delete force->pair;
force->pair = NULL;
}
force->pair->read_restart(fp);
} else if (flag == BOND) {
n = read_int();
style = new char[n];
if (me == 0) nread_char(style,n,fp);
MPI_Bcast(style,n,MPI_CHAR,0,world);
style = read_string();
force->create_bond(style);
delete [] style;
force->bond->read_restart(fp);
} else if (flag == ANGLE) {
n = read_int();
style = new char[n];
if (me == 0) nread_char(style,n,fp);
MPI_Bcast(style,n,MPI_CHAR,0,world);
style = read_string();
force->create_angle(style);
delete [] style;
force->angle->read_restart(fp);
} else if (flag == DIHEDRAL) {
n = read_int();
style = new char[n];
if (me == 0) nread_char(style,n,fp);
MPI_Bcast(style,n,MPI_CHAR,0,world);
style = read_string();
force->create_dihedral(style);
delete [] style;
force->dihedral->read_restart(fp);
} else if (flag == IMPROPER) {
n = read_int();
style = new char[n];
if (me == 0) nread_char(style,n,fp);
MPI_Bcast(style,n,MPI_CHAR,0,world);
style = read_string();
force->create_improper(style);
delete [] style;
force->improper->read_restart(fp);
@ -796,36 +884,81 @@ void ReadRestart::force_fields()
}
}
/* ---------------------------------------------------------------------- */
void ReadRestart::file_layout()
{
int flag = read_int();
while (flag >= 0) {
if (flag == MULTIPROC) {
multiproc_file = read_int();
if (multiproc == 0 && multiproc_file)
error->all(FLERR,"Restart file is not a multi-proc file");
if (multiproc && multiproc_file == 0)
error->all(FLERR,"Restart file is a multi-proc file");
} else if (flag = MPIIO) {
int mpiio_file = read_int();
if (mpiio == 0 && mpiio_file)
error->all(FLERR,"Restart file is a MPI-IO file");
if (mpiio && mpiio_file == 0)
error->all(FLERR,"Restart file is not a MPI-IO file");
}
flag = read_int();
}
}
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// low-level fread methods
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
/* ----------------------------------------------------------------------
read N ints from restart file
do not bcast them, caller does that if required
------------------------------------------------------------------------- */
void ReadRestart::nread_int(int *buf, int n, FILE *fp)
void ReadRestart::magic_string()
{
fread(buf,sizeof(int),n,fp);
if (swapflag) {}
int n = strlen(MAGIC_STRING) + 1;
char *str = new char[n];
int count;
if (me == 0) count = fread(str,sizeof(char),n,fp);
MPI_Bcast(&count,1,MPI_INT,0,world);
if (count < n)
error->all(FLERR,"Invalid LAMMPS restart file");
MPI_Bcast(str,n,MPI_CHAR,0,world);
if (strcmp(str,MAGIC_STRING) != 0)
error->all(FLERR,"Invalid LAMMPS restart file");
delete [] str;
}
/* ----------------------------------------------------------------------
read N doubles from restart file
do not bcast them, caller does that if required
------------------------------------------------------------------------- */
void ReadRestart::nread_double(double *buf, int n, FILE *fp)
void ReadRestart::endian()
{
fread(buf,sizeof(double),n,fp);
if (swapflag) {}
int endian;
if (me == 0) fread(&endian,sizeof(int),1,fp);
MPI_Bcast(&endian,1,MPI_INT,0,world);
if (endian == ENDIAN) return;
if (endian == ENDIANSWAP)
error->all(FLERR,"Restart file byte ordering is swapped");
else error->all(FLERR,"Restart file byte ordering is not recognized");
}
/* ----------------------------------------------------------------------
read N chars from restart file
do not bcast them, caller does that if required
------------------------------------------------------------------------- */
void ReadRestart::nread_char(char *buf, int n, FILE *fp)
int ReadRestart::version_numeric()
{
fread(buf,sizeof(char),n,fp);
int vn;
if (me == 0) fread(&vn,sizeof(int),1,fp);
MPI_Bcast(&vn,1,MPI_INT,0,world);
if (vn < VERSION_NUMERIC) return 1;
return 0;
}
/* ----------------------------------------------------------------------
@ -835,51 +968,11 @@ void ReadRestart::nread_char(char *buf, int n, FILE *fp)
int ReadRestart::read_int()
{
int value;
if (me == 0) {
fread(&value,sizeof(int),1,fp);
if (swapflag) {}
}
if (me == 0) fread(&value,sizeof(int),1,fp);
MPI_Bcast(&value,1,MPI_INT,0,world);
return value;
}
/* ----------------------------------------------------------------------
read a double from restart file and bcast it
------------------------------------------------------------------------- */
double ReadRestart::read_double()
{
double value;
if (me == 0) {
fread(&value,sizeof(double),1,fp);
if (swapflag) {}
}
MPI_Bcast(&value,1,MPI_DOUBLE,0,world);
return value;
}
/* ----------------------------------------------------------------------
read a char str from restart file and bcast it
str is allocated here, ptr is returned, caller must deallocate
------------------------------------------------------------------------- */
char *ReadRestart::read_char()
{
int n;
if (me == 0) {
fread(&n,sizeof(int),1,fp);
if (swapflag) {}
}
MPI_Bcast(&n,1,MPI_INT,0,world);
char *value = new char[n];
if (me == 0) {
fread(value,sizeof(char),n,fp);
if (swapflag) {}
}
MPI_Bcast(value,n,MPI_CHAR,0,world);
return value;
}
/* ----------------------------------------------------------------------
read a bigint from restart file and bcast it
------------------------------------------------------------------------- */
@ -887,35 +980,57 @@ char *ReadRestart::read_char()
bigint ReadRestart::read_bigint()
{
bigint value;
if (me == 0) {
fread(&value,sizeof(bigint),1,fp);
if (swapflag) {}
}
if (me == 0) fread(&value,sizeof(bigint),1,fp);
MPI_Bcast(&value,1,MPI_LMP_BIGINT,0,world);
return value;
}
/* ----------------------------------------------------------------------
auto-detect if restart file needs to be byte-swapped on this platform
return 0 if not, 1 if it does
re-open file with fp after checking first few bytes
read a bigint from restart file and bcast it
NOTE: not yet fully implemented, ditto for swapflag logic
read a double from restart file and bcast it
------------------------------------------------------------------------- */
int ReadRestart::autodetect(FILE **pfp, char *file)
double ReadRestart::read_double()
{
FILE *fp = *pfp;
// read, check, set return flag
int flag = 0;
// reset file pointer
fclose(fp);
fp = fopen(file,"rb");
*pfp = fp;
return flag;
double value;
if (me == 0) fread(&value,sizeof(double),1,fp);
MPI_Bcast(&value,1,MPI_DOUBLE,0,world);
return value;
}
/* ----------------------------------------------------------------------
read a char string (including NULL) and bcast it
str is allocated here, ptr is returned, caller must deallocate
------------------------------------------------------------------------- */
char *ReadRestart::read_string()
{
int n;
if (me == 0) fread(&n,sizeof(int),1,fp);
MPI_Bcast(&n,1,MPI_INT,0,world);
char *value = new char[n];
if (me == 0) fread(value,sizeof(char),n,fp);
MPI_Bcast(value,n,MPI_CHAR,0,world);
return value;
}
/* ----------------------------------------------------------------------
read vector of N ints from restart file and bcast them
do not bcast them, caller does that if required
------------------------------------------------------------------------- */
void ReadRestart::read_int_vec(int n, int *vec)
{
if (me == 0) fread(vec,sizeof(int),n,fp);
MPI_Bcast(vec,n,MPI_INT,0,world);
}
/* ----------------------------------------------------------------------
read vector of N doubles from restart file and bcast them
do not bcast them, caller does that if required
------------------------------------------------------------------------- */
void ReadRestart::read_double_vec(int n, double *vec)
{
if (me == 0) fread(vec,sizeof(double),n,fp);
MPI_Bcast(vec,n,MPI_DOUBLE,0,world);
}