diff --git a/src/atom.cpp b/src/atom.cpp index 49e95007cc..2ea85dd33b 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -1584,13 +1584,11 @@ void Atom::update_callback(int ifix) /* ---------------------------------------------------------------------- return a pointer to a named internal variable if don't recognize name, return NULL + customize by adding names ------------------------------------------------------------------------- */ void *Atom::extract(char *name) { - if (strcmp(name,"natoms") == 0) return (void *) &natoms; - if (strcmp(name,"nlocal") == 0) return (void *) &nlocal; - if (strcmp(name,"id") == 0) return (void *) tag; if (strcmp(name,"type") == 0) return (void *) type; if (strcmp(name,"x") == 0) return (void *) x; diff --git a/src/compute.h b/src/compute.h index 1c604e4060..f13f2fa9ad 100644 --- a/src/compute.h +++ b/src/compute.h @@ -107,7 +107,6 @@ class Compute : protected Pointers { int matchstep(int); void clearstep(); - virtual void *extract(char *) {return NULL;} virtual double memory_usage() {return 0.0;} protected: diff --git a/src/fix.h b/src/fix.h index 2cad07328d..52cb2eda46 100644 --- a/src/fix.h +++ b/src/fix.h @@ -149,7 +149,6 @@ class Fix : protected Pointers { virtual int modify_param(int, char **) {return 0;} - virtual void *extract(char *) {return NULL;} virtual double memory_usage() {return 0.0;} protected: diff --git a/src/library.cpp b/src/library.cpp index 59b92f4a7f..8fc5c92c3b 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -12,17 +12,23 @@ ------------------------------------------------------------------------- */ // C or Fortran style library interface to LAMMPS -// new LAMMPS-specific functions can be added +// customize by adding new LAMMPS-specific functions #include "mpi.h" #include "string.h" +#include "stdlib.h" #include "library.h" #include "lammps.h" #include "input.h" #include "atom.h" -#include "update.h" #include "domain.h" +#include "update.h" +#include "group.h" +#include "input.h" +#include "variable.h" #include "modify.h" +#include "compute.h" +#include "fix.h" using namespace LAMMPS_NS; @@ -70,35 +76,236 @@ char *lammps_command(void *ptr, char *str) /* ---------------------------------------------------------------------- add LAMMPS-specific library functions all must receive LAMMPS pointer as argument + customize by adding a function here and in library.h header file ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - extract a pointer to an internal LAMMPS value or data structure - category: 0 = general, 1 = atom, 2 = fix, 3 = compute - id = ID of fix or compute (else not used, just pass NULL) - name = desired quantity, e.g. x or dt - returns a void pointer which the caller can cast to the desired data type - returns a NULL if LAMMPS does not recognize the name + extract a pointer to an internal LAMMPS global entity + name = desired quantity, e.g. dt or boxyhi or natoms + returns a void pointer to the entity + which the caller can cast to the proper data type + returns a NULL if name not listed below + customize by adding names ------------------------------------------------------------------------- */ -void *lammps_extract(void *ptr, int category, char *id, char *name) +void *lammps_extract_global(void *ptr, char *name) { LAMMPS *lmp = (LAMMPS *) ptr; - if (category == 0) { - if (strcmp(name,"dt") == 0) return (void *) &lmp->update->dt; - if (strcmp(name,"boxxlo") == 0) return (void *) &lmp->domain->boxlo[0]; - if (strcmp(name,"boxxhi") == 0) return (void *) &lmp->domain->boxhi[0]; - if (strcmp(name,"boxylo") == 0) return (void *) &lmp->domain->boxlo[1]; - if (strcmp(name,"boxyhi") == 0) return (void *) &lmp->domain->boxhi[1]; - if (strcmp(name,"boxzlo") == 0) return (void *) &lmp->domain->boxlo[2]; - if (strcmp(name,"boxzhi") == 0) return (void *) &lmp->domain->boxhi[2]; - return NULL; + if (strcmp(name,"dt") == 0) return (void *) &lmp->update->dt; + if (strcmp(name,"boxxlo") == 0) return (void *) &lmp->domain->boxlo[0]; + if (strcmp(name,"boxxhi") == 0) return (void *) &lmp->domain->boxhi[0]; + if (strcmp(name,"boxylo") == 0) return (void *) &lmp->domain->boxlo[1]; + if (strcmp(name,"boxyhi") == 0) return (void *) &lmp->domain->boxhi[1]; + if (strcmp(name,"boxzlo") == 0) return (void *) &lmp->domain->boxlo[2]; + if (strcmp(name,"boxzhi") == 0) return (void *) &lmp->domain->boxhi[2]; + if (strcmp(name,"natoms") == 0) return (void *) &lmp->atom->natoms; + if (strcmp(name,"nlocal") == 0) return (void *) &lmp->atom->nlocal; + return NULL; +} + +/* ---------------------------------------------------------------------- + extract a pointer to an internal LAMMPS atom-based entity + name = desired quantity, e.g. x or mass + returns a void pointer to the entity + which the caller can cast to the proper data type + returns a NULL if Atom::extract() does not recognize the name + customize by adding names to Atom::extract() +------------------------------------------------------------------------- */ + +void *lammps_extract_atom(void *ptr, char *name) +{ + LAMMPS *lmp = (LAMMPS *) ptr; + return lmp->atom->extract(name); +} + +/* ---------------------------------------------------------------------- + extract a pointer to an internal LAMMPS compute-based entity + id = compute ID + style = 0 for global data, 1 for per-atom data, 2 for local data + type = 0 for scalar, 1 for vector, 2 for array + returns a void pointer to the compute's internal data structure + for the entity which the caller can cast to the proper data type + returns a NULL if id is not recognized or style/type not supported + IMPORTANT: if the compute is not current it will be invoked + LAMMPS cannot easily check if it is valid to invoke the compute, + so caller must insure that it is OK +------------------------------------------------------------------------- */ + +void *lammps_extract_compute(void *ptr, char *id, int style, int type) +{ + LAMMPS *lmp = (LAMMPS *) ptr; + + int icompute = lmp->modify->find_compute(id); + if (icompute < 0) return NULL; + Compute *compute = lmp->modify->compute[icompute]; + + if (style == 0) { + if (type == 0) { + if (!compute->scalar_flag) return NULL; + if (compute->invoked_scalar != lmp->update->ntimestep) + compute->compute_scalar(); + return (void *) &compute->scalar; + } + if (type == 1) { + if (!compute->vector_flag) return NULL; + if (compute->invoked_vector != lmp->update->ntimestep) + compute->compute_vector(); + return (void *) compute->vector; + } + if (type == 2) { + if (!compute->array_flag) return NULL; + if (compute->invoked_array != lmp->update->ntimestep) + compute->compute_array(); + return (void *) compute->array; + } } - if (category == 1) return lmp->atom->extract(name); - if (category == 2) return lmp->modify->extract_fix(id,name); - if (category == 3) return lmp->modify->extract_compute(id,name); + if (style == 1) { + if (!compute->peratom_flag) return NULL; + if (type == 1) { + if (compute->invoked_peratom != lmp->update->ntimestep) + compute->compute_peratom(); + return (void *) compute->vector_atom; + } + if (type == 2) { + if (compute->invoked_peratom != lmp->update->ntimestep) + compute->compute_peratom(); + return (void *) compute->array_atom; + } + } + + if (style == 2) { + if (!compute->local_flag) return NULL; + if (type == 1) { + if (compute->invoked_local != lmp->update->ntimestep) + compute->compute_local(); + return (void *) compute->vector_local; + } + if (type == 2) { + if (compute->invoked_local != lmp->update->ntimestep) + compute->compute_local(); + return (void *) compute->array_local; + } + } + + return NULL; +} + +/* ---------------------------------------------------------------------- + extract a pointer to an internal LAMMPS fix-based entity + id = fix ID + style = 0 for global data, 1 for per-atom data, 2 for local data + type = 0 for scalar, 1 for vector, 2 for array + i,j = indices needed only to specify which global vector or array value + for global data, returns a pointer to a memory location + which is allocated by this function + which the caller can cast to a (double *) which points to the value + for per-atom or local data, returns a pointer to the + fix's internal data structure for the entity + which the caller can cast to the proper data type + returns a NULL if id is not recognized or style/type not supported + IMPORTANT: for global data, + this function allocates a double to store the value in, + so the caller must free this memory to avoid a leak, e.g. + double *dptr = (double *) lammps_extract_fix(); + double value = *dptr; + free(dptr); + IMPORTANT: LAMMPS cannot easily check when info extracted from + the fix is valid, so caller must insure that it is OK +------------------------------------------------------------------------- */ + +void *lammps_extract_fix(void *ptr, char *id, int style, int type, + int i, int j) +{ + LAMMPS *lmp = (LAMMPS *) ptr; + + int ifix = lmp->modify->find_fix(id); + if (ifix < 0) return NULL; + Fix *fix = lmp->modify->fix[ifix]; + + if (style == 0) { + double *dptr = (double *) malloc(sizeof(double)); + if (type == 0) { + if (!fix->scalar_flag) return NULL; + *dptr = fix->compute_scalar(); + return (void *) dptr; + } + if (type == 1) { + if (!fix->vector_flag) return NULL; + *dptr = fix->compute_vector(i); + return (void *) dptr; + } + if (type == 2) { + if (!fix->array_flag) return NULL; + *dptr = fix->compute_array(i,j); + return (void *) dptr; + } + } + + if (style == 1) { + if (!fix->peratom_flag) return NULL; + if (type == 1) return (void *) fix->vector_atom; + if (type == 2) return (void *) fix->array_atom; + } + + if (style == 2) { + if (!fix->local_flag) return NULL; + if (type == 1) return (void *) fix->vector_local; + if (type == 2) return (void *) fix->array_local; + } + + return NULL; +} + +/* ---------------------------------------------------------------------- + extract a pointer to an internal LAMMPS evaluated variable + name = variable name, must be equal-style or atom-style variable + group = group ID for evaluating an atom-style variable, else NULL + for equal-style variable, returns a pointer to a memory location + which is allocated by this function + which the caller can cast to a (double *) which points to the value + for atom-style variable, returns a pointer to the + vector of per-atom values on each processor, + which the caller can cast to the proper data type + returns a NULL if name is not recognized or not equal-style or atom-style + IMPORTANT: for both equal-style and atom-style variables, + this function allocates memory to store the variable data in + so the caller must free this memory to avoid a leak + e.g. for equal-style variables + double *dptr = (double *) lammps_extract_variable(); + double value = *dptr; + free(dptr); + e.g. for atom-style variables + double *vector = (double *) lammps_extract_variable(); + use the vector values + free(vector); + IMPORTANT: LAMMPS cannot easily check when it is valid to evaluate + the variable or any fixes or computes or thermodynamic info it references, + so caller must insure that it is OK +------------------------------------------------------------------------- */ + +void *lammps_extract_variable(void *ptr, char *name, char *group) +{ + LAMMPS *lmp = (LAMMPS *) ptr; + + int ivar = lmp->input->variable->find(name); + if (ivar < 0) return NULL; + + if (lmp->input->variable->equalstyle(ivar)) { + double *dptr = (double *) malloc(sizeof(double)); + *dptr = lmp->input->variable->compute_equal(ivar); + return (void *) dptr; + } + + if (lmp->input->variable->atomstyle(ivar)) { + int igroup = lmp->group->find(group); + if (igroup < 0) return NULL; + int nlocal = lmp->atom->nlocal; + double *vector = (double *) malloc(nlocal*sizeof(double)); + lmp->input->variable->compute_atom(ivar,igroup,vector,1,0); + return (void *) vector; + } return NULL; } diff --git a/src/library.h b/src/library.h index 9c21d7a1d2..50237ee73d 100644 --- a/src/library.h +++ b/src/library.h @@ -29,7 +29,12 @@ void lammps_close(void *); void lammps_file(void *, char *); char *lammps_command(void *, char *); -void *lammps_extract(void *, int, char *, char *); +void *lammps_extract_global(void *, char *); +void *lammps_extract_atom(void *, char *); +void *lammps_extract_compute(void *, char *, int, int); +void *lammps_extract_fix(void *, int, int, int, int); +void *lammps_extract_variable(void *, char *, char *); + int lammps_get_natoms(void *); void lammps_get_coords(void *, double *); void lammps_put_coords(void *, double *); @@ -37,4 +42,3 @@ void lammps_put_coords(void *, double *); #ifdef __cplusplus } #endif - diff --git a/src/modify.cpp b/src/modify.cpp index 427172bf5c..3687296de5 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -1062,42 +1062,6 @@ void Modify::list_init_compute() if (compute[i]->timeflag) list_timeflag[n_timeflag++] = i; } -/* ---------------------------------------------------------------------- - return a pointer to a named internal variable owned by fix ID - if don't recognize ID, return NULL -------------------------------------------------------------------------- */ - -void *Modify::extract_fix(char *id, char *name) -{ - int ifix = find_fix(id); - if (ifix < 0) return NULL; - - if (strcmp(name,"index") == 0) { - index_permanent = ifix; - return (void *) &index_permanent; - } - - return fix[ifix]->extract(name); -} - -/* ---------------------------------------------------------------------- - return a pointer to a named internal variable owned by compute ID - if don't recognize ID, return NULL -------------------------------------------------------------------------- */ - -void *Modify::extract_compute(char *id, char *name) -{ - int icompute = find_compute(id); - if (icompute < 0) return NULL; - - if (strcmp(name,"index") == 0) { - index_permanent = icompute; - return (void *) &index_permanent; - } - - return compute[icompute]->extract(name); -} - /* ---------------------------------------------------------------------- return # of bytes of allocated memory from all fixes ------------------------------------------------------------------------- */ diff --git a/src/modify.h b/src/modify.h index ab1421dde4..eec71ab9b6 100644 --- a/src/modify.h +++ b/src/modify.h @@ -91,9 +91,6 @@ class Modify : protected Pointers { int read_restart(FILE *); void restart_deallocate(); - void *extract_fix(char *, char *); - void *extract_compute(char *, char *); - double memory_usage(); private: