forked from lijiext/lammps
git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@9222 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
parent
f2d187716c
commit
fa8c7b68fc
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue