diff --git a/doc/src/Library_create.rst b/doc/src/Library_create.rst index 7303c499d1..350569e54e 100644 --- a/doc/src/Library_create.rst +++ b/doc/src/Library_create.rst @@ -9,7 +9,6 @@ This section documents the following functions: - :cpp:func:`lammps_close` - :cpp:func:`lammps_mpi_init` - :cpp:func:`lammps_mpi_finalize` -- :cpp:func:`lammps_free` -------------------- @@ -75,11 +74,6 @@ that may only be called once. See :cpp:func:`lammps_mpi_finalize` for an alternative to invoking ``MPI_Finalize()`` explicitly from the calling program. -The :cpp:func:`lammps_free` function is a clean-up -function to free memory that the library allocated previously -via other function calls. See below for notes in the descriptions -of the individual commands where such memory buffers were allocated. - ----------------------- .. doxygenfunction:: lammps_open @@ -109,8 +103,3 @@ of the individual commands where such memory buffers were allocated. .. doxygenfunction:: lammps_mpi_finalize :project: progguide - ------------------------ - -.. doxygenfunction:: lammps_free - :project: progguide diff --git a/doc/src/Library_utility.rst b/doc/src/Library_utility.rst index 2e81a785af..b2f3666f88 100644 --- a/doc/src/Library_utility.rst +++ b/doc/src/Library_utility.rst @@ -9,11 +9,18 @@ functions. They do not directly call the LAMMPS library. - :cpp:func:`lammps_set_fix_external_callback` - :cpp:func:`lammps_fix_external_set_energy_global` - :cpp:func:`lammps_fix_external_set_virial_global` +- :cpp:func:`lammps_free` - :cpp:func:`lammps_is_running` - :cpp:func:`lammps_force_timeout` - :cpp:func:`lammps_has_error` - :cpp:func:`lammps_get_last_error_message` +The :cpp:func:`lammps_free` function is a clean-up function to free +memory that the library had allocated previously via other function +calls. Look for notes in the descriptions of the individual commands +where such memory buffers were allocated that require the use of +:cpp:func:`lammps_free`. + ----------------------- .. doxygenfunction:: lammps_encode_image_flags @@ -41,6 +48,11 @@ functions. They do not directly call the LAMMPS library. ----------------------- +.. doxygenfunction:: lammps_free + :project: progguide + +----------------------- + .. doxygenfunction:: lammps_is_running :project: progguide diff --git a/src/library.cpp b/src/library.cpp index 64d80468e5..2fd1486bc2 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -348,26 +348,6 @@ void lammps_mpi_finalize() } } -/* ---------------------------------------------------------------------- */ - -/** Free memory buffer allocated by LAMMPS. - * -\verbatim embed:rst - -Some of the LAMMPS C library interface functions return data as pointer -to a buffer that has been allocated by LAMMPS or the library interface. -This function can be used to delete those in order to avoid memory -leaks. - -\endverbatim - * - * \param ptr pointer to data allocated by LAMMPS */ - -void lammps_free(void *ptr) -{ - free(ptr); -} - // ---------------------------------------------------------------------- // Library functions to process commands // ---------------------------------------------------------------------- @@ -553,125 +533,6 @@ void lammps_commands_string(void *handle, const char *str) // Library functions to extract info from LAMMPS or set data in LAMMPS // ----------------------------------------------------------------------- -/** Get numerical representation of the LAMMPS version date. - * -\verbatim embed:rst - -The :cpp:func:`lammps_version` function returns an integer representing -the version of the LAMMPS code in the format YYYYMMDD. This can be used -to implement backward compatibility in software using the LAMMPS library -interface. The specific format guarantees, that this version number is -growing with every new LAMMPS release. - -\endverbatim - * - * \param handle pointer to a previously created LAMMPS instance - * \return an integer representing the version data in the - * format YYYYMMDD */ - -int lammps_version(void *handle) -{ - LAMMPS *lmp = (LAMMPS *) handle; - return lmp->num_ver; -} - -/** Get operating system and architecture information - * -\verbatim embed:rst - -The :cpp:func:`lammps_get_os_info` function can be used to retrieve -detailed information about the hosting operating system and -compiler/runtime. -A suitable buffer for a C-style string has to be provided and its length. -If the assembled text will be truncated to not overflow this buffer. - -.. versionadded:: 9Oct2020 - -\endverbatim - * - * \param buffer string buffer to copy the information to - * \param buf_size size of the provided string buffer */ - -void lammps_get_os_info(char *buffer, int buf_size) -{ - if (buf_size <=0) return; - buffer[0] = buffer[buf_size-1] = '\0'; - std::string txt = Info::get_os_info() + "\n"; - txt += Info::get_compiler_info(); - txt += " with " + Info::get_openmp_info() + "\n"; - strncpy(buffer, txt.c_str(), buf_size-1); -} - -/* ---------------------------------------------------------------------- */ - -/** Get memory usage information - * -\verbatim embed:rst - -This function will retrieve memory usage information for the current -LAMMPS instance or process. The *meminfo* buffer will be filled with -3 different numbers (if supported by the operating system). The first -is the tally (in MBytes) of all large memory allocations made by LAMMPS. -This is a lower boundary of how much memory is requested and does not -account for memory allocated on the stack or allocations via ``new``. -The second number is the current memory allocation of the current process -as returned by a memory allocation reporting in the system library. The -third number is the maximum amount of RAM (not swap) used by the process -so far. If any of the two latter parameters is not supported by the operating -system it will be set to zero. - -.. versionadded:: 18Sep2020 - -\endverbatim - * - * \param handle pointer to a previously created LAMMPS instance - * \param meminfo buffer with space for at least 3 double to store - * data in. */ - -void lammps_memory_usage(void *handle, double *meminfo) -{ - LAMMPS *lmp = (LAMMPS *) handle; - Info info(lmp); - info.get_memory_info(meminfo); -} - -/* ---------------------------------------------------------------------- */ - -/** Return current LAMMPS world communicator as integer - * -\verbatim embed:rst - -This will take the LAMMPS "world" communicator and convert it to an -integer using ``MPI_Comm_c2f()``, so it is equivalent to the -corresponding MPI communicator in Fortran. This way it can be safely -passed around between different programming languages. To convert it -to the C language representation use ``MPI_Comm_f2c()``. - -If LAMMPS was compiled with MPI_STUBS, this function returns -1. - -.. versionadded:: 18Sep2020 - -*See also* - :cpp:func:`lammps_open_fortran` - -\endverbatim - * - * \param handle pointer to a previously created LAMMPS instance - * \return Fortran representation of the LAMMPS world communicator */ - -int lammps_get_mpi_comm(void *handle) -{ -#ifdef MPI_STUBS - return -1; -#else - LAMMPS *lmp = (LAMMPS *) handle; - MPI_Fint f_comm = MPI_Comm_c2f(lmp->world); - return f_comm; -#endif -} - -/* ---------------------------------------------------------------------- */ - /** Return the total number of atoms in the system. * \verbatim embed:rst @@ -861,6 +722,74 @@ void lammps_reset_box(void *handle, double *boxlo, double *boxhi, /* ---------------------------------------------------------------------- */ +/** Get memory usage information + * +\verbatim embed:rst + +This function will retrieve memory usage information for the current +LAMMPS instance or process. The *meminfo* buffer will be filled with +3 different numbers (if supported by the operating system). The first +is the tally (in MBytes) of all large memory allocations made by LAMMPS. +This is a lower boundary of how much memory is requested and does not +account for memory allocated on the stack or allocations via ``new``. +The second number is the current memory allocation of the current process +as returned by a memory allocation reporting in the system library. The +third number is the maximum amount of RAM (not swap) used by the process +so far. If any of the two latter parameters is not supported by the operating +system it will be set to zero. + +.. versionadded:: 18Sep2020 + +\endverbatim + * + * \param handle pointer to a previously created LAMMPS instance + * \param meminfo buffer with space for at least 3 double to store + * data in. */ + +void lammps_memory_usage(void *handle, double *meminfo) +{ + LAMMPS *lmp = (LAMMPS *) handle; + Info info(lmp); + info.get_memory_info(meminfo); +} + +/* ---------------------------------------------------------------------- */ + +/** Return current LAMMPS world communicator as integer + * +\verbatim embed:rst + +This will take the LAMMPS "world" communicator and convert it to an +integer using ``MPI_Comm_c2f()``, so it is equivalent to the +corresponding MPI communicator in Fortran. This way it can be safely +passed around between different programming languages. To convert it +to the C language representation use ``MPI_Comm_f2c()``. + +If LAMMPS was compiled with MPI_STUBS, this function returns -1. + +.. versionadded:: 18Sep2020 + +*See also* + :cpp:func:`lammps_open_fortran` + +\endverbatim + * + * \param handle pointer to a previously created LAMMPS instance + * \return Fortran representation of the LAMMPS world communicator */ + +int lammps_get_mpi_comm(void *handle) +{ +#ifdef MPI_STUBS + return -1; +#else + LAMMPS *lmp = (LAMMPS *) handle; + MPI_Fint f_comm = MPI_Comm_c2f(lmp->world); + return f_comm; +#endif +} + +/* ---------------------------------------------------------------------- */ + /** Query LAMMPS about global settings. * \verbatim embed:rst @@ -1023,6 +952,83 @@ int lammps_extract_setting(void *handle, const char *keyword) /* ---------------------------------------------------------------------- */ +/** Get data type of internal global LAMMPS variables or arrays. + * +\verbatim embed:rst + +This function returns an integer that encodes the data type of the global +property with the specified name. See :cpp:enum:`_LMP_DATATYPE_CONST` for valid +values. Callers of :cpp:func:`lammps_extract_global` can use this information +to then decide how to cast the (void*) pointer and access the data. + +.. versionadded:: 18Sep2020 + +\endverbatim + * + * \param handle pointer to a previously created LAMMPS instance + * \param name string with the name of the extracted property + * \return integer constant encoding the data type of the property + * or -1 if not found. */ + +int lammps_extract_global_datatype(void *handle, const char *name) +{ + if (strcmp(name,"dt") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"ntimestep") == 0) return LAMMPS_BIGINT; + if (strcmp(name,"atime") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"atimestep") == 0) return LAMMPS_BIGINT; + + if (strcmp(name,"boxlo") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"boxhi") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"boxxlo") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"boxxhi") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"boxylo") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"boxyhi") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"boxzlo") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"boxzhi") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"periodicity") == 0) return LAMMPS_INT; + if (strcmp(name,"triclinic") == 0) return LAMMPS_INT; + if (strcmp(name,"xy") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"xz") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"yz") == 0) return LAMMPS_DOUBLE; + + if (strcmp(name,"natoms") == 0) return LAMMPS_BIGINT; + if (strcmp(name,"nbonds") == 0) return LAMMPS_BIGINT; + if (strcmp(name,"nangles") == 0) return LAMMPS_BIGINT; + if (strcmp(name,"ndihedrals") == 0) return LAMMPS_BIGINT; + if (strcmp(name,"nimpropers") == 0) return LAMMPS_BIGINT; + if (strcmp(name,"nlocal") == 0) return LAMMPS_INT; + if (strcmp(name,"nghost") == 0) return LAMMPS_INT; + if (strcmp(name,"nmax") == 0) return LAMMPS_INT; + if (strcmp(name,"ntypes") == 0) return LAMMPS_INT; + + if (strcmp(name,"q_flag") == 0) return LAMMPS_INT; + + if (strcmp(name,"units") == 0) return LAMMPS_STRING; + if (strcmp(name,"boltz") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"hplanck") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"mvv2e") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"ftm2v") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"mv2d") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"nktv2p") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"qqr2e") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"qe2f") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"vxmu2f") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"xxt2kmu") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"dielectric") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"qqrd2e") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"e_mass") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"hhmrr2e") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"mvh2r") == 0) return LAMMPS_DOUBLE; + + if (strcmp(name,"angstrom") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"femtosecond") == 0) return LAMMPS_DOUBLE; + if (strcmp(name,"qelectron") == 0) return LAMMPS_DOUBLE; + + return -1; +} + +/* ---------------------------------------------------------------------- */ + /** Get pointer to internal global LAMMPS variables or arrays. * \verbatim embed:rst @@ -1379,6 +1385,33 @@ void *lammps_extract_global(void *handle, const char *name) /* ---------------------------------------------------------------------- */ +/** Get data type of a LAMMPS per-atom property + * +\verbatim embed:rst + +This function returns an integer that encodes the data type of the per-atom +property with the specified name. See :cpp:enum:`_LMP_DATATYPE_CONST` for valid +values. Callers of :cpp:func:`lammps_extract_atom` can use this information +to then decide how to cast the (void*) pointer and access the data. + +.. versionadded:: 18Sep2020 + +\endverbatim + * + * \param handle pointer to a previously created LAMMPS instance + * \param name string with the name of the extracted property + * \return integer constant encoding the data type of the property + * or -1 if not found. + * */ + +int lammps_extract_atom_datatype(void *handle, const char *name) +{ + LAMMPS *lmp = (LAMMPS *) handle; + return lmp->atom->extract_datatype(name); +} + +/* ---------------------------------------------------------------------- */ + /** Get pointer to a LAMMPS per-atom property. * \verbatim embed:rst @@ -1411,255 +1444,6 @@ void *lammps_extract_atom(void *handle, const char *name) return lmp->atom->extract(name); } -/* ---------------------------------------------------------------------- */ - -/** Get data type of internal global LAMMPS variables or arrays. - * -\verbatim embed:rst - -This function returns an integer that encodes the data type of the global -property with the specified name. See :cpp:enum:`_LMP_DATATYPE_CONST` for valid -values. Callers of :cpp:func:`lammps_extract_global` can use this information -to then decide how to cast the (void*) pointer and access the data. - -.. versionadded:: 18Sep2020 - -\endverbatim - * - * \param handle pointer to a previously created LAMMPS instance - * \param name string with the name of the extracted property - * \return integer constant encoding the data type of the property - * or -1 if not found. */ - -int lammps_extract_global_datatype(void *, const char *name) -{ - if (strcmp(name,"dt") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"ntimestep") == 0) return LAMMPS_BIGINT; - if (strcmp(name,"atime") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"atimestep") == 0) return LAMMPS_BIGINT; - - if (strcmp(name,"boxlo") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"boxhi") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"boxxlo") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"boxxhi") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"boxylo") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"boxyhi") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"boxzlo") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"boxzhi") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"periodicity") == 0) return LAMMPS_INT; - if (strcmp(name,"triclinic") == 0) return LAMMPS_INT; - if (strcmp(name,"xy") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"xz") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"yz") == 0) return LAMMPS_DOUBLE; - - if (strcmp(name,"natoms") == 0) return LAMMPS_BIGINT; - if (strcmp(name,"nbonds") == 0) return LAMMPS_BIGINT; - if (strcmp(name,"nangles") == 0) return LAMMPS_BIGINT; - if (strcmp(name,"ndihedrals") == 0) return LAMMPS_BIGINT; - if (strcmp(name,"nimpropers") == 0) return LAMMPS_BIGINT; - if (strcmp(name,"nlocal") == 0) return LAMMPS_INT; - if (strcmp(name,"nghost") == 0) return LAMMPS_INT; - if (strcmp(name,"nmax") == 0) return LAMMPS_INT; - if (strcmp(name,"ntypes") == 0) return LAMMPS_INT; - - if (strcmp(name,"q_flag") == 0) return LAMMPS_INT; - - if (strcmp(name,"units") == 0) return LAMMPS_STRING; - if (strcmp(name,"boltz") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"hplanck") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"mvv2e") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"ftm2v") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"mv2d") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"nktv2p") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"qqr2e") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"qe2f") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"vxmu2f") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"xxt2kmu") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"dielectric") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"qqrd2e") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"e_mass") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"hhmrr2e") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"mvh2r") == 0) return LAMMPS_DOUBLE; - - if (strcmp(name,"angstrom") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"femtosecond") == 0) return LAMMPS_DOUBLE; - if (strcmp(name,"qelectron") == 0) return LAMMPS_DOUBLE; - - return -1; -} - -/* ---------------------------------------------------------------------- */ - -/** Get data type of a LAMMPS per-atom property - * -\verbatim embed:rst - -This function returns an integer that encodes the data type of the per-atom -property with the specified name. See :cpp:enum:`_LMP_DATATYPE_CONST` for valid -values. Callers of :cpp:func:`lammps_extract_atom` can use this information -to then decide how to cast the (void*) pointer and access the data. - -.. versionadded:: 18Sep2020 - -\endverbatim - * - * \param handle pointer to a previously created LAMMPS instance - * \param name string with the name of the extracted property - * \return integer constant encoding the data type of the property - * or -1 if not found. - * */ - -int lammps_extract_atom_datatype(void *handle, const char *name) -{ - LAMMPS *lmp = (LAMMPS *) handle; - return lmp->atom->extract_datatype(name); -} - -/* ---------------------------------------------------------------------- */ - -/** Create N atoms from list of coordinates - * -\verbatim embed:rst - -The prototype for this function when compiling with ``-DLAMMPS_BIGBIG`` -is: - -.. code-block:: c - - int lammps_create_atoms(void *handle, int n, int64_t *id, int *type, double *x, double *v, int64_t *image, int bexpand); - -This function creates additional atoms from a given list of coordinates -and a list of atom types. Additionally the atom-IDs, velocities, and -image flags may be provided. If atom-IDs are not provided, they will be -automatically created as a sequence following the largest existing -atom-ID. - -This function is useful to add atoms to a simulation or - in tandem with -:cpp:func:`lammps_reset_box` - to restore a previously extracted and -saved state of a simulation. Additional properties for the new atoms -can then be assigned via the :cpp:func:`lammps_scatter_atoms` -:cpp:func:`lammps_extract_atom` functions. - -For non-periodic boundaries, atoms will **not** be created that have -coordinates outside the box unless it is a shrink-wrap boundary and the -shrinkexceed flag has been set to a non-zero value. For periodic -boundaries atoms will be wrapped back into the simulation cell and its -image flags adjusted accordingly, unless explicit image flags are -provided. - -The function returns the number of atoms created or -1 on failure, e.g. -when called before as box has been created. - -Coordinates and velocities have to be given in a 1d-array in the order -X(1),Y(1),Z(1),X(2),Y(2),Z(2),...,X(N),Y(N),Z(N). - -\endverbatim - * - * \param handle pointer to a previously created LAMMPS instance - * \param n number of atoms, N, to be added to the system - * \param id pointer to N atom IDs; ``NULL`` will generate IDs - * \param type pointer to N atom types (required) - * \param x pointer to 3N doubles with x-,y-,z- positions - of the new atoms (required) - * \param v pointer to 3N doubles with x-,y-,z- velocities - of the new atoms (set to 0.0 if ``NULL``) - * \param image pointer to N imageint sets of image flags, or ``NULL`` - * \param bexpand if 1, atoms outside of shrink-wrap boundaries will - still be created and not dropped and the box extended - * \return number of atoms created on success; - -1 on failure (no box, no atom IDs, etc.) */ - -int lammps_create_atoms(void *handle, int n, tagint *id, int *type, - double *x, double *v, imageint *image, - int bexpand) -{ - LAMMPS *lmp = (LAMMPS *) handle; - bigint natoms_prev = lmp->atom->natoms; - - BEGIN_CAPTURE - { - // error if box does not exist or tags not defined - - int flag = 0; - std::string msg("Failure in lammps_create_atoms: "); - if (lmp->domain->box_exist == 0) { - flag = 1; - msg += "trying to create atoms before before simulation box is defined"; - } - if (lmp->atom->tag_enable == 0) { - flag = 1; - msg += "must have atom IDs to use this function"; - } - - if (flag) { - if (lmp->comm->me == 0) lmp->error->warning(FLERR,msg.c_str()); - return -1; - } - - // loop over all N atoms on all MPI ranks - // if this proc would own it based on its coordinates, invoke create_atom() - // optionally set atom tags and velocities - - Atom *atom = lmp->atom; - Domain *domain = lmp->domain; - int nlocal = atom->nlocal; - - int nlocal_prev = nlocal; - double xdata[3]; - - for (int i = 0; i < n; i++) { - xdata[0] = x[3*i]; - xdata[1] = x[3*i+1]; - xdata[2] = x[3*i+2]; - imageint * img = image ? image + i : nullptr; - tagint tag = id ? id[i] : 0; - - // create atom only on MPI rank that would own it - - if (!domain->ownatom(tag, xdata, img, bexpand)) continue; - - atom->avec->create_atom(type[i],xdata); - if (id) atom->tag[nlocal] = id[i]; - else atom->tag[nlocal] = 0; - if (v) { - atom->v[nlocal][0] = v[3*i]; - atom->v[nlocal][1] = v[3*i+1]; - atom->v[nlocal][2] = v[3*i+2]; - } - if (image) atom->image[nlocal] = image[i]; - nlocal++; - } - - // if no tags are given explicitly, create new and unique tags - - if (id == nullptr) atom->tag_extend(); - - // reset box info, if extended when adding atoms. - - if (bexpand) domain->reset_box(); - - // need to reset atom->natoms inside LAMMPS - - bigint ncurrent = nlocal; - MPI_Allreduce(&ncurrent,&lmp->atom->natoms,1,MPI_LMP_BIGINT, - MPI_SUM,lmp->world); - - // init per-atom fix/compute/variable values for created atoms - - atom->data_fix_compute_variable(nlocal_prev,nlocal); - - // if global map exists, reset it - // invoke map_init() b/c atom count has grown - - if (lmp->atom->map_style != Atom::MAP_NONE) { - lmp->atom->map_init(); - lmp->atom->map_set(); - } - } - END_CAPTURE; - return (int) lmp->atom->natoms - natoms_prev; -} - // ---------------------------------------------------------------------- // Library functions to access data from computes, fixes, variables in LAMMPS // ---------------------------------------------------------------------- @@ -2154,27 +1938,16 @@ int lammps_set_variable(void *handle, char *name, char *str) Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -#if defined(LAMMPS_BIGBIG) -void lammps_gather_atoms(void *handle, char * /*name */, - int /*type*/, int /*count*/, void * /*data*/) +void lammps_gather_atoms(void *handle, char *name, int type, int count, void *data) { LAMMPS *lmp = (LAMMPS *) handle; BEGIN_CAPTURE { +#if defined(LAMMPS_BIGBIG) lmp->error->all(FLERR,"Library function lammps_gather_atoms() " "is not compatible with -DLAMMPS_BIGBIG"); - } - END_CAPTURE -} #else -void lammps_gather_atoms(void *handle, char *name, - int type, int count, void *data) -{ - LAMMPS *lmp = (LAMMPS *) handle; - - BEGIN_CAPTURE - { int i,j,offset; // error if tags are not defined or not consecutive @@ -2194,7 +1967,8 @@ void lammps_gather_atoms(void *handle, char *name, void *vptr = lmp->atom->extract(name); if (vptr == nullptr) { - lmp->error->warning(FLERR,"lammps_gather_atoms: unknown property name"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_atoms: unknown property name"); return; } @@ -2202,7 +1976,7 @@ void lammps_gather_atoms(void *handle, char *name, // use atom ID to insert each atom's values into copy // MPI_Allreduce with MPI_SUM to merge into data, ordered by atom ID - if (type == 0) { + if (type == LAMMPS_INT) { int *vector = nullptr; int **array = nullptr; const int imgunpack = (count == 3) && (strcmp(name,"image") == 0); @@ -2241,7 +2015,7 @@ void lammps_gather_atoms(void *handle, char *name, MPI_Allreduce(copy,data,count*natoms,MPI_INT,MPI_SUM,lmp->world); lmp->memory->destroy(copy); - } else { + } else if (type == LAMMPS_DOUBLE) { double *vector = nullptr; double **array = nullptr; if (count == 1) vector = (double *) vptr; @@ -2268,11 +2042,15 @@ void lammps_gather_atoms(void *handle, char *name, MPI_Allreduce(copy,data,count*natoms,MPI_DOUBLE,MPI_SUM,lmp->world); lmp->memory->destroy(copy); + } else { + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_atoms: unsupported data type"); + return; } +#endif } END_CAPTURE } -#endif /* ---------------------------------------------------------------------- gather the named atom-based entity for all atoms @@ -2295,27 +2073,16 @@ void lammps_gather_atoms(void *handle, char *name, Allgather Nlocal atoms from each proc into data ------------------------------------------------------------------------- */ -#if defined(LAMMPS_BIGBIG) -void lammps_gather_atoms_concat(void *handle, char * /*name */, - int /*type*/, int /*count*/, void * /*data*/) +void lammps_gather_atoms_concat(void *handle, char *name, int type, int count, void *data) { LAMMPS *lmp = (LAMMPS *) handle; BEGIN_CAPTURE { +#if defined(LAMMPS_BIGBIG) lmp->error->all(FLERR,"Library function lammps_gather_atoms_concat() " "is not compatible with -DLAMMPS_BIGBIG"); - } - END_CAPTURE -} #else -void lammps_gather_atoms_concat(void *handle, char *name, - int type, int count, void *data) -{ - LAMMPS *lmp = (LAMMPS *) handle; - - BEGIN_CAPTURE - { int i,offset; // error if tags are not defined @@ -2334,7 +2101,8 @@ void lammps_gather_atoms_concat(void *handle, char *name, void *vptr = lmp->atom->extract(name); if (vptr == nullptr) { - lmp->error->warning(FLERR,"lammps_gather_atoms: unknown property name"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_atoms: unknown property name"); return; } @@ -2426,10 +2194,10 @@ void lammps_gather_atoms_concat(void *handle, char *name, lmp->memory->destroy(recvcounts); lmp->memory->destroy(displs); +#endif } END_CAPTURE } -#endif /* ---------------------------------------------------------------------- gather the named atom-based entity for a subset of atoms @@ -2454,29 +2222,17 @@ void lammps_gather_atoms_concat(void *handle, char *name, Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -#if defined(LAMMPS_BIGBIG) -void lammps_gather_atoms_subset(void *handle, char * /*name */, - int /*type*/, int /*count*/, - int /*ndata*/, int * /*ids*/, void * /*data*/) -{ - LAMMPS *lmp = (LAMMPS *) handle; - - BEGIN_CAPTURE - { - lmp->error->all(FLERR,"Library function lammps_gather_atoms_subset() " - "is not compatible with -DLAMMPS_BIGBIG"); - } - END_CAPTURE -} -#else -void lammps_gather_atoms_subset(void *handle, char *name, - int type, int count, +void lammps_gather_atoms_subset(void *handle, char *name, int type, int count, int ndata, int *ids, void *data) { LAMMPS *lmp = (LAMMPS *) handle; BEGIN_CAPTURE { +#if defined(LAMMPS_BIGBIG) + lmp->error->all(FLERR,"Library function lammps_gather_atoms_subset() " + "is not compatible with -DLAMMPS_BIGBIG"); +#else int i,j,m,offset; tagint id; @@ -2494,8 +2250,9 @@ void lammps_gather_atoms_subset(void *handle, char *name, void *vptr = lmp->atom->extract(name); if (vptr == nullptr) { - lmp->error->warning(FLERR,"lammps_gather_atoms_subset: " - "unknown property name"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_atoms_subset: " + "unknown property name"); return; } @@ -2583,10 +2340,10 @@ void lammps_gather_atoms_subset(void *handle, char *name, MPI_Allreduce(copy,data,count*ndata,MPI_DOUBLE,MPI_SUM,lmp->world); lmp->memory->destroy(copy); } +#endif } END_CAPTURE } -#endif /* ---------------------------------------------------------------------- scatter the named atom-based entity in data to all atoms @@ -2604,27 +2361,16 @@ void lammps_gather_atoms_subset(void *handle, char *name, loop over Natoms, if I own atom ID, set its values from data ------------------------------------------------------------------------- */ -#if defined(LAMMPS_BIGBIG) -void lammps_scatter_atoms(void *handle, char * /*name */, - int /*type*/, int /*count*/, void * /*data*/) +void lammps_scatter_atoms(void *handle, char *name, int type, int count, void *data) { LAMMPS *lmp = (LAMMPS *) handle; BEGIN_CAPTURE { +#if defined(LAMMPS_BIGBIG) lmp->error->all(FLERR,"Library function lammps_scatter_atoms() " "is not compatible with -DLAMMPS_BIGBIG"); - } - END_CAPTURE -} #else -void lammps_scatter_atoms(void *handle, char *name, - int type, int count, void *data) -{ - LAMMPS *lmp = (LAMMPS *) handle; - - BEGIN_CAPTURE - { int i,j,m,offset; // error if tags are not defined or not consecutive or no atom map @@ -2645,9 +2391,10 @@ void lammps_scatter_atoms(void *handle, char *name, void *vptr = lmp->atom->extract(name); if(vptr == nullptr) { + if (lmp->comm->me == 0) lmp->error->warning(FLERR, "lammps_scatter_atoms: unknown property name"); - return; + return; } // copy = Natom length vector of per-atom values @@ -2709,10 +2456,10 @@ void lammps_scatter_atoms(void *handle, char *name, } } } +#endif } END_CAPTURE } -#endif /* ---------------------------------------------------------------------- scatter the named atom-based entity in data to a subset of atoms @@ -2732,29 +2479,17 @@ void lammps_scatter_atoms(void *handle, char *name, loop over Ndata, if I own atom ID, set its values from data ------------------------------------------------------------------------- */ -#if defined(LAMMPS_BIGBIG) -void lammps_scatter_atoms_subset(void *handle, char * /*name */, - int /*type*/, int /*count*/, - int /*ndata*/, int * /*ids*/, void * /*data*/) -{ - LAMMPS *lmp = (LAMMPS *) handle; - - BEGIN_CAPTURE - { - lmp->error->all(FLERR,"Library function lammps_scatter_atoms_subset() " - "is not compatible with -DLAMMPS_BIGBIG"); - } - END_CAPTURE -} -#else -void lammps_scatter_atoms_subset(void *handle, char *name, - int type, int count, +void lammps_scatter_atoms_subset(void *handle, char *name, int type, int count, int ndata, int *ids, void *data) { LAMMPS *lmp = (LAMMPS *) handle; BEGIN_CAPTURE { +#if defined(LAMMPS_BIGBIG) + lmp->error->all(FLERR,"Library function lammps_scatter_atoms_subset() " + "is not compatible with -DLAMMPS_BIGBIG"); +#else int i,j,m,offset; tagint id; @@ -2773,9 +2508,10 @@ void lammps_scatter_atoms_subset(void *handle, char *name, void *vptr = lmp->atom->extract(name); if(vptr == nullptr) { + if (lmp->comm->me == 0) lmp->error->warning(FLERR, "lammps_scatter_atoms_subset: unknown property name"); - return; + return; } // copy = Natom length vector of per-atom values @@ -2846,11 +2582,10 @@ void lammps_scatter_atoms_subset(void *handle, char *name, } } } +#endif } END_CAPTURE } -#endif - /* ---------------------------------------------------------------------- Contributing author: Thomas Swinburne (CNRS & CINaM, Marseille, France) @@ -2876,26 +2611,17 @@ void lammps_scatter_atoms_subset(void *handle, char *name, loop over Nlocal to fill vector with my values Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ + +void lammps_gather(void *handle, char *name, int type, int count, void *data) +{ + LAMMPS *lmp = (LAMMPS *) handle; + + BEGIN_CAPTURE + { #if defined(LAMMPS_BIGBIG) -void lammps_gather(void *ptr, char * /*name*/, int /*type*/, - int /*count*/, void * /*data*/) -{ - LAMMPS *lmp = (LAMMPS *) ptr; - - BEGIN_CAPTURE - { lmp->error->all(FLERR,"Library function lammps_gather" - " not compatible with -DLAMMPS_BIGBIG"); - } - END_CAPTURE -} + " not compatible with -DLAMMPS_BIGBIG"); #else -void lammps_gather(void *ptr, char *name, int type, int count, void *data) -{ - LAMMPS *lmp = (LAMMPS *) ptr; - - BEGIN_CAPTURE - { int i,j,offset,fcid,ltype; // error if tags are not defined or not consecutive @@ -2917,49 +2643,54 @@ void lammps_gather(void *ptr, char *name, int type, int count, void *data) fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_gather: unknown fix id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather: unknown fix id"); return; } if (lmp->modify->fix[fcid]->peratom_flag == 0) { - lmp->error->warning(FLERR,"lammps_gather:" - " fix does not return peratom data"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather:" + " fix does not return peratom data"); return; } if (count>1 && lmp->modify->fix[fcid]->size_peratom_cols != count) { - lmp->error->warning(FLERR,"lammps_gather:" - " count != values peratom for fix"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather:" + " count != values peratom for fix"); return; } if (lmp->update->ntimestep % lmp->modify->fix[fcid]->peratom_freq) { - lmp->error->all(FLERR,"lammps_gather:" - " fix not computed at compatible time"); + if (lmp->comm->me == 0) + lmp->error->all(FLERR,"lammps_gather:" + " fix not computed at compatible time"); return; } if(count==1) vptr = (void *) lmp->modify->fix[fcid]->vector_atom; else vptr = (void *) lmp->modify->fix[fcid]->array_atom; - - } if (vptr==nullptr && strstr(name,"c_") == name) { // compute fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_gather: unknown compute id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather: unknown compute id"); return; } if (lmp->modify->compute[fcid]->peratom_flag == 0) { - lmp->error->warning(FLERR,"lammps_gather:" - " compute does not return peratom data"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather:" + " compute does not return peratom data"); return; } if (count>1 && lmp->modify->compute[fcid]->size_peratom_cols != count) { - lmp->error->warning(FLERR,"lammps_gather:" - " count != values peratom for compute"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather:" + " count != values peratom for compute"); return; } @@ -2971,30 +2702,32 @@ void lammps_gather(void *ptr, char *name, int type, int count, void *data) } - - if (vptr==nullptr && strstr(name,"d_") == name) { // property / atom - + // property / atom + if ( (vptr == nullptr) && ((strstr(name,"d_") == name) + || (strstr(name,"i_") == name)) ) { fcid = lmp->atom->find_custom(&name[2], ltype); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_gather: unknown property/atom id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather: unknown property/atom id"); return; } if (ltype != type) { - lmp->error->warning(FLERR,"lammps_gather: mismatch property/atom type"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather: mismatch property/atom type"); return; } if (count != 1) { - lmp->error->warning(FLERR,"lammps_gather: property/atom has count=1"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather: property/atom has count=1"); return; } if(ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; else vptr = (void *) lmp->atom->dvector[fcid]; - } - if (vptr == nullptr) { - lmp->error->warning(FLERR,"lammps_gather: unknown property name"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather: unknown property name"); return; } @@ -3068,10 +2801,10 @@ void lammps_gather(void *ptr, char *name, int type, int count, void *data) MPI_Allreduce(copy,data,count*natoms,MPI_DOUBLE,MPI_SUM,lmp->world); lmp->memory->destroy(copy); } +#endif } END_CAPTURE } -#endif /* ---------------------------------------------------------------------- Contributing author: Thomas Swinburne (CNRS & CINaM, Marseille, France) @@ -3097,26 +2830,17 @@ void lammps_gather(void *ptr, char *name, int type, int count, void *data) loop over Nlocal to fill vector with my values Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -#if defined(LAMMPS_BIGBIG) -void lammps_gather_concat(void *ptr, char * /*name*/, int /*type*/, - int /*count*/, void * /*data*/) + +void lammps_gather_concat(void *handle, char *name, int type, int count, void *data) { - LAMMPS *lmp = (LAMMPS *) ptr; + LAMMPS *lmp = (LAMMPS *) handle; BEGIN_CAPTURE { +#if defined(LAMMPS_BIGBIG) lmp->error->all(FLERR,"Library function lammps_gather_concat" " not compatible with -DLAMMPS_BIGBIG"); - } - END_CAPTURE -} #else -void lammps_gather_concat(void *ptr, char *name, int type, int count, void *data) -{ - LAMMPS *lmp = (LAMMPS *) ptr; - - BEGIN_CAPTURE - { int i,offset,fcid,ltype; // error if tags are not defined or not consecutive @@ -3138,50 +2862,55 @@ void lammps_gather_concat(void *ptr, char *name, int type, int count, void *data fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_gather_concat: unknown fix id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat: unknown fix id"); return; } if (lmp->modify->fix[fcid]->peratom_flag == 0) { - lmp->error->warning(FLERR,"lammps_gather_concat:" - " fix does not return peratom data"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat:" + " fix does not return peratom data"); return; } if (count>1 && lmp->modify->fix[fcid]->size_peratom_cols != count) { - lmp->error->warning(FLERR,"lammps_gather_concat:" - " count != values peratom for fix"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat:" + " count != values peratom for fix"); return; } if (lmp->update->ntimestep % lmp->modify->fix[fcid]->peratom_freq) { - lmp->error->all(FLERR,"lammps_gather_concat:" - " fix not computed at compatible time"); + if (lmp->comm->me == 0) + lmp->error->all(FLERR,"lammps_gather_concat:" + " fix not computed at compatible time"); return; } if(count==1) vptr = (void *) lmp->modify->fix[fcid]->vector_atom; else vptr = (void *) lmp->modify->fix[fcid]->array_atom; - - } if (vptr==nullptr && strstr(name,"c_") == name) { // compute fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_gather_concat: unknown compute id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat: unknown compute id"); return; } if (lmp->modify->compute[fcid]->peratom_flag == 0) { - lmp->error->warning(FLERR,"lammps_gather_concat:" - " compute does not return peratom data"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat:" + " compute does not return peratom data"); return; } if (count>1 && lmp->modify->compute[fcid]->size_peratom_cols != count) { - lmp->error->warning(FLERR,"lammps_gather_concat:" - " count != values peratom for compute"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat:" + " count != values peratom for compute"); return; } @@ -3198,18 +2927,21 @@ void lammps_gather_concat(void *ptr, char *name, int type, int count, void *data fcid = lmp->atom->find_custom(&name[2], ltype); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_gather_concat: " - "unknown property/atom id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat: " + "unknown property/atom id"); return; } if (ltype != type) { - lmp->error->warning(FLERR,"lammps_gather_concat: " - "mismatch property/atom type"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat: " + "mismatch property/atom type"); return; } if (count != 1) { - lmp->error->warning(FLERR,"lammps_gather_concat: " - "property/atom has count=1"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat: " + "property/atom has count=1"); return; } if(ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; @@ -3218,7 +2950,8 @@ void lammps_gather_concat(void *ptr, char *name, int type, int count, void *data } if (vptr == nullptr) { - lmp->error->warning(FLERR,"lammps_gather_concat: unknown property name"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_concat: unknown property name"); return; } @@ -3310,10 +3043,10 @@ void lammps_gather_concat(void *ptr, char *name, int type, int count, void *data lmp->memory->destroy(recvcounts); lmp->memory->destroy(displs); +#endif } END_CAPTURE } -#endif /* ---------------------------------------------------------------------- Contributing author: Thomas Swinburne (CNRS & CINaM, Marseille, France) @@ -3339,29 +3072,19 @@ void lammps_gather_concat(void *ptr, char *name, int type, int count, void *data loop over Nlocal to fill vector with my values Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -#if defined(LAMMPS_BIGBIG) -void lammps_gather_subset(void *ptr, char * /*name */, - int /*type*/, int /*count*/, - int /*ndata*/, int * /*ids*/, void * /*data*/) -{ - LAMMPS *lmp = (LAMMPS *) ptr; - BEGIN_CAPTURE - { - lmp->error->all(FLERR,"Library function lammps_gather_subset() " - "is not compatible with -DLAMMPS_BIGBIG"); - } - END_CAPTURE -} -#else -void lammps_gather_subset(void *ptr, char *name, +void lammps_gather_subset(void *handle, char *name, int type, int count, int ndata, int *ids, void *data) { - LAMMPS *lmp = (LAMMPS *) ptr; + LAMMPS *lmp = (LAMMPS *) handle; BEGIN_CAPTURE { +#if defined(LAMMPS_BIGBIG) + lmp->error->all(FLERR,"Library function lammps_gather_subset() " + "is not compatible with -DLAMMPS_BIGBIG"); +#else int i,j,m,offset,fcid,ltype; tagint id; @@ -3381,50 +3104,54 @@ void lammps_gather_subset(void *ptr, char *name, fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_gather_subset: unknown fix id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_subset: unknown fix id"); return; } if (lmp->modify->fix[fcid]->peratom_flag == 0) { - lmp->error->warning(FLERR,"lammps_gather_subset:" - " fix does not return peratom data"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_subset:" + " fix does not return peratom data"); return; } + if (count>1 && lmp->modify->fix[fcid]->size_peratom_cols != count) { lmp->error->warning(FLERR,"lammps_gather_subset:" " count != values peratom for fix"); return; } - if (lmp->update->ntimestep % lmp->modify->fix[fcid]->peratom_freq) { - lmp->error->all(FLERR,"lammps_gather_subset:" - " fix not computed at compatible time"); + if (lmp->comm->me == 0) + lmp->error->all(FLERR,"lammps_gather_subset:" + " fix not computed at compatible time"); return; } if(count==1) vptr = (void *) lmp->modify->fix[fcid]->vector_atom; else vptr = (void *) lmp->modify->fix[fcid]->array_atom; - - } if (vptr==nullptr && strstr(name,"c_") == name) { // compute fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_gather_subset: unknown compute id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_subset: unknown compute id"); return; } if (lmp->modify->compute[fcid]->peratom_flag == 0) { - lmp->error->warning(FLERR,"lammps_gather_subset:" - " compute does not return peratom data"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_subset:" + " compute does not return peratom data"); return; } if (count>1 && lmp->modify->compute[fcid]->size_peratom_cols != count) { - lmp->error->warning(FLERR,"lammps_gather_subset:" - " count != values peratom for compute"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_subset:" + " count != values peratom for compute"); return; } @@ -3441,28 +3168,31 @@ void lammps_gather_subset(void *ptr, char *name, fcid = lmp->atom->find_custom(&name[2], ltype); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_gather_subset: " - "unknown property/atom id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_subset: " + "unknown property/atom id"); return; } if (ltype != type) { - lmp->error->warning(FLERR,"lammps_gather_subset: " - "mismatch property/atom type"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_subset: " + "mismatch property/atom type"); return; } if (count != 1) { - lmp->error->warning(FLERR,"lammps_gather_subset: " - "property/atom has count=1"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_subset: " + "property/atom has count=1"); return; } if(ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; else vptr = (void *) lmp->atom->dvector[fcid]; - } if (vptr == nullptr) { - lmp->error->warning(FLERR,"lammps_gather_subset: " - "unknown property name"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_gather_subset: " + "unknown property name"); return; } @@ -3550,10 +3280,10 @@ void lammps_gather_subset(void *ptr, char *name, MPI_Allreduce(copy,data,count*ndata,MPI_DOUBLE,MPI_SUM,lmp->world); lmp->memory->destroy(copy); } +#endif } END_CAPTURE } -#endif /* ---------------------------------------------------------------------- Contributing author: Thomas Swinburne (CNRS & CINaM, Marseille, France) @@ -3578,27 +3308,16 @@ void lammps_gather_subset(void *ptr, char *name, Allreduce to sum vector into data across all procs ------------------------------------------------------------------------- */ -#if defined(LAMMPS_BIGBIG) -void lammps_scatter(void *ptr, char * /*name */, - int /*type*/, int /*count*/, void * /*data*/) +void lammps_scatter(void *handle, char *name, int type, int count, void *data) { - LAMMPS *lmp = (LAMMPS *) ptr; + LAMMPS *lmp = (LAMMPS *) handle; BEGIN_CAPTURE { +#if defined(LAMMPS_BIGBIG) lmp->error->all(FLERR,"Library function lammps_scatter() " "is not compatible with -DLAMMPS_BIGBIG"); - } - END_CAPTURE -} #else -void lammps_scatter(void *ptr, char *name, - int type, int count, void *data) -{ - LAMMPS *lmp = (LAMMPS *) ptr; - - BEGIN_CAPTURE - { int i,j,m,offset,fcid,ltype; // error if tags are not defined or not consecutive or no atom map @@ -3623,43 +3342,47 @@ void lammps_scatter(void *ptr, char *name, fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_scatter: unknown fix id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter: unknown fix id"); return; } if (lmp->modify->fix[fcid]->peratom_flag == 0) { - lmp->error->warning(FLERR,"lammps_scatter:" - " fix does not return peratom data"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter:" + " fix does not return peratom data"); return; } if (count>1 && lmp->modify->fix[fcid]->size_peratom_cols != count) { - lmp->error->warning(FLERR,"lammps_scatter:" - " count != values peratom for fix"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter:" + " count != values peratom for fix"); return; } if(count==1) vptr = (void *) lmp->modify->fix[fcid]->vector_atom; else vptr = (void *) lmp->modify->fix[fcid]->array_atom; - - } if (vptr==nullptr && strstr(name,"c_") == name) { // compute fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_scatter: unknown compute id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter: unknown compute id"); return; } if (lmp->modify->compute[fcid]->peratom_flag == 0) { - lmp->error->warning(FLERR,"lammps_scatter:" - " compute does not return peratom data"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter:" + " compute does not return peratom data"); return; } if (count>1 && lmp->modify->compute[fcid]->size_peratom_cols != count) { - lmp->error->warning(FLERR,"lammps_scatter:" - " count != values peratom for compute"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter:" + " count != values peratom for compute"); return; } @@ -3676,15 +3399,18 @@ void lammps_scatter(void *ptr, char *name, fcid = lmp->atom->find_custom(&name[2], ltype); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_scatter: unknown property/atom id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter: unknown property/atom id"); return; } if (ltype != type) { - lmp->error->warning(FLERR,"lammps_scatter: mismatch property/atom type"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter: mismatch property/atom type"); return; } if (count != 1) { - lmp->error->warning(FLERR,"lammps_scatter: property/atom has count=1"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter: property/atom has count=1"); return; } if(ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; @@ -3693,8 +3419,9 @@ void lammps_scatter(void *ptr, char *name, } if(vptr == nullptr) { + if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_scatter: unknown property name"); - return; + return; } // copy = Natom length vector of per-atom values @@ -3756,10 +3483,10 @@ void lammps_scatter(void *ptr, char *name, } } } +#endif } END_CAPTURE } -#endif /* ---------------------------------------------------------------------- Contributing author: Thomas Swinburne (CNRS & CINaM, Marseille, France) @@ -3780,29 +3507,17 @@ void lammps_scatter(void *ptr, char *name, loop over Ndata, if I own atom ID, set its values from data ------------------------------------------------------------------------- */ -#if defined(LAMMPS_BIGBIG) -void lammps_scatter_subset(void *ptr, char * /*name */, - int /*type*/, int /*count*/, - int /*ndata*/, int * /*ids*/, void * /*data*/) -{ - LAMMPS *lmp = (LAMMPS *) ptr; - - BEGIN_CAPTURE - { - lmp->error->all(FLERR,"Library function lammps_scatter_subset() " - "is not compatible with -DLAMMPS_BIGBIG"); - } - END_CAPTURE -} -#else -void lammps_scatter_subset(void *ptr, char *name, - int type, int count, +void lammps_scatter_subset(void *handle, char *name,int type, int count, int ndata, int *ids, void *data) { - LAMMPS *lmp = (LAMMPS *) ptr; + LAMMPS *lmp = (LAMMPS *) handle; BEGIN_CAPTURE { +#if defined(LAMMPS_BIGBIG) + lmp->error->all(FLERR,"Library function lammps_scatter_subset() " + "is not compatible with -DLAMMPS_BIGBIG"); +#else int i,j,m,offset,fcid,ltype; tagint id; @@ -3825,43 +3540,47 @@ void lammps_scatter_subset(void *ptr, char *name, fcid = lmp->modify->find_fix(&name[2]); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_scatter_subset: unknown fix id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter_subset: unknown fix id"); return; } if (lmp->modify->fix[fcid]->peratom_flag == 0) { - lmp->error->warning(FLERR,"lammps_scatter_subset:" - " fix does not return peratom data"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter_subset:" + " fix does not return peratom data"); return; } if (count>1 && lmp->modify->fix[fcid]->size_peratom_cols != count) { - lmp->error->warning(FLERR,"lammps_scatter_subset:" - " count != values peratom for fix"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter_subset:" + " count != values peratom for fix"); return; } if(count==1) vptr = (void *) lmp->modify->fix[fcid]->vector_atom; else vptr = (void *) lmp->modify->fix[fcid]->array_atom; - - } if (vptr==nullptr && strstr(name,"c_") == name) { // compute fcid = lmp->modify->find_compute(&name[2]); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_scatter_subset: unknown compute id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter_subset: unknown compute id"); return; } if (lmp->modify->compute[fcid]->peratom_flag == 0) { - lmp->error->warning(FLERR,"lammps_scatter_subset:" - " compute does not return peratom data"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter_subset:" + " compute does not return peratom data"); return; } if (count>1 && lmp->modify->compute[fcid]->size_peratom_cols != count) { - lmp->error->warning(FLERR,"lammps_scatter_subset:" - " count != values peratom for compute"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter_subset:" + " count != values peratom for compute"); return; } @@ -3870,37 +3589,38 @@ void lammps_scatter_subset(void *ptr, char *name, if(count==1) vptr = (void *) lmp->modify->compute[fcid]->vector_atom; else vptr = (void *) lmp->modify->compute[fcid]->array_atom; - - } if (vptr==nullptr && strstr(name,"d_") == name) { // property / atom fcid = lmp->atom->find_custom(&name[2], ltype); if (fcid < 0) { - lmp->error->warning(FLERR,"lammps_scatter_subset: " - "unknown property/atom id"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter_subset: " + "unknown property/atom id"); return; } if (ltype != type) { - lmp->error->warning(FLERR,"lammps_scatter_subset: " - "mismatch property/atom type"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter_subset: " + "mismatch property/atom type"); return; } if (count != 1) { - lmp->error->warning(FLERR,"lammps_scatter_subset: " - "property/atom has count=1"); + if (lmp->comm->me == 0) + lmp->error->warning(FLERR,"lammps_scatter_subset: " + "property/atom has count=1"); return; } if(ltype==0) vptr = (void *) lmp->atom->ivector[fcid]; else vptr = (void *) lmp->atom->dvector[fcid]; - } if(vptr == nullptr) { + if (lmp->comm->me == 0) lmp->error->warning(FLERR,"lammps_scatter_atoms_subset: " "unknown property name"); - return; + return; } // copy = Natom length vector of per-atom values @@ -3971,95 +3691,503 @@ void lammps_scatter_subset(void *ptr, char *name, } } } - } - END_CAPTURE -} #endif - - -/* ---------------------------------------------------------------------- - find fix external with given ID and set the callback function - and caller pointer -------------------------------------------------------------------------- */ - -void lammps_set_fix_external_callback(void *handle, char *id, FixExternalFnPtr callback_ptr, void * caller) -{ - LAMMPS *lmp = (LAMMPS *) handle; - FixExternal::FnPtr callback = (FixExternal::FnPtr) callback_ptr; - - BEGIN_CAPTURE - { - int ifix = lmp->modify->find_fix(id); - if (ifix < 0) { - char str[128]; - snprintf(str, 128, "Can not find fix with ID '%s'!", id); - lmp->error->all(FLERR,str); - } - - Fix *fix = lmp->modify->fix[ifix]; - - if (strcmp("external",fix->style) != 0){ - char str[128]; - snprintf(str, 128, "Fix '%s' is not of style external!", id); - lmp->error->all(FLERR,str); - } - - FixExternal * fext = (FixExternal*) fix; - fext->set_callback(callback, caller); } END_CAPTURE } -/* set global energy contribution from fix external */ -void lammps_fix_external_set_energy_global(void *handle, char *id, - double energy) +/* ---------------------------------------------------------------------- */ + +/** Create N atoms from list of coordinates + * +\verbatim embed:rst + +The prototype for this function when compiling with ``-DLAMMPS_BIGBIG`` +is: + +.. code-block:: c + + int lammps_create_atoms(void *handle, int n, int64_t *id, int *type, double *x, double *v, int64_t *image, int bexpand); + +This function creates additional atoms from a given list of coordinates +and a list of atom types. Additionally the atom-IDs, velocities, and +image flags may be provided. If atom-IDs are not provided, they will be +automatically created as a sequence following the largest existing +atom-ID. + +This function is useful to add atoms to a simulation or - in tandem with +:cpp:func:`lammps_reset_box` - to restore a previously extracted and +saved state of a simulation. Additional properties for the new atoms +can then be assigned via the :cpp:func:`lammps_scatter_atoms` +:cpp:func:`lammps_extract_atom` functions. + +For non-periodic boundaries, atoms will **not** be created that have +coordinates outside the box unless it is a shrink-wrap boundary and the +shrinkexceed flag has been set to a non-zero value. For periodic +boundaries atoms will be wrapped back into the simulation cell and its +image flags adjusted accordingly, unless explicit image flags are +provided. + +The function returns the number of atoms created or -1 on failure, e.g. +when called before as box has been created. + +Coordinates and velocities have to be given in a 1d-array in the order +X(1),Y(1),Z(1),X(2),Y(2),Z(2),...,X(N),Y(N),Z(N). + +\endverbatim + * + * \param handle pointer to a previously created LAMMPS instance + * \param n number of atoms, N, to be added to the system + * \param id pointer to N atom IDs; ``NULL`` will generate IDs + * \param type pointer to N atom types (required) + * \param x pointer to 3N doubles with x-,y-,z- positions + of the new atoms (required) + * \param v pointer to 3N doubles with x-,y-,z- velocities + of the new atoms (set to 0.0 if ``NULL``) + * \param image pointer to N imageint sets of image flags, or ``NULL`` + * \param bexpand if 1, atoms outside of shrink-wrap boundaries will + still be created and not dropped and the box extended + * \return number of atoms created on success; + -1 on failure (no box, no atom IDs, etc.) */ + +int lammps_create_atoms(void *handle, int n, tagint *id, int *type, + double *x, double *v, imageint *image, + int bexpand) { LAMMPS *lmp = (LAMMPS *) handle; + bigint natoms_prev = lmp->atom->natoms; BEGIN_CAPTURE { - int ifix = lmp->modify->find_fix(id); - if (ifix < 0) - lmp->error->all(FLERR,fmt::format("Can not find fix with ID '{}'!", id)); + // error if box does not exist or tags not defined - Fix *fix = lmp->modify->fix[ifix]; + int flag = 0; + std::string msg("Failure in lammps_create_atoms: "); + if (lmp->domain->box_exist == 0) { + flag = 1; + msg += "trying to create atoms before before simulation box is defined"; + } + if (lmp->atom->tag_enable == 0) { + flag = 1; + msg += "must have atom IDs to use this function"; + } - if (strcmp("external",fix->style) != 0) - lmp->error->all(FLERR,fmt::format("Fix '{}' is not of style external!", id)); + if (flag) { + if (lmp->comm->me == 0) lmp->error->warning(FLERR,msg); + return -1; + } - FixExternal * fext = (FixExternal*) fix; - fext->set_energy_global(energy); + // loop over all N atoms on all MPI ranks + // if this proc would own it based on its coordinates, invoke create_atom() + // optionally set atom tags and velocities + + Atom *atom = lmp->atom; + Domain *domain = lmp->domain; + int nlocal = atom->nlocal; + + int nlocal_prev = nlocal; + double xdata[3]; + + for (int i = 0; i < n; i++) { + xdata[0] = x[3*i]; + xdata[1] = x[3*i+1]; + xdata[2] = x[3*i+2]; + imageint * img = image ? image + i : nullptr; + tagint tag = id ? id[i] : 0; + + // create atom only on MPI rank that would own it + + if (!domain->ownatom(tag, xdata, img, bexpand)) continue; + + atom->avec->create_atom(type[i],xdata); + if (id) atom->tag[nlocal] = id[i]; + else atom->tag[nlocal] = 0; + if (v) { + atom->v[nlocal][0] = v[3*i]; + atom->v[nlocal][1] = v[3*i+1]; + atom->v[nlocal][2] = v[3*i+2]; + } + if (image) atom->image[nlocal] = image[i]; + nlocal++; + } + + // if no tags are given explicitly, create new and unique tags + + if (id == nullptr) atom->tag_extend(); + + // reset box info, if extended when adding atoms. + + if (bexpand) domain->reset_box(); + + // need to reset atom->natoms inside LAMMPS + + bigint ncurrent = nlocal; + MPI_Allreduce(&ncurrent,&lmp->atom->natoms,1,MPI_LMP_BIGINT, + MPI_SUM,lmp->world); + + // init per-atom fix/compute/variable values for created atoms + + atom->data_fix_compute_variable(nlocal_prev,nlocal); + + // if global map exists, reset it + // invoke map_init() b/c atom count has grown + + if (lmp->atom->map_style != Atom::MAP_NONE) { + lmp->atom->map_init(); + lmp->atom->map_set(); + } } - END_CAPTURE + END_CAPTURE; + return (int) lmp->atom->natoms - natoms_prev; } -/* set global virial contribution from fix external */ -void lammps_fix_external_set_virial_global(void *handle, char *id, - double *virial) -{ - LAMMPS *lmp = (LAMMPS *) handle; +// ---------------------------------------------------------------------- +// Library functions for accessing neighbor lists +// ---------------------------------------------------------------------- - BEGIN_CAPTURE - { - int ifix = lmp->modify->find_fix(id); - if (ifix < 0) - lmp->error->all(FLERR,fmt::format("Can not find fix with ID '{}'!", id)); +/** Find neighbor list index of pair style neighbor list + * + * Try finding pair instance that matches style. If exact is set, the pair must + * match style exactly. If exact is 0, style must only be contained. If pair is + * of style pair/hybrid, style is instead matched the nsub-th hybrid sub-style. + * + * Once the pair instance has been identified, multiple neighbor list requests + * may be found. Every neighbor list is uniquely identified by its request + * index. Thus, providing this request index ensures that the correct neighbor + * list index is returned. + * + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + * \param style String used to search for pair style instance + * \param exact Flag to control whether style should match exactly or only + * must be contained in pair style name + * \param nsub match nsub-th hybrid sub-style + * \param request request index that specifies which neighbor list should be + * returned, in case there are multiple neighbor lists requests + * for the found pair style + * \return return neighbor list index if found, otherwise -1 */ - Fix *fix = lmp->modify->fix[ifix]; +int lammps_find_pair_neighlist(void* handle, char * style, int exact, int nsub, int request) { + LAMMPS * lmp = (LAMMPS *) handle; + Pair* pair = lmp->force->pair_match(style, exact, nsub); - if (strcmp("external",fix->style) != 0) - lmp->error->all(FLERR,fmt::format("Fix '{}' is not of style external!", id)); + if (pair != nullptr) { + // find neigh list + for (int i = 0; i < lmp->neighbor->nlist; i++) { + NeighList * list = lmp->neighbor->lists[i]; + if (list->requestor_type != NeighList::PAIR || pair != list->requestor) continue; - FixExternal * fext = (FixExternal*) fix; - fext->set_virial_global(virial); + if (list->index == request) { + return i; + } + } } - END_CAPTURE + return -1; +} + +/* ---------------------------------------------------------------------- */ + +/** Find neighbor list index of fix neighbor list + * + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + * \param id Identifier of fix instance + * \param request request index that specifies which request should be returned, + * in case there are multiple neighbor lists for this fix + * \return return neighbor list index if found, otherwise -1 */ + +int lammps_find_fix_neighlist(void* handle, char *id, int request) { + LAMMPS * lmp = (LAMMPS *) handle; + Fix* fix = nullptr; + const int nfix = lmp->modify->nfix; + + // find fix with name + for (int ifix = 0; ifix < nfix; ifix++) { + if (strcmp(lmp->modify->fix[ifix]->id, id) == 0) { + fix = lmp->modify->fix[ifix]; + break; + } + } + + if (fix != nullptr) { + // find neigh list + for (int i = 0; i < lmp->neighbor->nlist; i++) { + NeighList * list = lmp->neighbor->lists[i]; + if (list->requestor_type != NeighList::FIX || fix != list->requestor) continue; + + if (list->index == request) { + return i; + } + } + } + return -1; +} + +/* ---------------------------------------------------------------------- */ + +/** Find neighbor list index of compute neighbor list + * + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + * \param id Identifier of fix instance + * \param request request index that specifies which request should be returned, + * in case there are multiple neighbor lists for this fix + * \return return neighbor list index if found, otherwise -1 */ + +int lammps_find_compute_neighlist(void* handle, char *id, int request) { + LAMMPS * lmp = (LAMMPS *) handle; + Compute* compute = nullptr; + const int ncompute = lmp->modify->ncompute; + + // find compute with name + for (int icompute = 0; icompute < ncompute; icompute++) { + if (strcmp(lmp->modify->compute[icompute]->id, id) == 0) { + compute = lmp->modify->compute[icompute]; + break; + } + } + + if (compute != nullptr) { + // find neigh list + for (int i = 0; i < lmp->neighbor->nlist; i++) { + NeighList * list = lmp->neighbor->lists[i]; + if (list->requestor_type != NeighList::COMPUTE || compute != list->requestor) continue; + + if (list->index == request) { + return i; + } + } + } + return -1; +} + +/* ---------------------------------------------------------------------- */ + +/** Return the number of entries in the neighbor list with given index + * + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + * \param idx neighbor list index + * \return return number of entries in neighbor list, -1 if idx is + * not a valid index + */ +int lammps_neighlist_num_elements(void *handle, int idx) { + LAMMPS * lmp = (LAMMPS *) handle; + Neighbor * neighbor = lmp->neighbor; + + if(idx < 0 || idx >= neighbor->nlist) { + return -1; + } + + NeighList * list = neighbor->lists[idx]; + return list->inum; +} + +/* ---------------------------------------------------------------------- */ + +/** Return atom local index, number of neighbors, and array of neighbor local + * atom indices of neighbor list entry + * + * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. + * \param idx index of this neighbor list in the list of all neighbor lists + * \param element index of this neighbor list entry + * \param[out] iatom local atom index (i.e. in the range [0, nlocal + nghost), -1 if + invalid idx or element value + * \param[out] numneigh number of neighbors of atom iatom or 0 + * \param[out] neighbors pointer to array of neighbor atom local indices or NULL */ + +void lammps_neighlist_element_neighbors(void *handle, int idx, int element, int *iatom, int *numneigh, int **neighbors) { + LAMMPS * lmp = (LAMMPS *) handle; + Neighbor * neighbor = lmp->neighbor; + *iatom = -1; + *numneigh = 0; + *neighbors = nullptr; + + if(idx < 0 || idx >= neighbor->nlist) { + return; + } + + NeighList * list = neighbor->lists[idx]; + + if(element < 0 || element >= list->inum) { + return; + } + + int i = list->ilist[element]; + *iatom = i; + *numneigh = list->numneigh[i]; + *neighbors = list->firstneigh[i]; } // ---------------------------------------------------------------------- // Library functions for accessing LAMMPS configuration // ---------------------------------------------------------------------- +/** Get numerical representation of the LAMMPS version date. + * +\verbatim embed:rst + +The :cpp:func:`lammps_version` function returns an integer representing +the version of the LAMMPS code in the format YYYYMMDD. This can be used +to implement backward compatibility in software using the LAMMPS library +interface. The specific format guarantees, that this version number is +growing with every new LAMMPS release. + +\endverbatim + * + * \param handle pointer to a previously created LAMMPS instance + * \return an integer representing the version data in the + * format YYYYMMDD */ + +int lammps_version(void *handle) +{ + LAMMPS *lmp = (LAMMPS *) handle; + return lmp->num_ver; +} + +/** Get operating system and architecture information + * +\verbatim embed:rst + +The :cpp:func:`lammps_get_os_info` function can be used to retrieve +detailed information about the hosting operating system and +compiler/runtime. +A suitable buffer for a C-style string has to be provided and its length. +If the assembled text will be truncated to not overflow this buffer. + +.. versionadded:: 9Oct2020 + +\endverbatim + * + * \param buffer string buffer to copy the information to + * \param buf_size size of the provided string buffer */ + +/* ---------------------------------------------------------------------- */ + +void lammps_get_os_info(char *buffer, int buf_size) +{ + if (buf_size <=0) return; + buffer[0] = buffer[buf_size-1] = '\0'; + std::string txt = Info::get_os_info() + "\n"; + txt += Info::get_compiler_info(); + txt += " with " + Info::get_openmp_info() + "\n"; + strncpy(buffer, txt.c_str(), buf_size-1); +} + +/* ---------------------------------------------------------------------- */ + +/** This function is used to query whether LAMMPS was compiled with + * a real MPI library or in serial. + * + * \return 0 when compiled with MPI STUBS, otherwise 1 */ + +int lammps_config_has_mpi_support() +{ +#ifdef MPI_STUBS + return 0; +#else + return 1; +#endif +} + +/* ---------------------------------------------------------------------- */ + +/** Check if the LAMMPS library supports compressed files via a pipe to gzip + +\verbatim embed:rst +Several LAMMPS commands (e.g. :doc:`read_data`, :doc:`write_data`, +:doc:`dump styles atom, custom, and xyz `) support reading and +writing compressed files via creating a pipe to the ``gzip`` program. +This function checks whether this feature was :ref:`enabled at compile +time `. It does **not** check whether the ``gzip`` itself is +installed and usable. +\endverbatim + * + * \return 1 if yes, otherwise 0 + */ +int lammps_config_has_gzip_support() { + return Info::has_gzip_support() ? 1 : 0; +} + +/* ---------------------------------------------------------------------- */ + +/** Check if the LAMMPS library supports writing PNG format images + +\verbatim embed:rst +The LAMMPS :doc:`dump style image ` supports writing multiple +image file formats. Most of them need, however, support from an external +library and using that has to be :ref:`enabled at compile time `. +This function checks whether support for the `PNG image file format +`_ is available +in the current LAMMPS library. +\endverbatim + * + * \return 1 if yes, otherwise 0 + */ +int lammps_config_has_png_support() { + return Info::has_png_support() ? 1 : 0; +} + +/* ---------------------------------------------------------------------- */ + +/** Check if the LAMMPS library supports writing JPEG format images + +\verbatim embed:rst +The LAMMPS :doc:`dump style image ` supports writing multiple +image file formats. Most of them need, however, support from an external +library and using that has to be :ref:`enabled at compile time `. +This function checks whether support for the `JPEG image file format +`_ is available in the current LAMMPS library. +\endverbatim + * + * \return 1 if yes, otherwise 0 + */ +int lammps_config_has_jpeg_support() { + return Info::has_jpeg_support() ? 1 : 0; +} + +/* ---------------------------------------------------------------------- */ + +/** Check if the LAMMPS library supports creating movie files via a pipe to ffmpeg + +\verbatim embed:rst +The LAMMPS :doc:`dump style movie ` supports generating movies +from images on-the-fly via creating a pipe to the +`ffmpeg `_ program. +This function checks whether this feature was :ref:`enabled at compile time `. +It does **not** check whether the ``ffmpeg`` itself is installed and usable. +\endverbatim + * + * \return 1 if yes, otherwise 0 + */ +int lammps_config_has_ffmpeg_support() { + return Info::has_ffmpeg_support() ? 1 : 0; +} + +/* ---------------------------------------------------------------------- */ + +/** Check whether LAMMPS errors will throw a C++ exception + * +\verbatim embed:rst +In case of errors LAMMPS will either abort or throw a C++ exception. +The latter has to be :ref:`enabled at compile time `. +This function checks if exceptions were enabled. + +When using the library interface and C++ exceptions are enabled, +the library interface functions will "catch" them and the +error status can then be checked by calling +:cpp:func:`lammps_has_error` and the most recent error message +can be retrieved via :cpp:func:`lammps_get_last_error_message`. +This can allow to restart a calculation or delete and recreate +the LAMMPS instance when C++ exceptions are enabled. One application +of using exceptions this way is the :ref:`lammps_shell`. If C++ +exceptions are disabled and an error happens during a call to +LAMMPS, the application will terminate. +\endverbatim + * \return 1 if yes, otherwise 0 + */ +int lammps_config_has_exceptions() { + return Info::has_exceptions() ? 1 : 0; +} + +/* ---------------------------------------------------------------------- */ + /** Check if a specific package has been included in LAMMPS * \verbatim embed:rst @@ -4371,297 +4499,6 @@ int lammps_id_name(void *handle, const char *category, int idx, return 0; } -/* ---------------------------------------------------------------------- */ - -/** This function is used to query whether LAMMPS was compiled with - * a real MPI library or in serial. - * - * \return 0 when compiled with MPI STUBS, otherwise 1 */ - -int lammps_config_has_mpi_support() -{ -#ifdef MPI_STUBS - return 0; -#else - return 1; -#endif -} - -/* ---------------------------------------------------------------------- */ - -/** Check if the LAMMPS library supports compressed files via a pipe to gzip - -\verbatim embed:rst -Several LAMMPS commands (e.g. :doc:`read_data`, :doc:`write_data`, -:doc:`dump styles atom, custom, and xyz `) support reading and -writing compressed files via creating a pipe to the ``gzip`` program. -This function checks whether this feature was :ref:`enabled at compile -time `. It does **not** check whether the ``gzip`` itself is -installed and usable. -\endverbatim - * - * \return 1 if yes, otherwise 0 - */ -int lammps_config_has_gzip_support() { - return Info::has_gzip_support() ? 1 : 0; -} - -/* ---------------------------------------------------------------------- */ - -/** Check if the LAMMPS library supports writing PNG format images - -\verbatim embed:rst -The LAMMPS :doc:`dump style image ` supports writing multiple -image file formats. Most of them need, however, support from an external -library and using that has to be :ref:`enabled at compile time `. -This function checks whether support for the `PNG image file format -`_ is available -in the current LAMMPS library. -\endverbatim - * - * \return 1 if yes, otherwise 0 - */ -int lammps_config_has_png_support() { - return Info::has_png_support() ? 1 : 0; -} - -/* ---------------------------------------------------------------------- */ - -/** Check if the LAMMPS library supports writing JPEG format images - -\verbatim embed:rst -The LAMMPS :doc:`dump style image ` supports writing multiple -image file formats. Most of them need, however, support from an external -library and using that has to be :ref:`enabled at compile time `. -This function checks whether support for the `JPEG image file format -`_ is available in the current LAMMPS library. -\endverbatim - * - * \return 1 if yes, otherwise 0 - */ -int lammps_config_has_jpeg_support() { - return Info::has_jpeg_support() ? 1 : 0; -} - -/* ---------------------------------------------------------------------- */ - -/** Check if the LAMMPS library supports creating movie files via a pipe to ffmpeg - -\verbatim embed:rst -The LAMMPS :doc:`dump style movie ` supports generating movies -from images on-the-fly via creating a pipe to the -`ffmpeg `_ program. -This function checks whether this feature was :ref:`enabled at compile time `. -It does **not** check whether the ``ffmpeg`` itself is installed and usable. -\endverbatim - * - * \return 1 if yes, otherwise 0 - */ -int lammps_config_has_ffmpeg_support() { - return Info::has_ffmpeg_support() ? 1 : 0; -} - -/* ---------------------------------------------------------------------- */ - -/** Check whether LAMMPS errors will throw a C++ exception - * -\verbatim embed:rst -In case of errors LAMMPS will either abort or throw a C++ exception. -The latter has to be :ref:`enabled at compile time `. -This function checks if exceptions were enabled. - -When using the library interface and C++ exceptions are enabled, -the library interface functions will "catch" them and the -error status can then be checked by calling -:cpp:func:`lammps_has_error` and the most recent error message -can be retrieved via :cpp:func:`lammps_get_last_error_message`. -This can allow to restart a calculation or delete and recreate -the LAMMPS instance when C++ exceptions are enabled. One application -of using exceptions this way is the :ref:`lammps_shell`. If C++ -exceptions are disabled and an error happens during a call to -LAMMPS, the application will terminate. -\endverbatim - * \return 1 if yes, otherwise 0 - */ -int lammps_config_has_exceptions() { - return Info::has_exceptions() ? 1 : 0; -} - -// ---------------------------------------------------------------------- -// Library functions for accessing neighbor lists -// ---------------------------------------------------------------------- - -/** Find neighbor list index of pair style neighbor list - * - * Try finding pair instance that matches style. If exact is set, the pair must - * match style exactly. If exact is 0, style must only be contained. If pair is - * of style pair/hybrid, style is instead matched the nsub-th hybrid sub-style. - * - * Once the pair instance has been identified, multiple neighbor list requests - * may be found. Every neighbor list is uniquely identified by its request - * index. Thus, providing this request index ensures that the correct neighbor - * list index is returned. - * - * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. - * \param style String used to search for pair style instance - * \param exact Flag to control whether style should match exactly or only - * must be contained in pair style name - * \param nsub match nsub-th hybrid sub-style - * \param request request index that specifies which neighbor list should be - * returned, in case there are multiple neighbor lists requests - * for the found pair style - * \return return neighbor list index if found, otherwise -1 - */ -int lammps_find_pair_neighlist(void* handle, char * style, int exact, int nsub, int request) { - LAMMPS * lmp = (LAMMPS *) handle; - Pair* pair = lmp->force->pair_match(style, exact, nsub); - - if (pair != nullptr) { - // find neigh list - for (int i = 0; i < lmp->neighbor->nlist; i++) { - NeighList * list = lmp->neighbor->lists[i]; - if (list->requestor_type != NeighList::PAIR || pair != list->requestor) continue; - - if (list->index == request) { - return i; - } - } - } - return -1; -} - -/* ---------------------------------------------------------------------- */ - -/** Find neighbor list index of fix neighbor list - * - * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. - * \param id Identifier of fix instance - * \param request request index that specifies which request should be returned, - * in case there are multiple neighbor lists for this fix - * \return return neighbor list index if found, otherwise -1 - */ -int lammps_find_fix_neighlist(void* handle, char * id, int request) { - LAMMPS * lmp = (LAMMPS *) handle; - Fix* fix = nullptr; - const int nfix = lmp->modify->nfix; - - // find fix with name - for (int ifix = 0; ifix < nfix; ifix++) { - if (strcmp(lmp->modify->fix[ifix]->id, id) == 0) { - fix = lmp->modify->fix[ifix]; - break; - } - } - - if (fix != nullptr) { - // find neigh list - for (int i = 0; i < lmp->neighbor->nlist; i++) { - NeighList * list = lmp->neighbor->lists[i]; - if (list->requestor_type != NeighList::FIX || fix != list->requestor) continue; - - if (list->index == request) { - return i; - } - } - } - return -1; -} - -/* ---------------------------------------------------------------------- */ - -/** Find neighbor list index of compute neighbor list - * - * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. - * \param id Identifier of fix instance - * \param request request index that specifies which request should be returned, - * in case there are multiple neighbor lists for this fix - * \return return neighbor list index if found, otherwise -1 - */ -int lammps_find_compute_neighlist(void* handle, char * id, int request) { - LAMMPS * lmp = (LAMMPS *) handle; - Compute* compute = nullptr; - const int ncompute = lmp->modify->ncompute; - - // find compute with name - for (int icompute = 0; icompute < ncompute; icompute++) { - if (strcmp(lmp->modify->compute[icompute]->id, id) == 0) { - compute = lmp->modify->compute[icompute]; - break; - } - } - - if (compute != nullptr) { - // find neigh list - for (int i = 0; i < lmp->neighbor->nlist; i++) { - NeighList * list = lmp->neighbor->lists[i]; - if (list->requestor_type != NeighList::COMPUTE || compute != list->requestor) continue; - - if (list->index == request) { - return i; - } - } - } - return -1; -} - -/* ---------------------------------------------------------------------- */ - -/** Return the number of entries in the neighbor list with given index - * - * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. - * \param idx neighbor list index - * \return return number of entries in neighbor list, -1 if idx is - * not a valid index - */ -int lammps_neighlist_num_elements(void * handle, int idx) { - LAMMPS * lmp = (LAMMPS *) handle; - Neighbor * neighbor = lmp->neighbor; - - if(idx < 0 || idx >= neighbor->nlist) { - return -1; - } - - NeighList * list = neighbor->lists[idx]; - return list->inum; -} - -/* ---------------------------------------------------------------------- */ - -/** Return atom local index, number of neighbors, and array of neighbor local - * atom indices of neighbor list entry - * - * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. - * \param idx index of this neighbor list in the list of all neighbor lists - * \param element index of this neighbor list entry - * \param[out] iatom local atom index (i.e. in the range [0, nlocal + nghost), -1 if - invalid idx or element value - * \param[out] numneigh number of neighbors of atom iatom or 0 - * \param[out] neighbors pointer to array of neighbor atom local indices or - * NULL - */ -void lammps_neighlist_element_neighbors(void * handle, int idx, int element, int * iatom, int * numneigh, int ** neighbors) { - LAMMPS * lmp = (LAMMPS *) handle; - Neighbor * neighbor = lmp->neighbor; - *iatom = -1; - *numneigh = 0; - *neighbors = nullptr; - - if(idx < 0 || idx >= neighbor->nlist) { - return; - } - - NeighList * list = neighbor->lists[idx]; - - if(element < 0 || element >= list->inum) { - return; - } - - int i = list->ilist[element]; - *iatom = i; - *numneigh = list->numneigh[i]; - *neighbors = list->firstneigh[i]; -} - // ---------------------------------------------------------------------- // utility functions // ---------------------------------------------------------------------- @@ -4733,6 +4570,107 @@ void lammps_decode_image_flags(imageint image, int *flags) flags[2] = (image >> IMG2BITS) - IMGMAX; } +/* ---------------------------------------------------------------------- + find fix external with given ID and set the callback function + and caller pointer +------------------------------------------------------------------------- */ + +void lammps_set_fix_external_callback(void *handle, char *id, FixExternalFnPtr callback_ptr, void * caller) +{ + LAMMPS *lmp = (LAMMPS *) handle; + FixExternal::FnPtr callback = (FixExternal::FnPtr) callback_ptr; + + BEGIN_CAPTURE + { + int ifix = lmp->modify->find_fix(id); + if (ifix < 0) { + char str[128]; + snprintf(str, 128, "Can not find fix with ID '%s'!", id); + lmp->error->all(FLERR,str); + } + + Fix *fix = lmp->modify->fix[ifix]; + + if (strcmp("external",fix->style) != 0){ + char str[128]; + snprintf(str, 128, "Fix '%s' is not of style external!", id); + lmp->error->all(FLERR,str); + } + + FixExternal * fext = (FixExternal*) fix; + fext->set_callback(callback, caller); + } + END_CAPTURE +} + +/* set global energy contribution from fix external */ +void lammps_fix_external_set_energy_global(void *handle, char *id, + double energy) +{ + LAMMPS *lmp = (LAMMPS *) handle; + + BEGIN_CAPTURE + { + int ifix = lmp->modify->find_fix(id); + if (ifix < 0) + lmp->error->all(FLERR,fmt::format("Can not find fix with ID '{}'!", id)); + + Fix *fix = lmp->modify->fix[ifix]; + + if (strcmp("external",fix->style) != 0) + lmp->error->all(FLERR,fmt::format("Fix '{}' is not of style external!", id)); + + FixExternal * fext = (FixExternal*) fix; + fext->set_energy_global(energy); + } + END_CAPTURE +} + +/* set global virial contribution from fix external */ +void lammps_fix_external_set_virial_global(void *handle, char *id, + double *virial) +{ + LAMMPS *lmp = (LAMMPS *) handle; + + BEGIN_CAPTURE + { + int ifix = lmp->modify->find_fix(id); + if (ifix < 0) + lmp->error->all(FLERR,fmt::format("Can not find fix with ID '{}'!", id)); + + Fix *fix = lmp->modify->fix[ifix]; + + if (strcmp("external",fix->style) != 0) + lmp->error->all(FLERR,fmt::format("Fix '{}' is not of style external!", id)); + + FixExternal * fext = (FixExternal*) fix; + fext->set_virial_global(virial); + } + END_CAPTURE +} + +/* ---------------------------------------------------------------------- */ + +/** Free memory buffer allocated by LAMMPS. + * +\verbatim embed:rst + +Some of the LAMMPS C library interface functions return data as pointer +to a buffer that has been allocated by LAMMPS or the library interface. +This function can be used to delete those in order to avoid memory +leaks. + +\endverbatim + * + * \param ptr pointer to data allocated by LAMMPS */ + +void lammps_free(void *ptr) +{ + free(ptr); +} + +/* ---------------------------------------------------------------------- */ + /** Check if LAMMPS is currently inside a run or minimization * * This function can be used from signal handlers or multi-threaded @@ -4819,8 +4757,8 @@ the failing MPI ranks to send messages. * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. * \param buffer string buffer to copy the error message to * \param buf_size size of the provided string buffer - * \return 1 when all ranks had the error, 2 on a single rank error. - */ + * \return 1 when all ranks had the error, 2 on a single rank error. */ + int lammps_get_last_error_message(void *handle, char *buffer, int buf_size) { #ifdef LAMMPS_EXCEPTIONS LAMMPS *lmp = (LAMMPS *) handle; diff --git a/src/library.h b/src/library.h index 36b07a4fe5..a38ea2dc82 100644 --- a/src/library.h +++ b/src/library.h @@ -93,9 +93,9 @@ void *lammps_open(int argc, char **argv, MPI_Comm comm, void **ptr); void *lammps_open_no_mpi(int argc, char **argv, void **ptr); void *lammps_open_fortran(int argc, char **argv, int f_comm); void lammps_close(void *handle); + void lammps_mpi_init(); void lammps_mpi_finalize(); -void lammps_free(void *ptr); /* ---------------------------------------------------------------------- * Library functions to process commands @@ -111,33 +111,28 @@ void lammps_commands_string(void *handle, const char *str); * Library functions to extract info from LAMMPS or set data in LAMMPS * ----------------------------------------------------------------------- */ -int lammps_version(void *handle); -void lammps_get_os_info(char *buffer, int buf_size); -void lammps_memory_usage(void *handle, double *meminfo); -int lammps_get_mpi_comm(void *handle); double lammps_get_natoms(void *handle); double lammps_get_thermo(void *handle, const char *keyword); -void lammps_extract_box(void *handle, double *boxlo, double *boxhi, - double *xy, double *yz, double *xz, - int *pflags, int *boxflag); -void lammps_reset_box(void *handle, double *boxlo, double *boxhi, - double xy, double yz, double xz); +void lammps_extract_box(void *handle, double *boxlo, double *boxhi, + double *xy, double *yz, double *xz, + int *pflags, int *boxflag); +void lammps_reset_box(void *handle, double *boxlo, double *boxhi, + double xy, double yz, double xz); -int lammps_extract_setting(void *handle, const char *keyword); -void *lammps_extract_global(void *handle, const char *name); -void *lammps_extract_atom(void *handle, const char *name); +void lammps_memory_usage(void *handle, double *meminfo); +int lammps_get_mpi_comm(void *handle); + +int lammps_extract_setting(void *handle, const char *keyword); +int lammps_extract_global_datatype(void *handle, const char *name); +void *lammps_extract_global(void *handle, const char *name); + +/* ---------------------------------------------------------------------- + * Library functions to read or modify per-atom data in LAMMPS + * ---------------------------------------------------------------------- */ -int lammps_extract_global_datatype(void *handle, const char *name); int lammps_extract_atom_datatype(void *handle, const char *name); - -#if !defined(LAMMPS_BIGBIG) -int lammps_create_atoms(void *handle, int n, int *id, int *type, - double *x, double *v, int *image, int bexpand); -#else -int lammps_create_atoms(void *handle, int n, int64_t *id, int *type, - double *x, double *v, int64_t* image, int bexpand); -#endif +void *lammps_extract_atom(void *handle, const char *name); /* ---------------------------------------------------------------------- * Library functions to access data from computes, fixes, variables in LAMMPS @@ -152,34 +147,54 @@ int lammps_set_variable(void *, char *, char *); * Library functions for scatter/gather operations of data * ---------------------------------------------------------------------- */ +void lammps_gather_atoms(void *handle, char *name, int type, int count, void *data); +void lammps_gather_atoms_concat(void *handle, char *name, int type, int count, void *data); +void lammps_gather_atoms_subset(void *handle, char *name, int type, int count, int ndata, int *ids, void *data); +void lammps_scatter_atoms(void *handle, char *name, int type, int count, void *data); +void lammps_scatter_atoms_subset(void *handle, char *name, int type, int count, int ndata, int *ids, void *data); -void lammps_gather(void *, char *, int, int, void *); -void lammps_gather_concat(void *, char *, int, int, void *); -void lammps_gather_subset(void *, char *, int, int, int, int *, void *); -void lammps_scatter(void *, char *, int, int, void *); -void lammps_scatter_subset(void *, char *, int, int, int, int *, void *); +void lammps_gather(void *handle, char *name, int type, int count, void *data); +void lammps_gather_concat(void *handle, char *name, int type, int count, void *data); +void lammps_gather_subset(void *handle, char *name, int type, int count, int ndata, int *ids, void *data); +void lammps_scatter(void *handle, char *name, int type, int count, void *data); +void lammps_scatter_subset(void *handle, char *name, int type, int count, int ndata, int *ids, void *data); +#if !defined(LAMMPS_BIGBIG) +int lammps_create_atoms(void *handle, int n, int *id, int *type, + double *x, double *v, int *image, int bexpand); +#else +int lammps_create_atoms(void *handle, int n, int64_t *id, int *type, + double *x, double *v, int64_t* image, int bexpand); +#endif -void lammps_gather_atoms(void *, char *, int, int, void *); -void lammps_gather_atoms_concat(void *, char *, int, int, void *); -void lammps_gather_atoms_subset(void *, char *, int, int, int, int *, void *); -void lammps_scatter_atoms(void *, char *, int, int, void *); -void lammps_scatter_atoms_subset(void *, char *, int, int, int, int *, void *); +/* ---------------------------------------------------------------------- + * Library functions for accessing neighbor lists + * ---------------------------------------------------------------------- */ + +int lammps_find_pair_neighlist(void *handle, char *style, int exact, int nsub, int request); +int lammps_find_fix_neighlist(void *handle, char *id, int request); +int lammps_find_compute_neighlist(void *handle, char *id, int request); +int lammps_neighlist_num_elements(void *handle, int idx); +void lammps_neighlist_element_neighbors(void *handle, int idx, int element, int *iatom, int *numneigh, int **neighbors); /* ---------------------------------------------------------------------- * Library functions for retrieving configuration information * ---------------------------------------------------------------------- */ +int lammps_version(void *handle); +void lammps_get_os_info(char *buffer, int buf_size); + int lammps_config_has_mpi_support(); -int lammps_config_has_package(const char *); -int lammps_config_package_count(); -int lammps_config_package_name(int, char *, int); int lammps_config_has_gzip_support(); int lammps_config_has_png_support(); int lammps_config_has_jpeg_support(); int lammps_config_has_ffmpeg_support(); int lammps_config_has_exceptions(); +int lammps_config_has_package(const char *); +int lammps_config_package_count(); +int lammps_config_package_name(int, char *, int); + int lammps_has_style(void *, const char *, const char *); int lammps_style_count(void *, const char *); int lammps_style_name(void *, const char *, int, char *, int); @@ -188,16 +203,6 @@ int lammps_has_id(void *, const char *, const char *); int lammps_id_count(void *, const char *); int lammps_id_name(void *, const char *, int, char *, int); -/* ---------------------------------------------------------------------- - * Library functions for accessing neighbor lists - * ---------------------------------------------------------------------- */ - -int lammps_find_pair_neighlist(void*, char *, int, int, int); -int lammps_find_fix_neighlist(void*, char *, int); -int lammps_find_compute_neighlist(void*, char *, int); -int lammps_neighlist_num_elements(void*, int); -void lammps_neighlist_element_neighbors(void *, int, int, int *, int *, int ** ); - /* ---------------------------------------------------------------------- * Utility functions * ---------------------------------------------------------------------- */ @@ -223,7 +228,9 @@ void lammps_set_fix_external_callback(void *, char *, FixExternalFnPtr, void*); void lammps_fix_external_set_energy_global(void *, char *, double); void lammps_fix_external_set_virial_global(void *, char *, double *); -int lammps_is_running(void *handle); +void lammps_free(void *ptr); + +int lammps_is_running(void *handle); void lammps_force_timeout(void *handle); int lammps_has_error(void *handle); diff --git a/tools/swig/CMakeLists.txt b/tools/swig/CMakeLists.txt index 8497450388..204b351ed6 100644 --- a/tools/swig/CMakeLists.txt +++ b/tools/swig/CMakeLists.txt @@ -43,6 +43,7 @@ if(BUILD_SWIG_JAVA) set_property(SOURCE lammps.i PROPERTY SWIG_MODULE_NAME javalammps) swig_add_library(javalammps TYPE MODULE LANGUAGE java SOURCES lammps.i) find_package(JNI REQUIRED) + find_package(Java COMPONENTS Development REQUIRED) target_include_directories(javalammps PRIVATE ${JNI_INCLUDE_DIRS}) swig_link_libraries(javalammps PRIVATE lammps ${JNI_LIBRARIES}) configure_file(run_java_example.sh.in run_java_example.sh @ONLY) diff --git a/unittest/tools/test_lammps_shell.py b/unittest/tools/test_lammps_shell.py index 36c375fa59..afbbca033b 100644 --- a/unittest/tools/test_lammps_shell.py +++ b/unittest/tools/test_lammps_shell.py @@ -5,6 +5,7 @@ import os, re, subprocess, unittest os.putenv('LAMMPS_SHELL_TESTING','1') shell_prompt_re = r"([^>]*LAMMPS Shell> ([a-z0-9_]+) *([a-z0-9_\.]+)?.*\n)+" +cmd_group_re = r"([^>]*LAMMPS Shell> ([a-z0-9_]+) +([a-z0-9]+) +([a-z0-9]+)? *([a-z/0-9]+)?.*\n)+" # class LammpsShell(unittest.TestCase): @@ -28,10 +29,61 @@ class LammpsShell(unittest.TestCase): return outs.decode('UTF-8') - def testExpandClear(self): + def testExpandClearHistory(self): """Test expansion of a shell specific command""" - matches = re.findall(shell_prompt_re, self.InputRunner(b'cle\t\n'), re.MULTILINE) - self.assertEqual(matches[0][1],"clear") + matches = re.findall(shell_prompt_re, self.InputRunner(b'clear_his\t\n'), re.MULTILINE) + self.assertEqual(matches[0][1],"clear_history") + + def testExpandDimension(self): + """Test expansion of a LAMMPS command""" + matches = re.findall(shell_prompt_re, self.InputRunner(b'dimens\t\n'), re.MULTILINE) + self.assertEqual(matches[0][1],"dimension") + + def testExpandPairStyle(self): + """Test expansion of a pair style""" + matches = re.findall(shell_prompt_re, self.InputRunner(b'pair_st\t zer\t\n'), re.MULTILINE) + self.assertEqual(matches[0][1],"pair_style") + self.assertEqual(matches[0][2],"zero") + + def testExpandBondStyle(self): + """Test expansion of a bond style""" + matches = re.findall(shell_prompt_re, self.InputRunner(b'bond_st\t zer\t\n'), re.MULTILINE) + self.assertEqual(matches[0][1],"bond_style") + self.assertEqual(matches[0][2],"zero") + + def testExpandAngleStyle(self): + """Test expansion of a angle style""" + matches = re.findall(shell_prompt_re, self.InputRunner(b'angle_st\t zer\t\n'), re.MULTILINE) + self.assertEqual(matches[0][1],"angle_style") + self.assertEqual(matches[0][2],"zero") + + def testExpandDihedralStyle(self): + """Test expansion of a dihedral style""" + matches = re.findall(shell_prompt_re, self.InputRunner(b'dihedral_st\t zer\t\n'), re.MULTILINE) + self.assertEqual(matches[0][1],"dihedral_style") + self.assertEqual(matches[0][2],"zero") + + def testExpandImproperStyle(self): + """Test expansion of a improper style""" + matches = re.findall(shell_prompt_re, self.InputRunner(b'improper_st\t zer\t\n'), re.MULTILINE) + self.assertEqual(matches[0][1],"improper_style") + self.assertEqual(matches[0][2],"zero") + + def testExpandComputeGroup(self): + """Test expansion of a group-ID and a compute command""" + matches = re.findall(cmd_group_re, self.InputRunner(b'compute test al\tcentro/at\t\n'), re.MULTILINE) + self.assertEqual(matches[0][1],"compute") + self.assertEqual(matches[0][2],"test") + self.assertEqual(matches[0][3],"all") + self.assertEqual(matches[0][4],"centro/atom") + + def testExpandFixGroup(self): + """Test expansion of a group-ID and a fix command""" + matches = re.findall(cmd_group_re, self.InputRunner(b'fix test al\tcontroll\t\n'), re.MULTILINE) + self.assertEqual(matches[0][1],"fix") + self.assertEqual(matches[0][2],"test") + self.assertEqual(matches[0][3],"all") + self.assertEqual(matches[0][4],"controller") def testExpandSource(self): """Test expansion of a shell command and a file name"""