Refactor PotentialFileReader
This commit is contained in:
@ -22,6 +22,7 @@
|
||||
#include "potential_file_reader.h"
|
||||
#include "utils.h"
|
||||
#include "tokenizer.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@ -30,102 +31,111 @@ using namespace LAMMPS_NS;
|
||||
PotentialFileReader::PotentialFileReader(LAMMPS *lmp,
|
||||
const std::string &filename,
|
||||
const std::string &potential_name) :
|
||||
Pointers(lmp), filename(filename), potential_name(potential_name)
|
||||
Pointers(lmp),
|
||||
reader(nullptr),
|
||||
filename(filename),
|
||||
potential_name(potential_name)
|
||||
{
|
||||
if (comm->me != 0) {
|
||||
error->one(FLERR, "PotentialFileReader should only be called by proc 0!");
|
||||
}
|
||||
|
||||
fp = force->open_potential(filename.c_str());
|
||||
|
||||
if (fp == NULL) {
|
||||
char str[128];
|
||||
snprintf(str, 128, "cannot open %s potential file %s", potential_name.c_str(), filename.c_str());
|
||||
error->one(FLERR, str);
|
||||
try {
|
||||
reader = open_potential(filename);
|
||||
} catch (FileReaderException & e) {
|
||||
error->one(FLERR, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
PotentialFileReader::~PotentialFileReader() {
|
||||
fclose(fp);
|
||||
delete reader;
|
||||
}
|
||||
|
||||
void PotentialFileReader::skip_line() {
|
||||
char *ptr = fgets(line, MAXLINE, fp);
|
||||
if (ptr == nullptr) {
|
||||
// EOF
|
||||
char str[128];
|
||||
snprintf(str, 128, "Missing line in %s potential file!", potential_name.c_str());
|
||||
error->one(FLERR, str);
|
||||
try {
|
||||
reader->skip_line();
|
||||
} catch (FileReaderException & e) {
|
||||
error->one(FLERR, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
char *PotentialFileReader::next_line(int nparams) {
|
||||
// concatenate lines until have nparams words
|
||||
int n = 0;
|
||||
int nwords = 0;
|
||||
|
||||
char *ptr = fgets(line, MAXLINE, fp);
|
||||
|
||||
if (ptr == nullptr) {
|
||||
// EOF
|
||||
try {
|
||||
return reader->next_line(nparams);
|
||||
} catch (FileReaderException & e) {
|
||||
error->one(FLERR, e.what());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// strip comment
|
||||
if ((ptr = strchr(line, '#'))) *ptr = '\0';
|
||||
|
||||
nwords = utils::count_words(line);
|
||||
|
||||
if (nwords > 0) {
|
||||
n = strlen(line);
|
||||
}
|
||||
|
||||
while(nwords == 0 || nwords < nparams) {
|
||||
char *ptr = fgets(&line[n], MAXLINE - n, fp);
|
||||
|
||||
if (ptr == nullptr) {
|
||||
// EOF
|
||||
if (nwords > 0 && nwords < nparams) {
|
||||
char str[128];
|
||||
snprintf(str, 128, "Incorrect format in %s potential file! %d/%d parameters", potential_name.c_str(), nwords, nparams);
|
||||
error->one(FLERR, str);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
// strip comment
|
||||
if ((ptr = strchr(line, '#'))) *ptr = '\0';
|
||||
|
||||
nwords = utils::count_words(line);
|
||||
|
||||
// skip line if blank
|
||||
if (nwords > 0) {
|
||||
n = strlen(line);
|
||||
}
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
void PotentialFileReader::next_dvector(int n, double * list) {
|
||||
int i = 0;
|
||||
while (i < n) {
|
||||
char *ptr = fgets(line, MAXLINE, fp);
|
||||
|
||||
if (ptr == nullptr) {
|
||||
// EOF
|
||||
if (i < n) {
|
||||
char str[128];
|
||||
snprintf(str, 128, "Incorrect format in %s potential file! %d/%d values", potential_name.c_str(), i, n);
|
||||
error->one(FLERR, str);
|
||||
try {
|
||||
return reader->next_dvector(n, list);
|
||||
} catch (FileReaderException & e) {
|
||||
error->one(FLERR, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
open a potential file as specified by name
|
||||
if fails, search in dir specified by env variable LAMMPS_POTENTIALS
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
TextFileReader * PotentialFileReader::open_potential(const std::string& path) {
|
||||
// attempt to open file directly
|
||||
// if successful, return filename
|
||||
std::string filepath = path;
|
||||
std::string filename = utils::path_basename(path);
|
||||
std::string date;
|
||||
|
||||
if(utils::file_is_readable(filepath)) {
|
||||
date = get_potential_date(filepath);
|
||||
} else {
|
||||
// try the environment variable directory
|
||||
const char *path = getenv("LAMMPS_POTENTIALS");
|
||||
|
||||
if (path != nullptr){
|
||||
std::string pot = utils::path_basename(filepath);
|
||||
filepath = utils::path_join(path, pot);
|
||||
|
||||
if (utils::file_is_readable(filepath)) {
|
||||
date = get_potential_date(filepath);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if(!date.empty()) {
|
||||
utils::logmesg(lmp, fmt::format("Reading potential file {} with DATE: {}", filename, date));
|
||||
}
|
||||
|
||||
return new TextFileReader(filepath, potential_name + " potential");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
read first line of potential file
|
||||
if has DATE field, print following word
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
std::string PotentialFileReader::get_potential_date(const std::string & path) {
|
||||
TextFileReader reader(path, potential_name + " potential");
|
||||
reader.ignore_comments = false;
|
||||
char * line = nullptr;
|
||||
|
||||
while (line = reader.next_line()) {
|
||||
ValueTokenizer values(line);
|
||||
while (values.has_next()) {
|
||||
list[i++] = values.next_double();
|
||||
std::string word = values.next_string();
|
||||
if (word == "DATE:") {
|
||||
if (values.has_next()) {
|
||||
std::string date = values.next_string();
|
||||
return date;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -21,15 +21,17 @@
|
||||
#include <string>
|
||||
|
||||
#include "pointers.h"
|
||||
#include "text_file_reader.h"
|
||||
|
||||
namespace LAMMPS_NS
|
||||
{
|
||||
class PotentialFileReader : protected Pointers {
|
||||
std::string potential_name;
|
||||
TextFileReader * reader;
|
||||
std::string filename;
|
||||
static const int MAXLINE = 1024;
|
||||
char line[MAXLINE];
|
||||
FILE *fp;
|
||||
std::string potential_name;
|
||||
|
||||
TextFileReader * open_potential(const std::string& path);
|
||||
std::string get_potential_date(const std::string & path);
|
||||
|
||||
public:
|
||||
PotentialFileReader(class LAMMPS *lmp, const std::string &filename, const std::string &potential_name);
|
||||
|
||||
117
src/text_file_reader.cpp
Normal file
117
src/text_file_reader.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing authors: Richard Berger (Temple U)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "lammps.h"
|
||||
#include "force.h"
|
||||
#include "error.h"
|
||||
#include "comm.h"
|
||||
#include "utils.h"
|
||||
#include "text_file_reader.h"
|
||||
#include "tokenizer.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
TextFileReader::TextFileReader(const std::string &filename, const std::string &filetype)
|
||||
: filename(filename), filetype(filetype)
|
||||
{
|
||||
fp = fopen(filename.c_str(), "r");
|
||||
|
||||
if (fp == nullptr) {
|
||||
throw FileReaderException(fmt::format("cannot open {} file {}", filetype, filename));
|
||||
}
|
||||
}
|
||||
|
||||
TextFileReader::~TextFileReader() {
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void TextFileReader::skip_line() {
|
||||
char *ptr = fgets(line, MAXLINE, fp);
|
||||
if (ptr == nullptr) {
|
||||
// EOF
|
||||
throw EOFException(fmt::format("Missing line in {} file!", filetype));
|
||||
}
|
||||
}
|
||||
|
||||
char *TextFileReader::next_line(int nparams) {
|
||||
// concatenate lines until have nparams words
|
||||
int n = 0;
|
||||
int nwords = 0;
|
||||
|
||||
char *ptr = fgets(line, MAXLINE, fp);
|
||||
|
||||
if (ptr == nullptr) {
|
||||
// EOF
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// strip comment
|
||||
if (ignore_comments && (ptr = strchr(line, '#'))) *ptr = '\0';
|
||||
|
||||
nwords = utils::count_words(line);
|
||||
|
||||
if (nwords > 0) {
|
||||
n = strlen(line);
|
||||
}
|
||||
|
||||
while(nwords == 0 || nwords < nparams) {
|
||||
char *ptr = fgets(&line[n], MAXLINE - n, fp);
|
||||
|
||||
if (ptr == nullptr) {
|
||||
// EOF
|
||||
if (nwords > 0 && nwords < nparams) {
|
||||
throw EOFException(fmt::format("Incorrect format in {} file! {}/{} parameters", filetype.c_str(), nwords, nparams));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
// strip comment
|
||||
if (ignore_comments && (ptr = strchr(line, '#'))) *ptr = '\0';
|
||||
|
||||
nwords = utils::count_words(line);
|
||||
|
||||
// skip line if blank
|
||||
if (nwords > 0) {
|
||||
n = strlen(line);
|
||||
}
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
void TextFileReader::next_dvector(int n, double * list) {
|
||||
int i = 0;
|
||||
while (i < n) {
|
||||
char *ptr = fgets(line, MAXLINE, fp);
|
||||
|
||||
if (ptr == nullptr) {
|
||||
// EOF
|
||||
if (i < n) {
|
||||
throw FileReaderException(fmt::format("Incorrect format in {} file! {}/{} values", filetype, i, n));
|
||||
}
|
||||
}
|
||||
|
||||
ValueTokenizer values(line);
|
||||
while(values.has_next()) {
|
||||
list[i++] = values.next_double();
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/text_file_reader.h
Normal file
68
src/text_file_reader.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing authors: Richard Berger (Temple U)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LMP_TEXT_FILE_READER_H
|
||||
#define LMP_TEXT_FILE_READER_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
|
||||
namespace LAMMPS_NS
|
||||
{
|
||||
class TextFileReader {
|
||||
std::string filename;
|
||||
std::string filetype;
|
||||
static const int MAXLINE = 1024;
|
||||
char line[MAXLINE];
|
||||
FILE *fp;
|
||||
|
||||
public:
|
||||
bool ignore_comments;
|
||||
|
||||
TextFileReader(const std::string &filename, const std::string &filetype);
|
||||
~TextFileReader();
|
||||
|
||||
void skip_line();
|
||||
char * next_line(int nparams = 0);
|
||||
|
||||
void next_dvector(int n, double * list);
|
||||
};
|
||||
|
||||
class FileReaderException : public std::exception {
|
||||
std::string message;
|
||||
public:
|
||||
FileReaderException(const std::string & msg) : message(msg) {
|
||||
}
|
||||
|
||||
~FileReaderException() throw() {
|
||||
}
|
||||
|
||||
virtual const char * what() const throw() {
|
||||
return message.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
class EOFException : public FileReaderException {
|
||||
public:
|
||||
EOFException(const std::string & msg) : FileReaderException(msg) {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user