diff --git a/python/lammps.py b/python/lammps.py index bbe9c07a30..ffcdbac456 100644 --- a/python/lammps.py +++ b/python/lammps.py @@ -290,6 +290,7 @@ class lammps(object): self.c_tagint = get_ctypes_int(self.extract_setting("tagint")) self.c_imageint = get_ctypes_int(self.extract_setting("imageint")) self._installed_packages = None + self._available_styles = None # add way to insert Python callback for fix external self.callback = {} @@ -701,6 +702,38 @@ class lammps(object): self._installed_packages.append(sb.value.decode()) return self._installed_packages + def has_style(self, category, name): + """Returns whether a given style name is available in a given category + + :param category: name of category + :type category: string + :param name: name of the style + :type name: string + :return: true if style is available in given category + :rtype: bool + """ + return self.lib.lammps_has_style(self.lmp, category.encode(), name.encode()) != 0 + + def available_styles(self, category): + """Returns a list of styles available for a given category + + :param category: name of category + :type category: string + :return: list of style names in given category + :rtype: list + """ + if self._available_styles is None: + self._available_styles = {} + + if category not in self._available_styles: + self._available_styles[category] = [] + nstyles = self.lib.lammps_style_count(self.lmp, category.encode()) + sb = create_string_buffer(100) + for idx in range(nstyles): + self.lib.lammps_style_name(self.lmp, category.encode(), idx, sb, 100) + self._available_styles[category].append(sb.value.decode()) + return self._available_styles[category] + def set_fix_external_callback(self, fix_name, callback, caller=None): import numpy as np def _ctype_to_numpy_int(ctype_int): diff --git a/src/info.cpp b/src/info.cpp index ca90a6cc2f..f2e7f96271 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -121,6 +121,12 @@ using namespace std; template static void print_columns(FILE* fp, map * styles); +template +static bool find_style(const LAMMPS * lmp, map * styles, const string & name, bool suffix_check); + +template +static vector get_style_names(map * styles); + /* ---------------------------------------------------------------------- */ void Info::command(int narg, char **arg) @@ -868,73 +874,9 @@ bool Info::is_active(const char *category, const char *name) bool Info::is_available(const char *category, const char *name) { if ((category == NULL) || (name == NULL)) return false; - const int len = strlen(name); - int match = 0; - if (strcmp(category,"command") == 0) { - if (input->command_map->find(name) != input->command_map->end()) - match = 1; - - } else if (strcmp(category,"compute") == 0) { - if (modify->compute_map->find(name) != modify->compute_map->end()) - match = 1; - - if (!match && lmp->suffix_enable) { - if (lmp->suffix) { - char *name_w_suffix = new char [len + 2 + strlen(lmp->suffix)]; - sprintf(name_w_suffix,"%s/%s",name,lmp->suffix); - if (modify->compute_map->find(name_w_suffix) != modify->compute_map->end()) - match = 1; - delete[] name_w_suffix; - } - if (!match && lmp->suffix2) { - char *name_w_suffix = new char [len + 2 + strlen(lmp->suffix2)]; - sprintf(name_w_suffix,"%s/%s",name,lmp->suffix2); - if (modify->compute_map->find(name_w_suffix) != modify->compute_map->end()) - match = 1; - delete[] name_w_suffix; - } - } - } else if (strcmp(category,"fix") == 0) { - if (modify->fix_map->find(name) != modify->fix_map->end()) - match = 1; - - if (!match && lmp->suffix_enable) { - if (lmp->suffix) { - char *name_w_suffix = new char [len + 2 + strlen(lmp->suffix)]; - sprintf(name_w_suffix,"%s/%s",name,lmp->suffix); - if (modify->fix_map->find(name_w_suffix) != modify->fix_map->end()) - match = 1; - delete[] name_w_suffix; - } - if (!match && lmp->suffix2) { - char *name_w_suffix = new char [len + 2 + strlen(lmp->suffix2)]; - sprintf(name_w_suffix,"%s/%s",name,lmp->suffix2); - if (modify->fix_map->find(name_w_suffix) != modify->fix_map->end()) - match = 1; - delete[] name_w_suffix; - } - } - } else if (strcmp(category,"pair_style") == 0) { - if (force->pair_map->find(name) != force->pair_map->end()) - match = 1; - - if (!match && lmp->suffix_enable) { - if (lmp->suffix) { - char *name_w_suffix = new char [len + 2 + strlen(lmp->suffix)]; - sprintf(name_w_suffix,"%s/%s",name,lmp->suffix); - if (force->pair_map->find(name_w_suffix) != force->pair_map->end()) - match = 1; - delete[] name_w_suffix; - } - if (!match && lmp->suffix2) { - char *name_w_suffix = new char [len + 2 + strlen(lmp->suffix2)]; - sprintf(name_w_suffix,"%s/%s",name,lmp->suffix2); - if (force->pair_map->find(name_w_suffix) != force->pair_map->end()) - match = 1; - delete[] name_w_suffix; - } - } + if (has_style(category, name)) { + return true; } else if (strcmp(category,"feature") == 0) { if (strcmp(name,"gzip") == 0) { return has_gzip_support(); @@ -949,7 +891,7 @@ bool Info::is_available(const char *category, const char *name) } } else error->all(FLERR,"Unknown category for info is_available()"); - return match ? true : false; + return false; } /* ---------------------------------------------------------------------- */ @@ -1001,6 +943,7 @@ bool Info::is_defined(const char *category, const char *name) } else if (strcmp(category,"variable") == 0) { int nvar = input->variable->nvar; char **names = input->variable->names; + for (int i=0; i < nvar; ++i) { if (strcmp(names[i],name) == 0) return true; @@ -1010,6 +953,111 @@ bool Info::is_defined(const char *category, const char *name) return false; } +bool Info::has_style(const string & category, const string & name) +{ + if ( category == "atom" ) { + return find_style(lmp, atom->avec_map, name, false); + } else if( category == "integrate" ) { + return find_style(lmp, update->integrate_map, name, true); + } else if( category == "minimize" ) { + return find_style(lmp, update->minimize_map, name, true); + } else if( category == "pair" ) { + return find_style(lmp, force->pair_map, name, true); + } else if( category == "bond" ) { + return find_style(lmp, force->bond_map, name, true); + } else if( category == "angle" ) { + return find_style(lmp, force->angle_map, name, true); + } else if( category == "dihedral" ) { + return find_style(lmp, force->dihedral_map, name, true); + } else if( category == "improper" ) { + return find_style(lmp, force->improper_map, name, true); + } else if( category == "kspace" ) { + return find_style(lmp, force->kspace_map, name, true); + } else if( category == "fix" ) { + return find_style(lmp, modify->fix_map, name, true); + } else if( category == "compute" ) { + return find_style(lmp, modify->compute_map, name, true); + } else if( category == "region" ) { + return find_style(lmp, domain->region_map, name, false); + } else if( category == "dump" ) { + return find_style(lmp, output->dump_map, name, false); + } else if( category == "command" ) { + return find_style(lmp, input->command_map, name, false); + } + return false; +} + +vector Info::get_available_styles(const string & category) +{ + if ( category == "atom" ) { + return get_style_names(atom->avec_map); + } else if( category == "integrate" ) { + return get_style_names(update->integrate_map); + } else if( category == "minimize" ) { + return get_style_names(update->minimize_map); + } else if( category == "pair" ) { + return get_style_names(force->pair_map); + } else if( category == "bond" ) { + return get_style_names(force->bond_map); + } else if( category == "angle" ) { + return get_style_names(force->angle_map); + } else if( category == "dihedral" ) { + return get_style_names(force->dihedral_map); + } else if( category == "improper" ) { + return get_style_names(force->improper_map); + } else if( category == "kspace" ) { + return get_style_names(force->kspace_map); + } else if( category == "fix" ) { + return get_style_names(modify->fix_map); + } else if( category == "compute" ) { + return get_style_names(modify->compute_map); + } else if( category == "region" ) { + return get_style_names(domain->region_map); + } else if( category == "dump" ) { + return get_style_names(output->dump_map); + } else if( category == "command" ) { + return get_style_names(input->command_map); + } + return vector(); +} + +template +static vector get_style_names(map * styles) +{ + vector names; + + names.reserve(styles->size()); + for(auto const& kv : *styles) { + names.push_back(kv.first); + } + + return names; +} + +template +static bool find_style(const LAMMPS* lmp, map * styles, const string & name, bool suffix_check) +{ + if (styles->find(name) != styles->end()) { + return true; + } + + if (suffix_check && lmp->suffix_enable) { + if (lmp->suffix) { + string name_w_suffix = name + "/" + lmp->suffix; + if (find_style(lmp, styles, name_w_suffix, false)) { + return true; + } + } + if (lmp->suffix2) { + string name_w_suffix = name + "/" + lmp->suffix2; + if (find_style(lmp, styles, name_w_suffix, false)) { + return true; + } + } + } + return false; +} + template static void print_columns(FILE* fp, map * styles) { diff --git a/src/info.h b/src/info.h index 01d6105ff2..14e4afcc19 100644 --- a/src/info.h +++ b/src/info.h @@ -21,6 +21,8 @@ CommandStyle(info,Info) #define LMP_INFO_H #include "pointers.h" +#include +#include namespace LAMMPS_NS { @@ -33,6 +35,9 @@ class Info : protected Pointers { bool is_defined(const char *, const char *); bool is_available(const char *, const char *); + bool has_style(const std::string & category, const std::string & name); + std::vector get_available_styles(const std::string & category); + static bool has_gzip_support(); static bool has_png_support(); static bool has_jpeg_support(); diff --git a/src/library.cpp b/src/library.cpp index 72fcbba833..ee3a847030 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -1658,6 +1658,31 @@ int lammps_config_package_name(int index, char * buffer, int max_size) { return false; } +int lammps_has_style(void * ptr, char * category, char * name) { + LAMMPS *lmp = (LAMMPS *) ptr; + Info info(lmp); + return info.has_style(category, name); +} + +int lammps_style_count(void * ptr, char * category) { + LAMMPS *lmp = (LAMMPS *) ptr; + Info info(lmp); + return info.get_available_styles(category).size(); +} + +int lammps_style_name(void* ptr, char * category, int index, char * buffer, int max_size) { + LAMMPS *lmp = (LAMMPS *) ptr; + Info info(lmp); + auto styles = info.get_available_styles(category); + + if (index < styles.size()) { + strncpy(buffer, styles[index].c_str(), max_size); + return true; + } + + return false; +} + int lammps_config_has_gzip_support() { return Info::has_gzip_support(); } diff --git a/src/library.h b/src/library.h index 2076371316..d078474454 100644 --- a/src/library.h +++ b/src/library.h @@ -89,6 +89,10 @@ int lammps_config_has_jpeg_support(); int lammps_config_has_ffmpeg_support(); int lammps_config_has_exceptions(); +int lammps_has_style(void* ptr, char * category, char * name); +int lammps_style_count(void* ptr, char * category); +int lammps_style_name(void*ptr, char * category, int index, char * buffer, int max_size); + int lammps_find_pair_neighlist(void* ptr, char * style, int exact, int nsub, int request); int lammps_find_fix_neighlist(void* ptr, char * id, int request); int lammps_find_compute_neighlist(void* ptr, char * id, int request);