4.15. Utility functions — LAMMPS documentation

\(\renewcommand{\AA}{\text{Å}}\)

# 4.15. Utility functions

The `utils` sub-namespace inside the `LAMMPS_NS` namespace provides a collection of convenience functions and utilities that perform common tasks that are required repeatedly throughout the LAMMPS code like reading or writing to files with error checking or translation of strings into specific types of numbers with checking for validity. This reduces redundant implementations and encourages consistent behavior and thus has some overlap with the “platform” sub-namespace.

## 4.15.1. I/O with status check and similar functions

The the first two functions are wrappers around the corresponding C library calls `fgets()` or `fread()`. They will check if there were errors on reading or an unexpected end-of-file state was reached. In that case, the functions will stop with an error message, indicating the name of the problematic file, if possible unless the error argument is a NULL pointer.

The `utils::fgets_trunc()` function will work similar for `fgets()` but it will read in a whole line (i.e. until the end of line or end of file), but store only as many characters as will fit into the buffer including a final newline character and the terminating NULL byte. If the line in the file is longer it will thus be truncated in the buffer. This function is used by `utils::read_lines_from_file()` to read individual lines but make certain they follow the size constraints.

The `utils::read_lines_from_file()` function will read the requested number of lines of a maximum length into a buffer and will return 0 if successful or 1 if not. It also guarantees that all lines are terminated with a newline character and the entire buffer with a NULL character.

void LAMMPS_NS::utils::sfgets(const char *srcname, int srcline, char *s, int size, FILE *fp, const char *filename, Error *error)

  Safe wrapper around fgets() which aborts on errors or EOF and prints a suitable error message to help debugging.

  Use nullptr as the error parameter to avoid the abort on EOF or error.

  Parameters:

    - srcname – name of the calling source file (from FLERR macro)

    - srcline – line in the calling source file (from FLERR macro)

    - s – buffer for storing the result of fgets()

    - size – size of buffer s (max number of bytes read by fgets())

    - fp – file pointer used by fgets()

    - filename – file name associated with fp (may be a null pointer; then LAMMPS will try to detect)

    - error – pointer to Error class instance (for abort) or nullptr

void LAMMPS_NS::utils::sfread(const char *srcname, int srcline, void *s, size_t size, size_t num, FILE *fp, const char *filename, Error *error)

  Safe wrapper around fread() which aborts on errors or EOF and prints a suitable error message to help debugging.

  Use nullptr as the error parameter to avoid the abort on EOF or error.

  Parameters:

    - srcname – name of the calling source file (from FLERR macro)

    - srcline – line in the calling source file (from FLERR macro)

    - s – buffer for storing the result of fread()

    - size – size of data elements read by fread()

    - num – number of data elements read by fread()

    - fp – file pointer used by fread()

    - filename – file name associated with fp (may be a null pointer; then LAMMPS will try to detect)

    - error – pointer to Error class instance (for abort) or nullptr

char *LAMMPS_NS::utils::fgets_trunc(char *s, int size, FILE *fp)

  Wrapper around fgets() which reads whole lines but truncates the data to the buffer size and ensures a newline char at the end.

  This function is useful for reading line based text files with possible comments that should be parsed later. This applies to data files, potential files, atomfile variable files and so on. It is used instead of fgets() by utils::read_lines_from_file().

  Parameters:

    - s – buffer for storing the result of fgets()

    - size – size of buffer s (max number of bytes returned)

    - fp – file pointer used by fgets()

int LAMMPS_NS::utils::read_lines_from_file(FILE *fp, int nlines, int nmax, char *buffer, int me, MPI_Comm comm)

  Read N lines of text from file into buffer and broadcast them

  This function uses repeated calls to fread() to fill a buffer with newline terminated text. If a line does not end in a newline (e.g. at the end of a file), it is added. The caller has to allocate an nlines by nmax sized buffer for storing the text data. Reading is done by MPI rank 0 of the given communicator only, and thus only MPI rank 0 needs to provide a valid file pointer.

  Parameters:

    - fp – file pointer used by fread

    - nlines – number of lines to be read

    - nmax – maximum length of a single line

    - buffer – buffer for storing the data.

    - me – MPI rank of calling process in MPI communicator

    - comm – MPI communicator for broadcast

  Returns:

    1 if the read was short, 0 if read was successful

## 4.15.2. String to number conversions with validity check

These functions should be used to convert strings to numbers. They are are strongly preferred over C library calls like `atoi()` or `atof()` since they check if the entire string is a valid (floating-point or integer) number, and will error out instead of silently returning the result of a partial conversion or zero in cases where the string is not a valid number. This behavior improves detecting typos or issues when processing input files.

Similarly the `utils::logical()` function will convert a string into a boolean and will only accept certain words.

The do_abort flag should be set to `true` in case this function is called only on a single MPI rank, as that will then trigger the a call to `Error::one()` for errors instead of `Error::all()` and avoids a “hanging” calculation when run in parallel.

Please also see `utils::is_integer()` and `utils::is_double()` for testing strings for compliance without conversion.

double LAMMPS_NS::utils::numeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)

  Convert a string to a floating point number while checking if it is a valid floating point or integer number

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be converted to number

    - do_abort – determines whether to call Error::one() or Error::all()

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    double precision floating point number

double LAMMPS_NS::utils::numeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)

  This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be converted to number

    - do_abort – determines whether to call Error::one() or Error::all()

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    double precision floating point number

int LAMMPS_NS::utils::inumeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)

  Convert a string to an integer number while checking if it is a valid integer number (regular int)

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be converted to number

    - do_abort – determines whether to call Error::one() or Error::all()

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    integer number (regular int)

int LAMMPS_NS::utils::inumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)

  This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be converted to number

    - do_abort – determines whether to call Error::one() or Error::all()

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    double precision floating point number

bigint LAMMPS_NS::utils::bnumeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)

  Convert a string to an integer number while checking if it is a valid integer number (bigint)

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be converted to number

    - do_abort – determines whether to call Error::one() or Error::all()

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    integer number (bigint)

bigint LAMMPS_NS::utils::bnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)

  This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be converted to number

    - do_abort – determines whether to call Error::one() or Error::all()

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    double precision floating point number

tagint LAMMPS_NS::utils::tnumeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)

  Convert a string to an integer number while checking if it is a valid integer number (tagint)

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be converted to number

    - do_abort – determines whether to call Error::one() or Error::all()

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    integer number (tagint)

tagint LAMMPS_NS::utils::tnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)

  This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be converted to number

    - do_abort – determines whether to call Error::one() or Error::all()

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    double precision floating point number

int LAMMPS_NS::utils::logical(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)

  Convert a string to a boolean while checking whether it is a valid boolean term. Valid terms are ‘yes’, ‘no’, ‘true’, ‘false’, ‘on’, ‘off’, and ‘1’, ‘0’. Only lower case is accepted.

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be converted to logical

    - do_abort – determines whether to call Error::one() or Error::all()

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    1 if string resolves to “true”, otherwise 0

int LAMMPS_NS::utils::logical(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)

  This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be converted to logical

    - do_abort – determines whether to call Error::one() or Error::all()

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    1 if string resolves to “true”, otherwise 0

## 4.15.3. String processing

The following are functions to help with processing strings and parsing files or arguments.

char *LAMMPS_NS::utils::strdup(const std::string &text)

  Make C-style copy of string in new storage

  This allocates a storage buffer and copies the C-style or C++ style string into it. The buffer is allocated with “new” and thus needs to be deallocated with “delete[]”.

  Parameters:

    text – string that should be copied

  Returns:

    new buffer with copy of string

std::string LAMMPS_NS::utils::lowercase(const std::string &line)

  Convert string to lowercase

  Parameters:

    line – string that should be converted

  Returns:

    new string with all lowercase characters

std::string LAMMPS_NS::utils::uppercase(const std::string &line)

  Convert string to uppercase

  Parameters:

    line – string that should be converted

  Returns:

    new string with all uppercase characters

std::string LAMMPS_NS::utils::trim(const std::string &line)

  Trim leading and trailing whitespace. Like TRIM() in Fortran.

  Parameters:

    line – string that should be trimmed

  Returns:

    new string without whitespace (string)

std::string LAMMPS_NS::utils::trim_comment(const std::string &line)

  Return string with anything from the first ‘#’ character onward removed

  Parameters:

    line – string that should be trimmed

  Returns:

    new string without comment (string)

std::string LAMMPS_NS::utils::strip_style_suffix(const std::string &style, LAMMPS *lmp)

  Remove style suffix from string if suffix flag is active

  This will try to undo the effect from using the suffix command or the -suffix/-sf command line flag and return correspondingly modified string.

       \param style  string of style name
       \param lmp    pointer to the LAMMPS class (has suffix_flag and suffix strings)
       \return  processed string

std::string LAMMPS_NS::utils::star_subst(const std::string &name, bigint step, int pad)

  Replace first ‘*’ character in a string with a number, optionally zero-padded

  If there is no ‘*’ character in the string, return the original string. If the number requires more characters than the value of the pad argument, do not add zeros; otherwise add as many zeroes as needed to the left to make the the number representation pad characters wide.

  Parameters:

    - name – string with file containing a ‘*’ (or not)

    - step – step number to replace the (first) ‘*’

    - pad – zero-padding (may be zero)

  Returns:

    processed string

inline bool LAMMPS_NS::utils::has_utf8(const std::string &line)

  Check if a string will likely have UTF-8 encoded characters

  UTF-8 uses the 7-bit standard ASCII table for the first 127 characters and all other characters are encoded as multiple bytes. For the multi-byte characters the first byte has either the highest two, three, or four bits set followed by a zero bit and followed by one, two, or three more bytes, respectively, where the highest bit is set and the second highest bit set to 0. The remaining bits combined are the character code, which is thus limited to 21-bits.

  For the sake of efficiency this test only checks if a character in the string has the highest bit set and thus is very likely an UTF-8 character. It will not be able to tell this this is a valid UTF-8 character or whether it is a 2-byte, 3-byte, or 4-byte character.

  See also

    `utils::utf8_subst()`

  Parameters:

    line – string that should be checked

  Returns:

    true if string contains UTF-8 encoded characters (bool)

std::string LAMMPS_NS::utils::utf8_subst(const std::string &line)

  Replace known UTF-8 characters with ASCII equivalents

  See also

    `utils::has_utf8()`

  Parameters:

    line – string that should be converted

  Returns:

    new string with ascii replacements (string)

size_t LAMMPS_NS::utils::count_words(const char *text)

  Count words in C-string, ignore any whitespace matching ” \t\r\n\f”

  Parameters:

    text – string that should be searched

  Returns:

    number of words found

size_t LAMMPS_NS::utils::count_words(const std::string &text)

  Count words in string, ignore any whitespace matching ” \t\r\n\f”

  Parameters:

    text – string that should be searched

  Returns:

    number of words found

size_t LAMMPS_NS::utils::count_words(const std::string &text, const std::string &separators)

  Count words in string with custom choice of separating characters

  Parameters:

    - text – string that should be searched

    - separators – string containing characters that will be treated as whitespace

  Returns:

    number of words found

size_t LAMMPS_NS::utils::trim_and_count_words(const std::string &text, const std::string &separators = " \t\r\n\f")

  Count words in a single line, trim anything from ‘#’ onward

  Parameters:

    - text – string that should be trimmed and searched

    - separators – string containing characters that will be treated as whitespace

  Returns:

    number of words found

std::string LAMMPS_NS::utils::join_words(const std::vector<std::string> &words, const std::string &sep)

  Take list of words and join them with a given separator text.

  This is the inverse operation of what the split_words() function Tokenizer classes do.

  Parameters:

    - words – STL vector with strings

    - sep – separator string (may be empty)

  Returns:

    string with the concatenated words and separators

std::vector<std::string> LAMMPS_NS::utils::split_words(const std::string &text)

  Take text and split into non-whitespace words.

  This can handle strings with single and double quotes, escaped quotes, and escaped codes within quotes, but due to using an STL container and STL strings is rather slow because of making copies. Designed for parsing command lines and similar text and not for time critical processing. Use a tokenizer class if performance matters.

  See also

    `Tokenizer`, `ValueTokenizer`

  Parameters:

    text – string that should be split

  Returns:

    STL vector with the words

std::vector<std::string> LAMMPS_NS::utils::split_lines(const std::string &text)

  Take multi-line text and split into lines

  Parameters:

    text – string that should be split

  Returns:

    STL vector with the lines

bool LAMMPS_NS::utils::strmatch(const std::string &text, const std::string &pattern)

  Match text against a simplified regex pattern

  More flexible and specific matching of a string against a pattern. This function is supposed to be a more safe, more specific and simple to use API to find pattern matches. The purpose is to replace uses of either strncmp() or strstr() in the code base to find sub-strings safely. With strncmp() finding prefixes, the number of characters to match must be counted, which can lead to errors, while using “^pattern” will do the same with less problems. Matching for suffixes using strstr() is not as specific as ‘pattern$’, and complex matches, e.g. “^rigid.*\/small.*”, to match all small body optimized rigid fixes require only one test.

  The use of std::string arguments allows for simple concatenation even with char * type variables. Example: utils::strmatch(text, std::string(“^”) + charptr)

  Parameters:

    - text – the text to be matched against the pattern

    - pattern – the search pattern, which may contain regexp markers

  Returns:

    true if the pattern matches, false if not

std::string LAMMPS_NS::utils::strfind(const std::string &text, const std::string &pattern)

  Find sub-string that matches a simplified regex pattern

  This function is a companion function to utils::strmatch(). Arguments and logic is the same, but instead of a boolean, it returns the sub-string that matches the regex pattern. There can be only one match. This can be used as a more flexible alternative to strstr().

  Parameters:

    - text – the text to be matched against the pattern

    - pattern – the search pattern, which may contain regexp markers

  Returns:

    the string that matches the pattern or an empty one

bool LAMMPS_NS::utils::is_integer(const std::string &str)

  Check if string can be converted to valid integer

  Parameters:

    str – string that should be checked

  Returns:

    true, if string contains valid a integer, false otherwise

bool LAMMPS_NS::utils::is_double(const std::string &str)

  Check if string can be converted to valid floating-point number

  Parameters:

    str – string that should be checked

  Returns:

    true, if string contains valid number, false otherwise

bool LAMMPS_NS::utils::is_id(const std::string &str)

  Check if string is a valid ID ID strings may contain only letters, numbers, and underscores.

  Parameters:

    str – string that should be checked

  Returns:

    true, if string contains valid id, false otherwise

int LAMMPS_NS::utils::is_type(const std::string &str)

  Check if string is a valid type label, or numeric type, or numeric type range. Numeric type or type range may only contain digits or the ‘*’ character. Type label strings may not contain a digit, or a ‘*’, or a ‘#’ character as the first character to distinguish them from comments and numeric types or type ranges. They also may not contain any whitespace. If the string is a valid numeric type or type range the function returns 0, if it is a valid type label the function returns 1, otherwise it returns -1.

  Parameters:

    str – string that should be checked

  Returns:

    0, 1, or -1, depending on whether the string is valid numeric type, valid type label or neither, respectively

## 4.15.4. Potential file functions

std::string LAMMPS_NS::utils::get_potential_file_path(const std::string &path)

  Determine full path of potential file. If file is not found in current directory, search directories listed in LAMMPS_POTENTIALS environment variable

  Parameters:

    path – file path

  Returns:

    full path to potential file

std::string LAMMPS_NS::utils::get_potential_date(const std::string &path, const std::string &potential_name)

  Read potential file and return DATE field if it is present

  Parameters:

    - path – file path

    - potential_name – name of potential that is being read

  Returns:

    DATE field if present

std::string LAMMPS_NS::utils::get_potential_units(const std::string &path, const std::string &potential_name)

  Read potential file and return UNITS field if it is present

  Parameters:

    - path – file path

    - potential_name – name of potential that is being read

  Returns:

    UNITS field if present

int LAMMPS_NS::utils::get_supported_conversions(const int property)

  Return bitmask of available conversion factors for a given property

  Parameters:

    property – property to be converted

  Returns:

    bitmask indicating available conversions

double LAMMPS_NS::utils::get_conversion_factor(const int property, const int conversion)

  Return unit conversion factor for given property and selected from/to units

  Parameters:

    - property – property to be converted

    - conversion – constant indicating the conversion

  Returns:

    conversion factor

FILE *LAMMPS_NS::utils::open_potential(const std::string &name, LAMMPS *lmp, int *auto_convert)

  Open a potential file as specified by name

  If opening the file directly fails, the function will search for it in the list of folder pointed to by the environment variable `LAMMPS_POTENTIALS` (if it is set).

  If the potential file has a `UNITS` tag in the first line, the tag’s value is compared to the current unit style setting. The behavior of the function then depends on the value of the auto_convert parameter. If it is a null pointer, then the unit values must match or else the open will fail with an error. Otherwise the bitmask that auto_convert points to is used check for compatibility with possible automatic conversions by the calling function. If compatible, the bitmask is set to the required conversion or `utils::NOCONVERT`.

  Parameters:

    - name – file- or pathname of the potential file

    - lmp – pointer to top-level LAMMPS class instance

    - auto_convert – pointer to unit conversion bitmask or `nullptr`

  Returns:

    FILE pointer of the opened potential file or `nullptr`

## 4.15.5. Argument processing

template<typename TYPE>
void LAMMPS_NS::utils::bounds(const char *file, int line, const std::string &str, bigint nmin, bigint nmax, TYPE &nlo, TYPE &nhi, Error *error)

  Compute index bounds derived from a string with a possible wildcard

  This functions processes the string in str and set the values of nlo and nhi according to the following five cases:

  - a single number, i: nlo = i; nhi = i;

  - a single asterisk, *: nlo = nmin; nhi = nmax;

  - a single number followed by an asterisk, i*: nlo = i; nhi = nmax;

  - a single asterisk followed by a number, *i: nlo = nmin; nhi = i;

  - two numbers with an asterisk in between. i*j: nlo = i; nhi = j;

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – string to be processed

    - nmin – smallest possible lower bound

    - nmax – largest allowed upper bound

    - nlo – lower bound

    - nhi – upper bound

    - error – pointer to Error class for out-of-bounds messages

int LAMMPS_NS::utils::expand_args(const char *file, int line, int narg, char **arg, int mode, char **&earg, LAMMPS *lmp)

  Expand list of arguments when containing fix/compute wildcards

  This function searches the list of arguments in arg for strings of the kind c_ID[*], f_ID[*], v_ID[*], i2_ID[*], d2_ID[*], or c_ID:gname:dname[*] referring to computes, fixes, vector style variables, custom per-atom arrays, or grids, respectively. Any such strings are replaced by one or more strings with the ‘*’ character replaced by the corresponding possible numbers as determined from the fix, compute, variable, property, or grid instance. Unrecognized strings are just copied. If the mode parameter is set to 0, expand global vectors, but not global arrays; if it is set to 1, expand global arrays (by column) but not global vectors.

  If any expansion happens, the earg list and all its strings are new allocations and must be freed explicitly by the caller. Otherwise arg and earg will point to the same address and no explicit de-allocation is needed by the caller.

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - narg – number of arguments in current list

    - arg – argument list, possibly containing wildcards

    - mode – select between global vectors(=0) and arrays (=1)

    - earg – new argument list with wildcards expanded

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    number of arguments in expanded list

std::vector<std::string> LAMMPS_NS::utils::parse_grid_id(const char *file, int line, const std::string &name, Error *error)

  Parse grid reference into 3 sub-strings

  Format of grid ID reference = id:gname:dname Return vector with the 3 sub-strings

  Parameters:

    name – = complete grid ID

  Returns:

    std::vector<std::string> containing the 3 sub-strings

char *LAMMPS_NS::utils::expand_type(const char *file, int line, const std::string &str, int mode, LAMMPS *lmp)

  Expand type label string into its equivalent numeric type

  This function checks if a given string may be a type label and then searches the labelmap type indicated by the mode argument for the corresponding numeric type. If this is found a copy of the numeric type string is made and returned. Otherwise a null pointer is returned. If a string is returned, the calling code must free it with delete[].

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - str – type string to be expanded

    - mode – select labelmap using constants from Atom class

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    pointer to expanded string or null pointer

## 4.15.6. Convenience functions

template<typename ...Args>
void LAMMPS_NS::utils::logmesg(LAMMPS *lmp, const std::string &format, Args&&... args)

  Send formatted message to screen and logfile, if available

  This function simplifies the repetitive task of outputting some message to both the screen and/or the log file. The template wrapper with fmtlib format and argument processing allows this function to work similar to `fmt::print()`.

  Parameters:

    - lmp – pointer to LAMMPS class instance

    - format – format string of message to be printed

    - args – arguments to format string

void LAMMPS_NS::utils::logmesg(LAMMPS *lmp, const std::string &mesg)

  This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

  Parameters:

    - lmp – pointer to LAMMPS class instance

    - mesg – string with message to be printed

std::string LAMMPS_NS::utils::errorurl(int errorcode)

  Return text redirecting the user to a specific paragraph in the manual

  The LAMMPS manual contains detailed detailed explanations for errors and warnings where a simple error message may not be sufficient. These can be reached through URLs with a numeric code. This function creates the corresponding text to be included into the error message that redirects the user to that URL.

  Parameters:

    errorcode – number pointing to a paragraph in the manual

void LAMMPS_NS::utils::missing_cmd_args(const std::string &file, int line, const std::string &cmd, Error *error)

  Print error message about missing arguments for command

  This function simplifies the repetitive reporting missing arguments to a command.

  Parameters:

    - file – name of source file for error message

    - line – line number in source file for error message

    - cmd – name of the failing command

    - error – pointer to Error class instance (for abort) or nullptr

void LAMMPS_NS::utils::flush_buffers(LAMMPS *lmp)

  Flush output buffers

  This function calls fflush() on screen and logfile FILE pointers if available and thus tells the operating system to output all currently buffered data. This is local operation and independent from buffering by a file system or an MPI library.

std::string LAMMPS_NS::utils::getsyserror()

  Return a string representing the current system error status

  This is a wrapper around calling strerror(errno).

  Returns:

    error string

std::string LAMMPS_NS::utils::check_packages_for_style(const std::string &style, const std::string &name, LAMMPS *lmp)

  Report if a requested style is in a package or may have a typo

  Parameters:

    - style – type of style that is to be checked for

    - name – name of style that was not found

    - lmp – pointer to top-level LAMMPS class instance

  Returns:

    string usable for error messages

double LAMMPS_NS::utils::timespec2seconds(const std::string &timespec)

  Convert a time string to seconds

  The strings “off” and “unlimited” result in -1

  Parameters:

    timespec – a string in the following format: ([[HH:]MM:]SS)

  Returns:

    total in seconds

int LAMMPS_NS::utils::date2num(const std::string &date)

  Convert a LAMMPS version date to a number

  This will generate a number YYYYMMDD from a date string (with or without blanks) that is suitable for numerical comparisons, i.e. later dates will generate a larger number.

  The day may or may not have a leading zero, the month is identified by the first 3 letters (so there may be more) and the year may be 2 or 4 digits (the missing 2 digits will be assumed as 20. That is 04 corresponds to 2004).

  No check is made whether the date is valid.

  Parameters:

    date – string in the format (Day Month Year)

  Returns:

    date code

std::string LAMMPS_NS::utils::current_date()

  Return current date as string

  This will generate a string containing the current date in YYYY-MM-DD format.

  Returns:

    string with current date

## 4.15.7. Customized standard functions

int LAMMPS_NS::utils::binary_search(const double needle, const int n, const double *haystack)

  Binary search in a vector of ascending doubles of length N

  If the value is smaller than the smallest value in the vector, 0 is returned. If the value is larger or equal than the largest value in the vector, N-1 is returned. Otherwise the index that satisfies the condition

  haystack[index] <= value < haystack[index+1]

  is returned, i.e. a value from 1 to N-2. Note that if there are tied values in the haystack, always the larger index is returned as only that satisfied the condition.

  Parameters:

    - needle – search value for which are are looking for the closest index

    - n – size of the haystack array

    - haystack – array with data in ascending order.

  Returns:

    index of value in the haystack array smaller or equal to needle

void LAMMPS_NS::utils::merge_sort(int *index, int num, void *ptr, int (*comp)(int, int, void*))

  Custom merge sort implementation

  This function provides a custom upward hybrid merge sort implementation with support to pass an opaque pointer to the comparison function, e.g. for access to class members. This avoids having to use global variables. For improved performance, it uses an in-place insertion sort on initial chunks of up to 64 elements and switches to merge sort from then on.

  Parameters:

    - index – Array with indices to be sorted

    - num – Length of the index array

    - ptr – Pointer to opaque object passed to comparison function

    - comp – Pointer to comparison function

# 4.16. Special Math functions

The `MathSpecial` namespace implements a selection of custom and optimized mathematical functions for a variety of applications.

double LAMMPS_NS::MathSpecial::factorial(const int n)

  Fast tabulated factorial function

  This function looks up pre-computed factorial values for arguments of n = 0 to a maximum of 167, which is the maximal value representable by a double precision floating point number. For other values of n a NaN value is returned.

  Parameters:

    n – argument (valid: 0 <= n <= 167)

  Returns:

    value of n! as double precision number or NaN

double LAMMPS_NS::MathSpecial::exp2_x86(double x)

  Fast implementation of 2^x without argument checks for little endian CPUs

  This function implements an optimized version of pow(2.0, x) that does not check for valid arguments and thus may only be used where arguments are well behaved. The implementation makes assumptions about the layout of double precision floating point numbers in memory and thus will only work on little endian CPUs. If little endian cannot be safely detected, the result of calling pow(2.0, x) will be returned. This function also is the basis for the fast exponential fm_exp(x).

  Parameters:

    x – argument

  Returns:

    value of 2^x as double precision number

double LAMMPS_NS::MathSpecial::fm_exp(double x)

  Fast implementation of exp(x) for little endian CPUs

  This function implements an optimized version of exp(x) for little endian CPUs. It calls the exp2_x86(x) function with a suitable prefactor to x to return exp(x). The implementation makes assumptions about the layout of double precision floating point numbers in memory and thus will only work on little endian CPUs. If little endian cannot be safely detected, the result of calling the exp(x) implementation in the standard math library will be returned.

  Parameters:

    x – argument

  Returns:

    value of e^x as double precision number

static inline double LAMMPS_NS::MathSpecial::my_erfcx(const double x)

  Fast scaled error function complement exp(x*x)*erfc(x) for coul/long styles

  This is a portable fast implementation of exp(x*x)*erfc(x) that can be used in coul/long pair styles as a replacement for the polynomial expansion that is/was widely used. Unlike the polynomial expansion, that is only accurate at the level of single precision floating point it provides full double precision accuracy, but at comparable speed (unlike the erfc() implementation shipped with GNU standard math library).

  Parameters:

    x – argument

  Returns:

    value of e^(x*x)*erfc(x)

static inline double LAMMPS_NS::MathSpecial::expmsq(double x)

  Fast implementation of exp(-x*x) for little endian CPUs for coul/long styles

  This function implements an optimized version of exp(-x*x) based on exp2_x86() for use with little endian CPUs. If little endian cannot be safely detected, the result of calling the exp(-x*x) implementation in the standard math library will be returned.

  Parameters:

    x – argument

  Returns:

    value of e^(-x*x) as double precision number

static inline double LAMMPS_NS::MathSpecial::square(const double &x)

  Fast inline version of pow(x, 2.0)

  Parameters:

    x – argument

  Returns:

    x*x

static inline double LAMMPS_NS::MathSpecial::cube(const double &x)

  Fast inline version of pow(x, 3.0)

  Parameters:

    x – argument

  Returns:

    x*x

static inline double LAMMPS_NS::MathSpecial::powsign(const int n)

static inline double LAMMPS_NS::MathSpecial::powint(const double &x, const int n)

static inline double LAMMPS_NS::MathSpecial::powsinxx(const double &x, int n)

# 4.17. Tokenizer classes

The purpose of the tokenizer classes is to simplify the recurring task of breaking lines of text down into words and/or numbers. Traditionally, LAMMPS code would be using the `strtok()` function from the C library for that purpose, but that function has two significant disadvantages: 1) it cannot be used concurrently from different LAMMPS instances since it stores its status in a global variable and 2) it modifies the string that it is processing. These classes were implemented to avoid both of these issues and also to reduce the amount of code that needs to be written.

The basic procedure is to create an instance of the tokenizer class with the string to be processed as an argument and then do a loop until all available tokens are read. The constructor has a default set of separator characters, but that can be overridden. The default separators are all “whitespace” characters, i.e. the space character, the tabulator character, the carriage return character, the linefeed character, and the form feed character.

Tokenizer class example listing entries of the PATH environment variable

    #include "tokenizer.h"
    #include <cstdlib>
    #include <string>
    #include <iostream>

    using namespace LAMMPS_NS;

    int main(int, char **)
    {
        const char *path = getenv("PATH");

        if (path != nullptr) {
            Tokenizer p(path,":");
            while (p.has_next())
                std::cout << "Entry: " << p.next() << "\n";
        }
        return 0;
    }

Most tokenizer operations cannot fail except for `LAMMPS_NS::Tokenizer::next()` (when used without first checking with `LAMMPS_NS::Tokenizer::has_next()`) and `LAMMPS_NS::Tokenizer::skip()`. In case of failure, the class will throw an exception, so you may need to wrap the code using the tokenizer into a `try` / `catch` block to handle errors. The `LAMMPS_NS::ValueTokenizer` class may also throw an exception when a (type of) number is requested as next token that is not compatible with the string representing the next word.

ValueTokenizer class example with exception handling

    #include "tokenizer.h"
    #include <cstdlib>
    #include <string>
    #include <iostream>

    using namespace LAMMPS_NS;

    int main(int, char **)
    {
        const char *text = "1 2 3 4 5 20.0 21 twentytwo 2.3";
        double num1(0),num2(0),num3(0),num4(0);

        ValueTokenizer t(text);
        // read 4 doubles after skipping over 5 numbers
        try {
            t.skip(5);
            num1 = t.next_double();
            num2 = t.next_double();
            num3 = t.next_double();
            num4 = t.next_double();
        } catch (TokenizerException &e) {
            std::cout << "Reading numbers failed: " << e.what() << "\n";
        }
        std::cout << "Values: " << num1 << " " << num2 << " " << num3 << " " << num4 << "\n";
        return 0;
    }

This code example should produce the following output:

    Reading numbers failed: Not a valid floating-point number: 'twentytwo'
    Values: 20 21 0 0

class Tokenizer

  Public Functions

  Tokenizer(std::string str, std::string separators = TOKENIZER_DEFAULT_SEPARATORS)

    Class for splitting text into words

    This tokenizer will break down a string into sub-strings (i.e words) separated by the given separator characters. If the string contains certain known UTF-8 characters they will be replaced by their ASCII equivalents processing the string.

    See also

      `ValueTokenizer`, `utils::split_words()`, `utils::utf8_subst()`

    Parameters:

      - str – string to be processed

      - _separators – string with separator characters (default: ” \t\r\n\f”)

  void reset()

    Re-position the tokenizer state to the first word, i.e. the first non-separator character

  void skip(int n = 1)

    Skip over a given number of tokens

    Parameters:

      n – number of tokens to skip over

  bool has_next() const

    Indicate whether more tokens are available

    Returns:

      true if there are more tokens, false if not

  bool contains(const std::string &str) const

    Search the text to be processed for a sub-string.

    Parameters:

      str – string to be searched for

    Returns:

      true if string was found, false if not

  std::string next()

    Retrieve next token.

    Returns:

      string with the next token

  size_t count()

    Count number of tokens in text.

    Returns:

      number of counted tokens

  std::vector<std::string> as_vector()

    Retrieve the entire text converted to an STL vector of tokens.

    Returns:

      The STL vector

class TokenizerException : public exception

  General Tokenizer exception class

  Subclassed by InvalidFloatException, InvalidIntegerException

  Public Functions

  explicit TokenizerException(const std::string &msg, const std::string &token)

    Thrown during retrieving or skipping tokens

    Parameters:

      - msg – String with error message

      - token – String of the token/word that caused the error

  inline const char *what() const noexcept override

    Retrieve message describing the thrown exception

    Returns:

      string with error message

class ValueTokenizer

  Public Functions

  ValueTokenizer(const std::string &str, const std::string &separators = TOKENIZER_DEFAULT_SEPARATORS)

    Class for reading text with numbers

    See also

      `Tokenizer`

    See also

    Tokenizer InvalidIntegerException InvalidFloatException

    Parameters:

      - str – String to be processed

      - separators – String with separator characters (default: ” \t\r\n\f”)

  std::string next_string()

    Retrieve next token

    Returns:

      string with next token

  tagint next_tagint()

    Retrieve next token and convert to tagint

    Returns:

      value of next token

  bigint next_bigint()

    Retrieve next token and convert to bigint

    Returns:

      value of next token

  int next_int()

    Retrieve next token and convert to int

    Returns:

      value of next token

  double next_double()

    Retrieve next token and convert to double

    Returns:

      value of next token

  bool has_next() const

    Indicate whether more tokens are available

    Returns:

      true if there are more tokens, false if not

  bool contains(const std::string &value) const

    Search the text to be processed for a sub-string.

    Parameters:

      value – string with value to be searched for

    Returns:

      true if string was found, false if not

  void skip(int ntokens = 1)

    Skip over a given number of tokens

    Parameters:

      n – number of tokens to skip over

  size_t count()

    Count number of tokens in text.

    Returns:

      number of counted tokens

class InvalidIntegerException : public TokenizerException

  Exception thrown by ValueTokenizer when trying to convert an invalid integer string

  Public Functions

  inline explicit InvalidIntegerException(const std::string &token)

    Thrown during converting string to integer number

    Parameters:

      token – String of the token/word that caused the error

class InvalidFloatException : public TokenizerException

  Exception thrown by ValueTokenizer when trying to convert an floating point string

  Public Functions

  inline explicit InvalidFloatException(const std::string &token)

    Thrown during converting string to floating point number

    Parameters:

      token – String of the token/word that caused the error

# 4.18. Argument parsing classes

The purpose of argument parsing classes it to simplify and unify how arguments of commands in LAMMPS are parsed and to make abstractions of repetitive tasks.

The `LAMMPS_NS::ArgInfo` class provides an abstraction for parsing references to compute or fix styles, variables or custom integer or double properties handled by fix property/atom. These would start with a “c_”, “f_”, “v_”, “d_”, “d2_”, “i_”, or “i2_” followed by the ID or name of than instance and may be postfixed with one or two array indices “[<number>]” with numbers > 0.

A typical code segment would look like this:

Usage example for ArgInfo class

    int nvalues = 0;
    for (iarg = 0; iarg < nargnew; iarg++) {
      ArgInfo argi(arg[iarg]);

      which[nvalues] = argi.get_type();
      argindex[nvalues] = argi.get_index1();
      ids[nvalues] = argi.copy_name();

      if ((which[nvalues] == ArgInfo::UNKNOWN)
           || (which[nvalues] == ArgInfo::NONE)
           || (argi.get_dim() > 1))
        error->all(FLERR,"Illegal compute XXX command");

      nvalues++;
    }

class ArgInfo

  Public Types

  enum ArgTypes

    constants for argument types

    Values:

    enumerator ERROR
    enumerator UNKNOWN
    enumerator NONE
    enumerator X
    enumerator V
    enumerator F
    enumerator COMPUTE
    enumerator FIX
    enumerator VARIABLE
    enumerator KEYWORD
    enumerator TYPE
    enumerator MOLECULE
    enumerator DNAME
    enumerator INAME
    enumerator DENSITY_NUMBER
    enumerator DENSITY_MASS
    enumerator MASS
    enumerator TEMPERATURE
    enumerator BIN1D
    enumerator BIN2D
    enumerator BIN3D
    enumerator BINSPHERE
    enumerator BINCYLINDER

  Public Functions

  ArgInfo(const std::string &arg, int allowed = COMPUTE | FIX | VARIABLE)

    Class for processing references to fixes, computes and variables

    This class provides an abstraction for the repetitive task of parsing arguments that may contain references to fixes, computes, variables, or custom per-atom properties. It will identify the name and the index value in the first and second dimension, if present.

    Parameters:

      - arg – string with possible reference

      - allowed – integer with bitmap of allowed types of references

  inline int get_type() const

    get type of reference

    Return a type constant for the reference. This may be either COMPUTE, FIX, VARIABLE (if not restricted to a subset of those by the “allowed” argument of the constructor) or NONE, if it if not a recognized or allowed reference, or UNKNOWN, in case some error happened identifying or parsing the values of the indices

    Returns:

      integer with a constant from ArgTypes enumerator

  inline int get_dim() const

    get dimension of reference

    This will return either 0, 1, 2 depending on whether the reference has no, one or two “[{number}]” postfixes.

    Returns:

      integer with the dimensionality of the reference

  inline int get_index1() const

    get index of first dimension

    This will return the number in the first “[{number}]” postfix or 0 if there is no postfix.

    Returns:

      integer with index or the postfix or 0

  inline int get_index2() const

    get index of second dimension

    This will return the number in the second “[{number}]” postfix or -1 if there is no second postfix.

    Returns:

      integer with index of the postfix or -1

  inline const char *get_name() const

    return reference to the ID or name of the reference

    This string is pointing to an internal storage element and is only valid to use while the ArgInfo class instance is in scope. If you need a long-lived string make a copy with copy_name().

    Returns:

      C-style char * string

  char *copy_name()

    make copy of the ID of the reference as C-style string

    The ID is copied into a buffer allocated with “new” and thus must be later deleted with “delete []” to avoid a memory leak. Because it is a full copy in a newly allocated buffer, the lifetime of this string extends beyond the the time the ArgInfo class is in scope.

    Returns:

      copy of string as char *

# 4.19. File reader classes

The purpose of the file reader classes is to simplify the recurring task of reading and parsing files. They can use the `ValueTokenizer` class to process the read in text. The `TextFileReader` is a more general version while `PotentialFileReader` is specialized to implement the behavior expected for looking up and reading/parsing files with potential parameters in LAMMPS. The potential file reader class requires a LAMMPS instance, requires to be run on MPI rank 0 only, will use the `utils::get_potential_file_path` function to look up and open the file, and will call the `LAMMPS_NS::Error` class in case of failures to read or to convert numbers, so that LAMMPS will be aborted.

Use of PotentialFileReader class in pair style coul/streitz

     PotentialFileReader reader(lmp, file, "coul/streitz");
     char * line;

     while((line = reader.next_line(NPARAMS_PER_LINE))) {
       try {
         ValueTokenizer values(line);
         std::string iname = values.next_string();

         int ielement;
         for (ielement = 0; ielement < nelements; ielement++)
           if (iname == elements[ielement]) break;

         if (nparams == maxparam) {
           maxparam += DELTA;
           params = (Param *) memory->srealloc(params,maxparam*sizeof(Param),
                                               "pair:params");
         }

         params[nparams].ielement = ielement;
         params[nparams].chi = values.next_double();
         params[nparams].eta = values.next_double();
         params[nparams].gamma = values.next_double();
         params[nparams].zeta = values.next_double();
         params[nparams].zcore = values.next_double();

       } catch (TokenizerException & e) {
         error->one(FLERR, e.what());
       }
       nparams++;
     }

A file that would be parsed by the reader code fragment looks like this:

    # DATE: 2015-02-19 UNITS: metal CONTRIBUTOR: Ray Shan CITATION: Streitz and Mintmire, Phys Rev B, 50, 11996-12003 (1994)
    #
    # X (eV)                J (eV)          gamma (1/AA)   zeta (1/AA)    Z (e)

    Al      0.000000        10.328655       0.000000        0.968438        0.763905
    O       5.484763        14.035715       0.000000        2.143957        0.000000

class TextFileReader

  Public Functions

  TextFileReader(const std::string &filename, const std::string &filetype)

    Class for reading and parsing text files

    The value of the class member variable ignore_comments controls whether any text following the pound sign (#) should be ignored (true) or not (false). Default: true, i.e. ignore.

    See also

      `TextFileReader`

    Parameters:

      - filename – Name of file to be read

      - filetype – Description of file type for error messages

  TextFileReader(FILE *fp, std::string filetype)

    This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

    This function is useful in combination with `utils::open_potential()`.

    Note

    The FILE pointer is not closed in the destructor, but will be advanced when reading from it.

    Parameters:

      - fp – File descriptor of the already opened file

      - filetype – Description of file type for error messages

  virtual ~TextFileReader()

    Closes the file

  void set_bufsize(int)

    adjust line buffer size

  void rewind()

    Reset file to the beginning

  void skip_line()

    Read the next line and ignore it

  char *next_line(int nparams = 0)

    Read the next line(s) until nparams words have been read.

    This reads a line and counts the words in it, if the number is less than the requested number, it will read the next line, as well. Output will be a string with all read lines combined. The purpose is to somewhat replicate the reading behavior of formatted files in Fortran.

    If the ignore_comments class member has the value true, then any text read in is truncated at the first ‘#’ character.

    Parameters:

      nparams – Number of words that must be read. Default: 0

    Returns:

      String with the concatenated text

  void next_dvector(double *list, int n)

    Read lines until n doubles have been read and stored in array list

    This reads lines from the file using the next_line() function, and splits them into floating-point numbers using the ValueTokenizer class and stores the number is the provided list.

    Parameters:

      - list – Pointer to array with suitable storage for n doubles

      - n – Number of doubles to be read

  ValueTokenizer next_values(int nparams, const std::string &separators = TOKENIZER_DEFAULT_SEPARATORS)

    Read text until nparams words are read and passed to a tokenizer object for custom parsing.

    This reads lines from the file using the next_line() function, and splits them into floating-point numbers using the ValueTokenizer class and stores the number is the provided list.

    Parameters:

      - nparams – Number of words to be read

      - separators – String with list of separators.

    Returns:

      ValueTokenizer object for read in text

  Public Members

  bool ignore_comments

    Controls whether comments are ignored.

class PotentialFileReader : protected Pointers

  Public Functions

  PotentialFileReader(class LAMMPS *lmp, const std::string &filename, const std::string &potential_name, const std::string &name_suffix, const int auto_convert = 0)

    Class for reading and parsing LAMMPS potential files

    The value of the class member variable ignore_comments controls whether any text following the pound sign (#) should be ignored (true) or not (false). Default: true, i.e. ignore.

    See also

      `TextFileReader`

    Parameters:

      - lmp – Pointer to LAMMPS instance

      - filename – Name of file to be read

      - potential_name – Name of potential style for error messages

      - name_suffix – Suffix added to potential name in error messages

      - auto_convert – Bitmask of supported unit conversions

  ~PotentialFileReader() override

    Closes the file

  void ignore_comments(bool value)

    Set comment (= text after ‘#’) handling preference for the file to be read

    Parameters:

      value – Comment text is ignored if true, or not if false

  void rewind()

    Reset file to the beginning

  void skip_line()

    Read a line but ignore its content

  char *next_line(int nparams = 0)

    Read the next line(s) until nparams words have been read.

    This reads a line and counts the words in it, if the number is less than the requested number, it will read the next line, as well. Output will be a string with all read lines combined. The purpose is to somewhat replicate the reading behavior of formatted files in Fortran.

    Parameters:

      nparams – Number of words that must be read. Default: 0

    Returns:

      String with the concatenated text

  void next_dvector(double *list, int n)

    Read lines until n doubles have been read and stored in array list

    This reads lines from the file using the next_line() function, and splits them into floating-point numbers using the ValueTokenizer class and stores the number is the provided list.

    Parameters:

      - list – Pointer to array with suitable storage for n doubles

      - n – Number of doubles to be read

  ValueTokenizer next_values(int nparams, const std::string &separators = TOKENIZER_DEFAULT_SEPARATORS)

    Read text until nparams words are read and passed to a tokenizer object for custom parsing.

    This reads lines from the file using the next_line() function, and splits them into floating-point numbers using the ValueTokenizer class and stores the number is the provided list.

    Parameters:

      - nparams – Number of words to be read

      - separators – String with list of separators.

    Returns:

      ValueTokenizer object for read in text

  double next_double()

    Read next line and convert first word to a double

    Returns:

      Value of first word in line as double

  int next_int()

    Read next line and convert first word to an int

    Returns:

      Value of first word in line as int

  tagint next_tagint()

    Read next line and convert first word to a tagint

    Returns:

      Value of first word in line as tagint

  bigint next_bigint()

    Read next line and convert first word to a bigint

    Returns:

      Value of first word in line as bigint

  std::string next_string()

    Read next line and return first word

    Returns:

      First word of read in line

# 4.20. Memory pool classes

The memory pool classes are used for cases where otherwise many small memory allocations would be needed and where the data would be either all used or all freed. One example for that is the storage of neighbor lists. The memory management strategy is based on the assumption that allocations will be in chunks of similar sizes. The allocation is then not done per individual call for a reserved chunk of memory, but for a “page” that can hold multiple chunks of data. A parameter for the maximum chunk size must be provided, as that is used to determine whether a new page of memory must be used.

The `MyPage` class offers two ways to reserve a chunk: 1) with `MyPage::get()` the chunk size needs to be known in advance, 2) with `MyPage::vget()` a pointer to the next chunk is returned, but its size is registered later with `MyPage::vgot()`.

Example of using `MyPage`

       #include "my_page.h"
       using namespace LAMMPS_NS;

       MyPage<double> *dpage = new MyPage<double>;
       // max size of chunk: 256, size of page: 10240 doubles (=81920 bytes)
       dpage->init(256,10240);

       double **build_some_lists(int num)
       {
           dpage->reset();
           double **dlist = new double*[num];
           for (int i=0; i < num; ++i) {
               double *dptr = dpage.vget();
               int jnum = 0;
               for (int j=0; j < jmax; ++j) {
                   // compute some dvalue for eligible loop index j
                   dptr[j] = dvalue;
                   ++jnum;
               }
               if (dpage.status() != 0) {
                   // handle out of memory or jnum too large errors
               }
               dpage.vgot(jnum);
               dlist[i] = dptr;
           }
           return dlist;
       }

template<class T>
class MyPage

  Templated class for storing chunks of datums in pages.

  The size of the chunk may vary from call to call, but must be less or equal than the maxchunk setting. The chunks are not returnable like with malloc() (i.e. you cannot call free() on them individually). One can only reset and start over. The purpose of this class is to replace many small memory allocations via malloc() with a few large ones. Since the pages are never freed until the class is re-initialized, they can be re-used without having to re-allocate them by calling the reset() method.

  The settings maxchunk, pagesize, and pagedelta control the memory allocation strategy. The maxchunk value represents the expected largest number of items per chunk. If there is less space left on the current page, a new page is allocated for the next chunk. The pagesize value represents how many items can fit on a single page. It should have space for multiple chunks of size maxchunk. The combination of these two parameters determines how much memory is wasted by either switching to the next page too soon or allocating too large pages that never get properly used. It is an error, if a requested chunk is larger than maxchunk. The pagedelta parameter determines how many pages are allocated in one go. In combination with the pagesize setting, this determines how often blocks of memory get allocated (fewer allocations will result in faster execution).

  Note

  This is a template class with explicit instantiation. If the class is used with a new data type a new explicit instantiation may need to be added at the end of the file `src/my_page.cpp` to avoid symbol lookup errors.

  Public Functions

  MyPage()

    Create a class instance

    Need to call init() before use to define allocation settings

  int init(int user_maxchunk = 1, int user_pagesize = 1024, int user_pagedelta = 1)

    (Re-)initialize the set of pages and allocation parameters.

    This also frees all previously allocated storage and allocates the first page(s).

    Parameters:

      - user_maxchunk – Expected maximum number of items for one chunk

      - user_pagesize – Number of items on a single memory page

      - user_pagedelta – Number of pages to allocate with one malloc

    Returns:

      1 if there were invalid parameters, 2 if there was an allocation error or 0 if successful

  T *get(int n = 1)

    Pointer to location that can store N items.

    This will allocate more pages as needed. If the parameter N is larger than the maxchunk setting an error is flagged.

    Parameters:

      n – number of items for which storage is requested

    Returns:

      memory location or null pointer, if error or allocation failed

  inline T *vget()

    Get pointer to location that can store maxchunk items.

    This will return the same pointer as the previous call to this function unless vgot() is called afterwards to record how many items of the chunk were actually used.

    Returns:

      pointer to chunk of memory or null pointer if run out of memory

  inline void vgot(int n)

    Mark N items as used of the chunk reserved with a preceding call to vget().

    This will advance the internal pointer inside the current memory page. It is not necessary to call this function for N = 0, that is the reserved storage was not used. A following call to vget() will then reserve the same location again. It is an error if N > maxchunk.

    Parameters:

      n – Number of items used in previously reserved chunk

  void reset()

    Reset state of memory pool without freeing any memory

  inline double size() const

    Return total size of allocated pages

    Returns:

      total storage used in bytes

  inline int status() const

    Return error status

    Returns:

      0 if no error, 1 requested chunk size > maxchunk, 2 if malloc failed

template<class T>
class MyPoolChunk

  Templated class for storing chunks of datums in pages.

  The size of the chunk may vary from call to call between the minchunk and maxchunk setting. Chunks may be returned to the pool for re-use. Chunks can be reserved in nbin different sizes between minchunk and maxchunk. The chunksperpage setting specifies how many chunks are stored on any page and the pagedelta setting determines how many pages are allocated in one go. Pages are never freed, so they can be re-used without re-allocation.

  Note

  This is a template class with explicit instantiation. If the class is used with a new data type a new explicit instantiation may need to be added at the end of the file `src/my_pool_chunk.cpp` to avoid symbol lookup errors.

  Public Functions

  MyPoolChunk(int user_minchunk = 1, int user_maxchunk = 1, int user_nbin = 1, int user_chunkperpage = 1024, int user_pagedelta = 1)

    Create a class instance and set memory pool parameters

    Parameters:

      - user_minchunk – Minimal chunk size

      - user_maxchunk – Maximal chunk size

      - user_nbin – Number of bins of different chunk sizes

      - user_chunkperpage – Number of chunks per page

      - user_pagedelta – Number of pages to allocate in one go

  ~MyPoolChunk()

    Destroy class instance and free all allocated memory

  T *get(int &index)

    Return pointer/index of unused chunk of size maxchunk

    Parameters:

      index – Index of chunk in memory pool

    Returns:

      Pointer to requested chunk of storage

  T *get(int n, int &index)

    Return pointer/index of unused chunk of size N

    Parameters:

      - n – Size of chunk

      - index – Index of chunk in memory pool

    Returns:

      Pointer to requested chunk of storage

  void put(int index)

    Put indexed chunk back into memory pool via free list

    Parameters:

      index – Memory chunk index returned by call to get()

  double size() const

    Return total size of allocated pages

    Returns:

      total storage used in bytes

  inline int status() const

    Return error status

    Returns:

      0 if no error, 1 if invalid input, 2 if malloc() failed, 3 if chunk > maxchunk

# 4.21. Eigensolver functions

The `MathEigen` sub-namespace of the `LAMMPS_NS` namespace contains functions and classes for eigensolvers. Currently only the `jacobi3 function` is used in various places in LAMMPS. That function is built on top of a group of more generic eigensolvers that are maintained in the `math_eigen_impl.h` header file. This header contains the implementation of three template classes:

1. “Jacobi” calculates all of the eigenvalues and eigenvectors of a dense, symmetric, real matrix.

2. The “PEigenDense” class only calculates the principal eigenvalue (ie. the largest or smallest eigenvalue), and its corresponding eigenvector. However it is much more efficient than “Jacobi” when applied to large matrices (larger than 13x13). PEigenDense also can understand complex-valued Hermitian matrices.

3. The “LambdaLanczos” class is a generalization of “PEigenDense” which can be applied to arbitrary sparse matrices.

The “math_eigen_impl.h” code is an amalgamation of jacobi_pd by Andrew Jewett at Scripps Research (under CC0-1.0 license) and Lambda Lanczos by Yuya Kurebayashi at Tohoku University (under MIT license)

int MathEigen::jacobi3(double const *const *mat, double *eval, double **evec)

  A specialized function which finds the eigenvalues and eigenvectors of a 3x3 matrix (in double ** format).

  Parameters:

    - mat – the 3x3 matrix you wish to diagonalize

    - eval – store the eigenvalues here

    - evec – store the eigenvectors here…

  Returns:

    0 if eigenvalue calculation converged, 1 if it failed

int MathEigen::jacobi3(double const mat[3][3], double *eval, double evec[3][3])

  This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

# 4.22. Communication buffer coding with ubuf

LAMMPS uses communication buffers where it collects data from various class instances and then exchanges the data with neighboring subdomains. For simplicity those buffers are defined as `double` buffers and used for doubles and integer numbers. This presents a unique problem when 64-bit integers are used. While the storage needed for a `double` is also 64-bit, it cannot be used by a simple assignment. To get around that limitation, LAMMPS uses the `ubuf` union. It is used in the various “pack” and “unpack” functions in the LAMMPS classes to store and retrieve integers that may be 64-bit from the communication buffers.

union ubuf
  #include <lmptype.h>

  Data structure for packing 32-bit and 64-bit integers into double (communication) buffers

  Using this union avoids aliasing issues by having member types (double, int) referencing the same buffer memory location.

  The explicit constructor for 32-bit integers prevents compilers from (incorrectly) calling the double constructor when storing an int into a double buffer.

  Usage:

  To copy an integer into a double buffer:

      double buf[2];
      int    foo =   1;
      tagint bar = 2<<40;
      buf[1] = ubuf(foo).d;
      buf[2] = ubuf(bar).d;

  To copy from a double buffer back to an int:

      foo = (int)    ubuf(buf[1]).i;
      bar = (tagint) ubuf(buf[2]).i;

  The typecasts prevent compiler warnings about possible truncation issues.

  Public Functions

  inline ubuf(const double &arg)
  inline ubuf(const int64_t &arg)
  inline ubuf(const int &arg)

  Public Members

  double d
  int64_t i