forked from lijiext/lammps
modernize and simplify code to find best matching restart file
This commit is contained in:
parent
c49a533ad9
commit
4710b7bc9e
|
@ -71,16 +71,18 @@ void ReadRestart::command(int narg, char **arg)
|
|||
|
||||
// if filename contains "*", search dir for latest restart file
|
||||
|
||||
char *file = new char[strlen(arg[0]) + 16];
|
||||
char *file;
|
||||
if (strchr(arg[0],'*')) {
|
||||
int n;
|
||||
int n=0;
|
||||
if (me == 0) {
|
||||
file_search(arg[0],file);
|
||||
n = strlen(file) + 1;
|
||||
auto fn = file_search(arg[0]);
|
||||
n = fn.size()+1;
|
||||
file = utils::strdup(fn);
|
||||
}
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
if (me != 0) file = new char[n];
|
||||
MPI_Bcast(file,n,MPI_CHAR,0,world);
|
||||
} else strcpy(file,arg[0]);
|
||||
} else file = utils::strdup(arg[0]);
|
||||
|
||||
// check for multiproc files and an MPI-IO filename
|
||||
|
||||
|
@ -90,14 +92,12 @@ void ReadRestart::command(int narg, char **arg)
|
|||
else mpiioflag = 0;
|
||||
|
||||
if (multiproc && mpiioflag)
|
||||
error->all(FLERR,
|
||||
"Read restart MPI-IO input not allowed with % in filename");
|
||||
error->all(FLERR,"Read restart MPI-IO input not allowed with % in filename");
|
||||
|
||||
if (mpiioflag) {
|
||||
mpiio = new RestartMPIIO(lmp);
|
||||
if (!mpiio->mpiio_exists)
|
||||
error->all(FLERR,"Reading from MPI-IO filename when "
|
||||
"MPIIO package is not installed");
|
||||
error->all(FLERR,"Reading from MPI-IO filename when MPIIO package is not installed");
|
||||
}
|
||||
|
||||
// open single restart file or base file for multiproc case
|
||||
|
@ -538,83 +538,45 @@ void ReadRestart::command(int narg, char **arg)
|
|||
only called by proc 0
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void ReadRestart::file_search(char *inpfile, char *outfile)
|
||||
std::string ReadRestart::file_search(const std::string &inpfile)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
// separate inpfile into dir + filename
|
||||
|
||||
char *dirname = new char[strlen(inpfile) + 1];
|
||||
char *filename = new char[strlen(inpfile) + 1];
|
||||
|
||||
if (strchr(inpfile,'/')) {
|
||||
ptr = strrchr(inpfile,'/');
|
||||
*ptr = '\0';
|
||||
strcpy(dirname,inpfile);
|
||||
strcpy(filename,ptr+1);
|
||||
*ptr = '/';
|
||||
} else {
|
||||
strcpy(dirname,"./");
|
||||
strcpy(filename,inpfile);
|
||||
}
|
||||
auto dirname = utils::path_dirname(inpfile);
|
||||
auto filename = utils::path_basename(inpfile);
|
||||
|
||||
// if filename contains "%" replace "%" with "base"
|
||||
|
||||
char *pattern = new char[strlen(filename) + 16];
|
||||
auto pattern = filename;
|
||||
auto loc = pattern.find('%');
|
||||
if (loc != std::string::npos) pattern.replace(loc,1,"base");
|
||||
|
||||
if ((ptr = strchr(filename,'%'))) {
|
||||
*ptr = '\0';
|
||||
sprintf(pattern,"%s%s%s",filename,"base",ptr+1);
|
||||
*ptr = '%';
|
||||
} else strcpy(pattern,filename);
|
||||
// scan all files in directory, searching for files that match regexp pattern
|
||||
// maxnum = largest integer that matches "*"
|
||||
|
||||
// scan all files in directory, searching for files that match pattern
|
||||
// maxnum = largest int that matches "*"
|
||||
|
||||
int n = strlen(pattern) + 16;
|
||||
char *begin = new char[n];
|
||||
char *middle = new char[n];
|
||||
char *end = new char[n];
|
||||
|
||||
ptr = strchr(pattern,'*');
|
||||
*ptr = '\0';
|
||||
strcpy(begin,pattern);
|
||||
strcpy(end,ptr+1);
|
||||
int nbegin = strlen(begin);
|
||||
bigint maxnum = -1;
|
||||
loc = pattern.find('*');
|
||||
if (loc != std::string::npos) {
|
||||
// convert pattern to equivalent regexp
|
||||
pattern.replace(loc,1,"\\d+");
|
||||
struct dirent *ep;
|
||||
DIR *dp = opendir(dirname.c_str());
|
||||
if (dp == nullptr)
|
||||
error->one(FLERR,"Cannot open directory {} to search for restart file: {}",
|
||||
dirname, utils::getsyserror());
|
||||
|
||||
struct dirent *ep;
|
||||
DIR *dp = opendir(dirname);
|
||||
if (dp == nullptr)
|
||||
error->one(FLERR,"Cannot open dir to search for restart file");
|
||||
while ((ep = readdir(dp))) {
|
||||
if (strstr(ep->d_name,begin) != ep->d_name) continue;
|
||||
if ((ptr = strstr(&ep->d_name[nbegin],end)) == nullptr) continue;
|
||||
if (strlen(end) == 0) ptr = ep->d_name + strlen(ep->d_name);
|
||||
*ptr = '\0';
|
||||
if ((int)strlen(&ep->d_name[nbegin]) < n) {
|
||||
strcpy(middle,&ep->d_name[nbegin]);
|
||||
if (ATOBIGINT(middle) > maxnum) maxnum = ATOBIGINT(middle);
|
||||
while ((ep = readdir(dp))) {
|
||||
std::string candidate(ep->d_name);
|
||||
if (utils::strmatch(candidate,pattern)) {
|
||||
bigint num = ATOBIGINT(utils::strfind(candidate.substr(loc),"\\d+").c_str());
|
||||
if (num > maxnum) maxnum = num;
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
if (maxnum < 0) error->one(FLERR,"Found no restart file matching pattern");
|
||||
filename.replace(filename.find('*'),1,std::to_string(maxnum));
|
||||
}
|
||||
closedir(dp);
|
||||
if (maxnum < 0) error->one(FLERR,"Found no restart file matching pattern");
|
||||
|
||||
// create outfile with maxint substituted for "*"
|
||||
// use original inpfile, not pattern, since need to retain "%" in filename
|
||||
|
||||
std::string newoutfile = inpfile;
|
||||
newoutfile.replace(newoutfile.find("*"),1,fmt::format("{}",maxnum));
|
||||
strcpy(outfile,newoutfile.c_str());
|
||||
|
||||
// clean up
|
||||
|
||||
delete [] dirname;
|
||||
delete [] filename;
|
||||
delete [] pattern;
|
||||
delete [] begin;
|
||||
delete [] middle;
|
||||
delete [] end;
|
||||
return utils::path_join(dirname,filename);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
|
|
@ -46,7 +46,7 @@ class ReadRestart : public Command {
|
|||
bigint assignedChunkSize;
|
||||
MPI_Offset assignedChunkOffset, headerOffset;
|
||||
|
||||
void file_search(char *, char *);
|
||||
std::string file_search(const std::string &);
|
||||
void header();
|
||||
void type_arrays();
|
||||
void force_fields();
|
||||
|
|
Loading…
Reference in New Issue