diff --git a/src/.gitignore b/src/.gitignore index 27f4f8a64c..615c35ed11 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -5,6 +5,7 @@ /lmp_* /style_*.h +/packages_*.h /lmpinstalledpkgs.h /lmpgitversion.h diff --git a/src/lammps.cpp b/src/lammps.cpp index 2b3f001b09..24012c0f18 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "lammps.h" #include "style_angle.h" #include "style_atom.h" @@ -54,10 +56,29 @@ #include "lmpinstalledpkgs.h" #include "lmpgitversion.h" -using namespace LAMMPS_NS; - static void print_style(FILE *fp, const char *str, int &pos); +struct LAMMPS_NS::package_styles_lists { + std::map angle_styles; + std::map atom_styles; + std::map body_styles; + std::map bond_styles; + std::map command_styles; + std::map compute_styles; + std::map dihedral_styles; + std::map dump_styles; + std::map fix_styles; + std::map improper_styles; + std::map integrate_styles; + std::map kspace_styles; + std::map minimize_styles; + std::map pair_styles; + std::map reader_styles; + std::map region_styles; +}; + +using namespace LAMMPS_NS; + /* ---------------------------------------------------------------------- start up LAMMPS allocate fundamental classes (memory, error, universe, input) @@ -86,6 +107,8 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : initclock = MPI_Wtime(); + init_pkg_lists(); + // check if -mpi is first arg // if so, then 2 apps were launched with one mpirun command // this means passed communicator (e.g. MPI_COMM_WORLD) is bigger than LAMMPS @@ -693,6 +716,8 @@ LAMMPS::~LAMMPS() delete universe; delete error; delete memory; + + delete pkg_lists; } /* ---------------------------------------------------------------------- @@ -867,6 +892,149 @@ void LAMMPS::destroy() python = NULL; } +/* ---------------------------------------------------------------------- + initialize lists of styles in packages +------------------------------------------------------------------------- */ + +void LAMMPS::init_pkg_lists() +{ + pkg_lists = new package_styles_lists; +#define PACKAGE "UNKNOWN" +#define ANGLE_CLASS +#define AngleStyle(key,Class) \ + pkg_lists->angle_styles[#key] = PACKAGE; +#include "packages_angle.h" +#undef AngleStyle +#undef ANGLE_CLASS +#define ATOM_CLASS +#define AtomStyle(key,Class) \ + pkg_lists->atom_styles[#key] = PACKAGE; +#include "packages_atom.h" +#undef AtomStyle +#undef ATOM_CLASS +#define BODY_CLASS +#define BodyStyle(key,Class) \ + pkg_lists->body_styles[#key] = PACKAGE; +#include "packages_body.h" +#undef BodyStyle +#undef BODY_CLASS +#define BOND_CLASS +#define BondStyle(key,Class) \ + pkg_lists->bond_styles[#key] = PACKAGE; +#include "packages_bond.h" +#undef BondStyle +#undef BOND_CLASS +#define COMMAND_CLASS +#define CommandStyle(key,Class) \ + pkg_lists->command_styles[#key] = PACKAGE; +#include "packages_command.h" +#undef CommandStyle +#undef COMMAND_CLASS +#define COMPUTE_CLASS +#define ComputeStyle(key,Class) \ + pkg_lists->compute_styles[#key] = PACKAGE; +#include "packages_compute.h" +#undef ComputeStyle +#undef COMPUTE_CLASS +#define DIHEDRAL_CLASS +#define DihedralStyle(key,Class) \ + pkg_lists->dihedral_styles[#key] = PACKAGE; +#include "packages_dihedral.h" +#undef DihedralStyle +#undef DIHEDRAL_CLASS +#define DUMP_CLASS +#define DumpStyle(key,Class) \ + pkg_lists->dump_styles[#key] = PACKAGE; +#include "packages_dump.h" +#undef DumpStyle +#undef DUMP_CLASS +#define FIX_CLASS +#define FixStyle(key,Class) \ + pkg_lists->fix_styles[#key] = PACKAGE; +#include "packages_fix.h" +#undef FixStyle +#undef FIX_CLASS +#define IMPROPER_CLASS +#define ImproperStyle(key,Class) \ + pkg_lists->improper_styles[#key] = PACKAGE; +#include "packages_improper.h" +#undef ImproperStyle +#undef IMPROPER_CLASS +#define INTEGRATE_CLASS +#define IntegrateStyle(key,Class) \ + pkg_lists->integrate_styles[#key] = PACKAGE; +#include "packages_integrate.h" +#undef IntegrateStyle +#undef INTEGRATE_CLASS +#define KSPACE_CLASS +#define KSpaceStyle(key,Class) \ + pkg_lists->kspace_styles[#key] = PACKAGE; +#include "packages_kspace.h" +#undef KSpaceStyle +#undef KSPACE_CLASS +#define MINIMIZE_CLASS +#define MinimizeStyle(key,Class) \ + pkg_lists->minimize_styles[#key] = PACKAGE; +#include "packages_minimize.h" +#undef MinimizeStyle +#undef MINIMIZE_CLASS +#define PAIR_CLASS +#define PairStyle(key,Class) \ + pkg_lists->pair_styles[#key] = PACKAGE; +#include "packages_pair.h" +#undef PairStyle +#undef PAIR_CLASS +#define READER_CLASS +#define ReaderStyle(key,Class) \ + pkg_lists->reader_styles[#key] = PACKAGE; +#include "packages_reader.h" +#undef ReaderStyle +#undef READER_CLASS +#define REGION_CLASS +#define RegionStyle(key,Class) \ + pkg_lists->region_styles[#key] = PACKAGE; +#include "packages_region.h" +#undef RegionStyle +#undef REGION_CLASS +} + +bool LAMMPS::is_installed_pkg(const char *pkg) +{ + for (int i=0; installed_packages[i] != NULL; ++i) + if (strcmp(installed_packages[i],pkg) == 0) return true; + + return false; +} + +#define check_for_match(style,list,name) \ + if (strcmp(list,#style) == 0) { \ + std::map &styles(pkg_lists-> style ## _styles); \ + if (styles.find(name) != styles.end()) { \ + return styles[name].c_str(); \ + } \ + } + +const char *LAMMPS::match_style(const char *style, const char *name) +{ + check_for_match(angle,style,name); + check_for_match(atom,style,name); + check_for_match(body,style,name); + check_for_match(bond,style,name); + check_for_match(command,style,name); + check_for_match(compute,style,name); + check_for_match(dump,style,name); + check_for_match(fix,style,name); + check_for_match(compute,style,name); + check_for_match(improper,style,name); + check_for_match(integrate,style,name); + check_for_match(kspace,style,name); + check_for_match(minimize,style,name); + check_for_match(pair,style,name); + check_for_match(reader,style,name); + check_for_match(region,style,name); + return NULL; +} + /* ---------------------------------------------------------------------- help message for command line options and styles present in executable ------------------------------------------------------------------------- */ diff --git a/src/lammps.h b/src/lammps.h index 2e052e5ed2..e02d0c764a 100644 --- a/src/lammps.h +++ b/src/lammps.h @@ -63,7 +63,9 @@ class LAMMPS { class CiteMe *citeme; // citation info + const char *match_style(const char *style, const char *name); static const char * installed_packages[]; + static bool is_installed_pkg(const char *pkg); static const bool has_git_info; static const char git_commit[]; @@ -79,6 +81,8 @@ class LAMMPS { void print_config(FILE *); // print compile time settings private: + struct package_styles_lists *pkg_lists; + void init_pkg_lists(); void help(); LAMMPS() {}; // prohibit using the default constructor LAMMPS(const LAMMPS &) {}; // prohibit using the copy constructor diff --git a/src/utils.cpp b/src/utils.cpp index c3c173a73f..42140db0ba 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -11,8 +11,10 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#include #include #include "utils.h" +#include "lammps.h" #include "error.h" /*! \file utils.cpp */ @@ -123,6 +125,24 @@ void utils::sfgets(const char *srcname, int srcline, char *s, int size, /* ------------------------------------------------------------------ */ +std::string utils::check_packages_for_style(std::string style, + std::string name, LAMMPS *lmp) +{ + std::string errmsg = "Unrecognized " + style + " style " + name; + const char *pkg = lmp->match_style(style.c_str(),name.c_str()); + + if (pkg) { + errmsg += " is part of the " + std::string(pkg) + " package"; + if (lmp->is_installed_pkg(pkg)) + errmsg += ", but seems to be missing because of a dependency"; + else + errmsg += " which is not enabled in this LAMMPS binary."; + } + return errmsg; +} + +/* ------------------------------------------------------------------ */ + extern "C" { /* Typedef'd pointer to get abstract datatype. */ typedef struct regex_t *re_t; diff --git a/src/utils.h b/src/utils.h index 2596fcd774..7dfba8ead0 100644 --- a/src/utils.h +++ b/src/utils.h @@ -23,6 +23,7 @@ namespace LAMMPS_NS { // forward declarations class Error; + class LAMMPS; namespace utils { @@ -66,6 +67,15 @@ namespace LAMMPS_NS { */ void sfgets(const char *srcname, int srcline, char *s, int size, FILE *fp, const char *filename, Error *error); + + /** \brief Report if a requested style is in a package or may have a typo + * + * \param style type of style that is to be checked for + * \param name name of style that was not found + * \param lmp pointer to top-level LAMMPS class instance + * \return string usable for error messages + */ + std::string check_packages_for_style(std::string style, std::string name, LAMMPS *lmp); } }