From fa8c7b68fc421a2cf0dfbd943755057691add75b Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 4 Jan 2013 17:15:32 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@9222 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/fix_external.cpp | 123 +++++++++++++++++++++++++++++++++++-------- src/fix_external.h | 7 +++ 2 files changed, 109 insertions(+), 21 deletions(-) diff --git a/src/fix_external.cpp b/src/fix_external.cpp index 0e787d078d..b973d5dca3 100644 --- a/src/fix_external.cpp +++ b/src/fix_external.cpp @@ -13,6 +13,7 @@ #include "stdio.h" #include "string.h" +#include "stdlib.h" #include "fix_external.h" #include "atom.h" #include "update.h" @@ -22,23 +23,47 @@ using namespace LAMMPS_NS; using namespace FixConst; +enum{PF_CALLBACK,PF_ARRAY}; + /* ---------------------------------------------------------------------- */ FixExternal::FixExternal(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - if (narg != 3) error->all(FLERR,"Illegal fix external command"); + if (narg < 4) error->all(FLERR,"Illegal fix external command"); + + if (strcmp(arg[3],"pf/callback") == 0) { + if (narg != 6) error->all(FLERR,"Illegal fix external command"); + mode = PF_CALLBACK; + ncall = atoi(arg[4]); + napply = atoi(arg[5]); + if (ncall <= 0 || napply <= 0) + error->all(FLERR,"Illegal fix external command"); + } else if (strcmp(arg[3],"pf/array") == 0) { + if (narg != 5) error->all(FLERR,"Illegal fix external command"); + mode = PF_ARRAY; + napply = atoi(arg[4]); + if (napply <= 0) error->all(FLERR,"Illegal fix external command"); + } else error->all(FLERR,"Illegal fix external command"); callback = NULL; - nmax = 0; + // perform initial allocation of atom-based array + // register with Atom class + fexternal = NULL; + grow_arrays(atom->nmax); + atom->add_callback(0); } /* ---------------------------------------------------------------------- */ FixExternal::~FixExternal() { + // unregister callbacks to this fix from Atom class + + atom->delete_callback(id,0); + memory->destroy(fexternal); } @@ -47,8 +72,10 @@ FixExternal::~FixExternal() int FixExternal::setmask() { int mask = 0; - mask |= POST_FORCE; - mask |= MIN_POST_FORCE; + if (mode == PF_CALLBACK || mode == PF_ARRAY) { + mask |= POST_FORCE; + mask |= MIN_POST_FORCE; + } return mask; } @@ -56,7 +83,7 @@ int FixExternal::setmask() void FixExternal::init() { - if (callback == NULL) + if (mode == PF_CALLBACK && callback == NULL) error->all(FLERR,"Fix external callback function not set"); } @@ -78,30 +105,29 @@ void FixExternal::min_setup(int vflag) void FixExternal::post_force(int vflag) { - if (atom->nlocal > nmax) { - memory->destroy(fexternal); - nmax = atom->nmax; - memory->create(fexternal,nmax,3,"external:fexternal"); - } + bigint ntimestep = update->ntimestep; // invoke the callback in driver program // it will fill fexternal with forces - (this->callback)(ptr_caller,update->ntimestep, - atom->nlocal,atom->tag,atom->x,fexternal); + if (mode == PF_CALLBACK && ntimestep & ncall == 0) + (this->callback)(ptr_caller,update->ntimestep, + atom->nlocal,atom->tag,atom->x,fexternal); // add forces from fexternal to atoms in group - double **f = atom->f; - int *mask = atom->mask; - int nlocal = atom->nlocal; + if (ntimestep & napply == 0) { + double **f = atom->f; + int *mask = atom->mask; + int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { - f[i][0] += fexternal[i][0]; - f[i][1] += fexternal[i][1]; - f[i][2] += fexternal[i][2]; - } + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + f[i][0] += fexternal[i][0]; + f[i][1] += fexternal[i][1]; + f[i][2] += fexternal[i][2]; + } + } } /* ---------------------------------------------------------------------- */ @@ -111,6 +137,60 @@ void FixExternal::min_post_force(int vflag) post_force(vflag); } +/* ---------------------------------------------------------------------- + memory usage of local atom-based array +------------------------------------------------------------------------- */ + +double FixExternal::memory_usage() +{ + double bytes = 3*atom->nmax * sizeof(double); + return bytes; +} + +/* ---------------------------------------------------------------------- + allocate atom-based array +------------------------------------------------------------------------- */ + +void FixExternal::grow_arrays(int nmax) +{ + memory->grow(fexternal,nmax,3,"external:fexternal"); +} + +/* ---------------------------------------------------------------------- + copy values within local atom-based array +------------------------------------------------------------------------- */ + +void FixExternal::copy_arrays(int i, int j) +{ + fexternal[j][0] = fexternal[i][0]; + fexternal[j][1] = fexternal[i][1]; + fexternal[j][2] = fexternal[i][2]; +} + +/* ---------------------------------------------------------------------- + pack values in local atom-based array for exchange with another proc +------------------------------------------------------------------------- */ + +int FixExternal::pack_exchange(int i, double *buf) +{ + buf[0] = fexternal[i][0]; + buf[1] = fexternal[i][1]; + buf[2] = fexternal[i][2]; + return 3; +} + +/* ---------------------------------------------------------------------- + unpack values in local atom-based array from exchange with another proc +------------------------------------------------------------------------- */ + +int FixExternal::unpack_exchange(int nlocal, double *buf) +{ + fexternal[nlocal][0] = buf[0]; + fexternal[nlocal][1] = buf[1]; + fexternal[nlocal][2] = buf[2]; + return 3; +} + /* ---------------------------------------------------------------------- external caller sets a callback function to invoke in post_force() ------------------------------------------------------------------------- */ @@ -120,3 +200,4 @@ void FixExternal::set_callback(FnPtr caller_callback, void *caller_ptr) callback = caller_callback; ptr_caller = caller_ptr; } + diff --git a/src/fix_external.h b/src/fix_external.h index 8dce882216..9d4d8d1b62 100644 --- a/src/fix_external.h +++ b/src/fix_external.h @@ -35,10 +35,17 @@ class FixExternal : public Fix { void post_force(int); void min_post_force(int); + double memory_usage(); + void grow_arrays(int); + void copy_arrays(int, int); + int pack_exchange(int, double *); + int unpack_exchange(int, double *); + typedef void (*FnPtr)(void *, int, int, int *, double **, double **); void set_callback(FnPtr, void *); private: + int mode,ncall,napply; FnPtr callback; void *ptr_caller; int nmax;