diff --git a/src/compute_com_chunk.cpp b/src/compute_com_chunk.cpp index b34310bc9..92194557d 100644 --- a/src/compute_com_chunk.cpp +++ b/src/compute_com_chunk.cpp @@ -1,242 +1,243 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "string.h" #include "compute_com_chunk.h" #include "atom.h" #include "update.h" #include "modify.h" #include "compute_chunk_atom.h" #include "domain.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; enum{ONCE,NFREQ,EVERY}; /* ---------------------------------------------------------------------- */ ComputeCOMChunk::ComputeCOMChunk(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg != 4) error->all(FLERR,"Illegal compute com/chunk command"); array_flag = 1; size_array_cols = 3; size_array_rows = 0; size_array_rows_variable = 1; extarray = 0; // ID of compute chunk/atom int n = strlen(arg[3]) + 1; idchunk = new char[n]; strcpy(idchunk,arg[3]); init(); // chunk-based data nchunk = 1; maxchunk = 0; massproc = masstotal = NULL; com = comall = NULL; allocate(); firstflag = massneed = 1; } /* ---------------------------------------------------------------------- */ ComputeCOMChunk::~ComputeCOMChunk() { delete [] idchunk; memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(com); memory->destroy(comall); } /* ---------------------------------------------------------------------- */ void ComputeCOMChunk::init() { int icompute = modify->find_compute(idchunk); if (icompute < 0) error->all(FLERR,"Chunk/atom compute does not exist for compute com/chunk"); cchunk = (ComputeChunkAtom *) modify->compute[icompute]; if (strcmp(cchunk->style,"chunk/atom") != 0) error->all(FLERR,"Compute com/chunk does not use chunk/atom compute"); } /* ---------------------------------------------------------------------- */ void ComputeCOMChunk::setup() { // one-time calculation of per-chunk mass // done in setup, so that ComputeChunkAtom::setup() is already called if (firstflag && cchunk->idsflag == ONCE) { firstflag = massneed = 0; compute_array(); } } /* ---------------------------------------------------------------------- */ void ComputeCOMChunk::compute_array() { int index; double massone; double unwrap[3]; invoked_array = update->ntimestep; // compute chunk/atom assigns atoms to chunk IDs // extract ichunk index vector from compute // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms nchunk = cchunk->setup_chunks(); cchunk->compute_ichunk(); int *ichunk = cchunk->ichunk; if (nchunk > maxchunk) allocate(); + size_array_rows = nchunk; // zero local per-chunk values for (int i = 0; i < nchunk; i++) com[i][0] = com[i][1] = com[i][2] = 0.0; if (massneed) for (int i = 0; i < nchunk; i++) massproc[i] = 0.0; // compute COM for each chunk double **x = atom->x; int *mask = atom->mask; int *type = atom->type; imageint *image = atom->image; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; domain->unmap(x[i],image[i],unwrap); com[index][0] += unwrap[0] * massone; com[index][1] += unwrap[1] * massone; com[index][2] += unwrap[2] * massone; if (massneed) massproc[index] += massone; } MPI_Allreduce(&com[0][0],&comall[0][0],3*nchunk,MPI_DOUBLE,MPI_SUM,world); if (massneed) MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < nchunk; i++) { if (masstotal[i] > 0.0) { comall[i][0] /= masstotal[i]; comall[i][1] /= masstotal[i]; comall[i][2] /= masstotal[i]; } else comall[i][0] = comall[i][1] = comall[i][2] = 0.0; } } /* ---------------------------------------------------------------------- lock methods: called by fix ave/time these methods insure vector/array size is locked for Nfreq epoch by passing lock info along to compute chunk/atom ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- increment lock counter ------------------------------------------------------------------------- */ void ComputeCOMChunk::lock_enable() { cchunk->lockcount++; } /* ---------------------------------------------------------------------- decrement lock counter in compute chunk/atom, it if still exists ------------------------------------------------------------------------- */ void ComputeCOMChunk::lock_disable() { int icompute = modify->find_compute(idchunk); if (icompute >= 0) { cchunk = (ComputeChunkAtom *) modify->compute[icompute]; cchunk->lockcount--; } } /* ---------------------------------------------------------------------- calculate and return # of chunks = length of vector/array ------------------------------------------------------------------------- */ int ComputeCOMChunk::lock_length() { nchunk = cchunk->setup_chunks(); return nchunk; } /* ---------------------------------------------------------------------- set the lock from startstep to stopstep ------------------------------------------------------------------------- */ void ComputeCOMChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep) { cchunk->lock(fixptr,startstep,stopstep); } /* ---------------------------------------------------------------------- unset the lock ------------------------------------------------------------------------- */ void ComputeCOMChunk::unlock(Fix *fixptr) { cchunk->unlock(fixptr); } /* ---------------------------------------------------------------------- free and reallocate per-chunk arrays ------------------------------------------------------------------------- */ void ComputeCOMChunk::allocate() { memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(com); memory->destroy(comall); - size_array_rows = maxchunk = nchunk; + maxchunk = nchunk; memory->create(massproc,maxchunk,"com/chunk:massproc"); memory->create(masstotal,maxchunk,"com/chunk:masstotal"); memory->create(com,maxchunk,3,"com/chunk:com"); memory->create(comall,maxchunk,3,"com/chunk:comall"); array = comall; } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputeCOMChunk::memory_usage() { double bytes = (bigint) maxchunk * 2 * sizeof(double); bytes += (bigint) maxchunk * 2*3 * sizeof(double); return bytes; } diff --git a/src/compute_gyration_chunk.cpp b/src/compute_gyration_chunk.cpp index 91bcdf97c..a0148cd6d 100644 --- a/src/compute_gyration_chunk.cpp +++ b/src/compute_gyration_chunk.cpp @@ -1,357 +1,359 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "math.h" #include "string.h" #include "compute_gyration_chunk.h" #include "atom.h" #include "update.h" #include "modify.h" #include "compute_chunk_atom.h" #include "domain.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeGyrationChunk::ComputeGyrationChunk(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg < 4) error->all(FLERR,"Illegal compute gyration/chunk command"); // ID of compute chunk/atom int n = strlen(arg[6]) + 1; idchunk = new char[n]; strcpy(idchunk,arg[6]); init(); // optional args tensor = 0; int iarg = 3; while (iarg < narg) { if (strcmp(arg[iarg],"tensor") == 0) { tensor = 1; iarg++; } else error->all(FLERR,"Illegal compute gyration/chunk command"); } if (tensor) { array_flag = 1; size_array_cols = 6; size_array_rows = 0; size_array_rows_variable = 1; extarray = 0; } else { vector_flag = 1; size_vector = 0; size_vector_variable = 1; extvector = 0; } // chunk-based data nchunk = 1; maxchunk = 0; massproc = masstotal = NULL; com = comall = NULL; rg = rgall = NULL; rgt = rgtall = NULL; allocate(); } /* ---------------------------------------------------------------------- */ ComputeGyrationChunk::~ComputeGyrationChunk() { delete [] idchunk; memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(com); memory->destroy(comall); memory->destroy(rg); memory->destroy(rgall); memory->destroy(rgt); memory->destroy(rgtall); } /* ---------------------------------------------------------------------- */ void ComputeGyrationChunk::init() { int icompute = modify->find_compute(idchunk); if (icompute < 0) error->all(FLERR,"Chunk/atom compute does not exist for " "compute gyration/chunk"); cchunk = (ComputeChunkAtom *) modify->compute[icompute]; if (strcmp(cchunk->style,"chunk/atom") != 0) error->all(FLERR,"Compute gyration/chunk does not use chunk/atom compute"); } /* ---------------------------------------------------------------------- */ void ComputeGyrationChunk::compute_vector() { int i,index; double dx,dy,dz,massone; double unwrap[3]; invoked_array = update->ntimestep; com_chunk(); int *ichunk = cchunk->ichunk; for (i = 0; i < nchunk; i++) rg[i] = 0.0; // compute Rg for each chunk double **x = atom->x; int *mask = atom->mask; int *type = atom->type; imageint *image = atom->image; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; domain->unmap(x[i],image[i],unwrap); dx = unwrap[0] - comall[index][0]; dy = unwrap[1] - comall[index][1]; dz = unwrap[2] - comall[index][2]; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; rg[index] += (dx*dx + dy*dy + dz*dz) * massone; } MPI_Allreduce(rg,rgall,nchunk,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < nchunk; i++) rgall[i] = sqrt(rgall[i]/masstotal[i]); } /* ---------------------------------------------------------------------- */ void ComputeGyrationChunk::compute_array() { int i,j,index; double dx,dy,dz,massone; double unwrap[3]; invoked_array = update->ntimestep; com_chunk(); int *ichunk = cchunk->ichunk; for (i = 0; i < nchunk; i++) for (j = 0; j < 6; j++) rgt[i][j] = 0.0; double **x = atom->x; int *mask = atom->mask; int *type = atom->type; imageint *image = atom->image; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; domain->unmap(x[i],image[i],unwrap); dx = unwrap[0] - comall[index][0]; dy = unwrap[1] - comall[index][1]; dz = unwrap[2] - comall[index][2]; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; rgt[index][0] += dx*dx * massone; rgt[index][1] += dy*dy * massone; rgt[index][2] += dz*dz * massone; rgt[index][3] += dx*dy * massone; rgt[index][4] += dx*dz * massone; rgt[index][5] += dy*dz * massone; } if (nchunk) MPI_Allreduce(&rgt[0][0],&rgtall[0][0],nchunk*6,MPI_DOUBLE,MPI_SUM,world); for (i = 0; i < nchunk; i++) for (j = 0; j < 6; j++) rgtall[i][j] = rgtall[i][j]/masstotal[i]; } /* ---------------------------------------------------------------------- calculate per-chunk COM, used by both scalar and tensor ------------------------------------------------------------------------- */ void ComputeGyrationChunk::com_chunk() { int index; double massone; double unwrap[3]; // compute chunk/atom assigns atoms to chunk IDs // extract ichunk index vector from compute // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms nchunk = cchunk->setup_chunks(); cchunk->compute_ichunk(); int *ichunk = cchunk->ichunk; if (nchunk > maxchunk) allocate(); + if (tensor) size_array_rows = nchunk; + else size_vector = nchunk; // zero local per-chunk values for (int i = 0; i < nchunk; i++) { massproc[i] = 0.0; com[i][0] = com[i][1] = com[i][2] = 0.0; } // compute COM for each chunk double **x = atom->x; int *mask = atom->mask; int *type = atom->type; imageint *image = atom->image; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; domain->unmap(x[i],image[i],unwrap); massproc[index] += massone; com[index][0] += unwrap[0] * massone; com[index][1] += unwrap[1] * massone; com[index][2] += unwrap[2] * massone; } MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&com[0][0],&comall[0][0],3*nchunk,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < nchunk; i++) { comall[i][0] /= masstotal[i]; comall[i][1] /= masstotal[i]; comall[i][2] /= masstotal[i]; } } /* ---------------------------------------------------------------------- lock methods: called by fix ave/time these methods insure vector/array size is locked for Nfreq epoch by passing lock info along to compute chunk/atom ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- increment lock counter ------------------------------------------------------------------------- */ void ComputeGyrationChunk::lock_enable() { cchunk->lockcount++; } /* ---------------------------------------------------------------------- decrement lock counter in compute chunk/atom, it if still exists ------------------------------------------------------------------------- */ void ComputeGyrationChunk::lock_disable() { int icompute = modify->find_compute(idchunk); if (icompute >= 0) { cchunk = (ComputeChunkAtom *) modify->compute[icompute]; cchunk->lockcount--; } } /* ---------------------------------------------------------------------- calculate and return # of chunks = length of vector/array ------------------------------------------------------------------------- */ int ComputeGyrationChunk::lock_length() { nchunk = cchunk->setup_chunks(); return nchunk; } /* ---------------------------------------------------------------------- set the lock from startstep to stopstep ------------------------------------------------------------------------- */ void ComputeGyrationChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep) { cchunk->lock(fixptr,startstep,stopstep); } /* ---------------------------------------------------------------------- unset the lock ------------------------------------------------------------------------- */ void ComputeGyrationChunk::unlock(Fix *fixptr) { cchunk->unlock(fixptr); } /* ---------------------------------------------------------------------- free and reallocate per-chunk arrays ------------------------------------------------------------------------- */ void ComputeGyrationChunk::allocate() { memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(com); memory->destroy(comall); memory->destroy(rg); memory->destroy(rgall); memory->destroy(rgt); memory->destroy(rgtall); - size_array_rows = maxchunk = nchunk; + maxchunk = nchunk; memory->create(massproc,maxchunk,"gyration/chunk:massproc"); memory->create(masstotal,maxchunk,"gyration/chunk:masstotal"); memory->create(com,maxchunk,3,"gyration/chunk:com"); memory->create(comall,maxchunk,3,"gyration/chunk:comall"); if (tensor) { memory->create(rgt,maxchunk,6,"gyration/chunk:rgt"); memory->create(rgtall,maxchunk,6,"gyration/chunk:rgtall"); array = rgtall; } else { memory->create(rg,maxchunk,"gyration/chunk:rg"); memory->create(rgall,maxchunk,"gyration/chunk:rgall"); vector = rgall; } } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputeGyrationChunk::memory_usage() { double bytes = (bigint) maxchunk * 2 * sizeof(double); bytes += (bigint) maxchunk * 2*3 * sizeof(double); if (tensor) bytes += (bigint) maxchunk * 2*6 * sizeof(double); else bytes += (bigint) maxchunk * 2 * sizeof(double); return bytes; } diff --git a/src/compute_inertia_chunk.cpp b/src/compute_inertia_chunk.cpp index f04b29147..93229f413 100644 --- a/src/compute_inertia_chunk.cpp +++ b/src/compute_inertia_chunk.cpp @@ -1,256 +1,257 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "string.h" #include "compute_inertia_chunk.h" #include "atom.h" #include "update.h" #include "modify.h" #include "compute_chunk_atom.h" #include "domain.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeInertiaChunk::ComputeInertiaChunk(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg != 4) error->all(FLERR,"Illegal compute inertia/chunk command"); array_flag = 1; size_array_cols = 6; size_array_rows = 0; size_array_rows_variable = 1; extarray = 0; // ID of compute chunk/atom int n = strlen(arg[6]) + 1; idchunk = new char[n]; strcpy(idchunk,arg[6]); init(); // chunk-based data nchunk = 1; maxchunk = 0; massproc = masstotal = NULL; com = comall = NULL; inertia = inertiaall = NULL; allocate(); } /* ---------------------------------------------------------------------- */ ComputeInertiaChunk::~ComputeInertiaChunk() { delete [] idchunk; memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(com); memory->destroy(comall); memory->destroy(inertia); memory->destroy(inertiaall); } /* ---------------------------------------------------------------------- */ void ComputeInertiaChunk::init() { int icompute = modify->find_compute(idchunk); if (icompute < 0) error->all(FLERR,"Chunk/atom compute does not exist for " "compute inertia/chunk"); cchunk = (ComputeChunkAtom *) modify->compute[icompute]; if (strcmp(cchunk->style,"chunk/atom") != 0) error->all(FLERR,"Compute inertia/chunk does not use chunk/atom compute"); } /* ---------------------------------------------------------------------- */ void ComputeInertiaChunk::compute_array() { int i,j,index; double dx,dy,dz,massone; double unwrap[3]; invoked_array = update->ntimestep; // compute chunk/atom assigns atoms to chunk IDs // extract ichunk index vector from compute // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms nchunk = cchunk->setup_chunks(); cchunk->compute_ichunk(); int *ichunk = cchunk->ichunk; if (nchunk > maxchunk) allocate(); + size_array_rows = nchunk; // zero local per-chunk values for (int i = 0; i < nchunk; i++) { massproc[i] = 0.0; com[i][0] = com[i][1] = com[i][2] = 0.0; for (j = 0; j < 6; j++) inertia[i][j] = 0.0; } // compute COM for each chunk double **x = atom->x; int *mask = atom->mask; int *type = atom->type; imageint *image = atom->image; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; domain->unmap(x[i],image[i],unwrap); massproc[index] += massone; com[index][0] += unwrap[0] * massone; com[index][1] += unwrap[1] * massone; com[index][2] += unwrap[2] * massone; } MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&com[0][0],&comall[0][0],3*nchunk,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < nchunk; i++) { comall[i][0] /= masstotal[i]; comall[i][1] /= masstotal[i]; comall[i][2] /= masstotal[i]; } // compute inertia tensor for each chunk for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; domain->unmap(x[i],image[i],unwrap); dx = unwrap[0] - comall[index][0]; dy = unwrap[1] - comall[index][1]; dz = unwrap[2] - comall[index][2]; inertia[index][0] += massone * (dy*dy + dz*dz); inertia[index][1] += massone * (dx*dx + dz*dz); inertia[index][2] += massone * (dx*dx + dy*dy); inertia[index][3] -= massone * dx*dy; inertia[index][4] -= massone * dy*dz; inertia[index][5] -= massone * dx*dz; } MPI_Allreduce(&inertia[0][0],&inertiaall[0][0],6*nchunk, MPI_DOUBLE,MPI_SUM,world); } /* ---------------------------------------------------------------------- lock methods: called by fix ave/time these methods insure vector/array size is locked for Nfreq epoch by passing lock info along to compute chunk/atom ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- increment lock counter ------------------------------------------------------------------------- */ void ComputeInertiaChunk::lock_enable() { cchunk->lockcount++; } /* ---------------------------------------------------------------------- decrement lock counter in compute chunk/atom, it if still exists ------------------------------------------------------------------------- */ void ComputeInertiaChunk::lock_disable() { int icompute = modify->find_compute(idchunk); if (icompute >= 0) { cchunk = (ComputeChunkAtom *) modify->compute[icompute]; cchunk->lockcount--; } } /* ---------------------------------------------------------------------- calculate and return # of chunks = length of vector/array ------------------------------------------------------------------------- */ int ComputeInertiaChunk::lock_length() { nchunk = cchunk->setup_chunks(); return nchunk; } /* ---------------------------------------------------------------------- set the lock from startstep to stopstep ------------------------------------------------------------------------- */ void ComputeInertiaChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep) { cchunk->lock(fixptr,startstep,stopstep); } /* ---------------------------------------------------------------------- unset the lock ------------------------------------------------------------------------- */ void ComputeInertiaChunk::unlock(Fix *fixptr) { cchunk->unlock(fixptr); } /* ---------------------------------------------------------------------- free and reallocate per-chunk arrays ------------------------------------------------------------------------- */ void ComputeInertiaChunk::allocate() { memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(com); memory->destroy(comall); memory->destroy(inertia); memory->destroy(inertiaall); - size_array_rows = maxchunk = nchunk; + maxchunk = nchunk; memory->create(massproc,maxchunk,"inertia/chunk:massproc"); memory->create(masstotal,maxchunk,"inertia/chunk:masstotal"); memory->create(com,maxchunk,3,"inertia/chunk:com"); memory->create(comall,maxchunk,3,"inertia/chunk:comall"); memory->create(inertia,maxchunk,6,"inertia/chunk:inertia"); memory->create(inertiaall,maxchunk,6,"inertia/chunk:inertiaall"); array = inertiaall; } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputeInertiaChunk::memory_usage() { double bytes = (bigint) maxchunk * 2 * sizeof(double); bytes += (bigint) maxchunk * 2*3 * sizeof(double); bytes += (bigint) maxchunk * 2*6 * sizeof(double); return bytes; } diff --git a/src/compute_msd_chunk.cpp b/src/compute_msd_chunk.cpp index 180b420b3..5f060b1ff 100644 --- a/src/compute_msd_chunk.cpp +++ b/src/compute_msd_chunk.cpp @@ -1,261 +1,262 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "string.h" #include "compute_msd_chunk.h" #include "atom.h" #include "update.h" #include "modify.h" #include "compute_chunk_atom.h" #include "domain.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeMSDChunk::ComputeMSDChunk(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg != 4) error->all(FLERR,"Illegal compute msd/chunk command"); array_flag = 1; size_array_cols = 4; size_array_rows = 0; size_array_rows_variable = 1; extarray = 0; // ID of compute chunk/atom int n = strlen(arg[6]) + 1; idchunk = new char[n]; strcpy(idchunk,arg[6]); init(); massproc = masstotal = NULL; com = comall = cominit = NULL; msd = NULL; firstflag = 1; } /* ---------------------------------------------------------------------- */ ComputeMSDChunk::~ComputeMSDChunk() { delete [] idchunk; memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(com); memory->destroy(comall); memory->destroy(cominit); memory->destroy(msd); } /* ---------------------------------------------------------------------- */ void ComputeMSDChunk::init() { int icompute = modify->find_compute(idchunk); if (icompute < 0) error->all(FLERR,"Chunk/atom compute does not exist for compute msd/chunk"); cchunk = (ComputeChunkAtom *) modify->compute[icompute]; if (strcmp(cchunk->style,"chunk/atom") != 0) error->all(FLERR,"Compute msd/chunk does not use chunk/atom compute"); } /* ---------------------------------------------------------------------- compute initial COM for each chunk only once on timestep compute is defined, when firstflag = 1 ------------------------------------------------------------------------- */ void ComputeMSDChunk::setup() { if (!firstflag) return; firstflag = 0; compute_array(); for (int i = 0; i < nchunk; i++) { cominit[i][0] = comall[i][0]; cominit[i][1] = comall[i][1]; cominit[i][2] = comall[i][2]; } } /* ---------------------------------------------------------------------- */ void ComputeMSDChunk::compute_array() { int index; double massone; double unwrap[3]; invoked_array = update->ntimestep; // compute chunk/atom assigns atoms to chunk IDs // extract ichunk index vector from compute // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms int n = cchunk->setup_chunks(); cchunk->compute_ichunk(); int *ichunk = cchunk->ichunk; // first time call, allocate per-chunk arrays // thereafter, require nchunk remain the same - if (firstflag) allocate(n); - else if (n != nchunk) + if (firstflag) { + nchunk = n; + allocate(); + } else if (n != nchunk) error->all(FLERR,"Compute msd/chunk nchunk is not static"); // zero local per-chunk values for (int i = 0; i < nchunk; i++) { massproc[i] = 0.0; com[i][0] = com[i][1] = com[i][2] = 0.0; } // compute current COM for each chunk double **x = atom->x; int *mask = atom->mask; int *type = atom->type; imageint *image = atom->image; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; domain->unmap(x[i],image[i],unwrap); massproc[index] += massone; com[index][0] += unwrap[0] * massone; com[index][1] += unwrap[1] * massone; com[index][2] += unwrap[2] * massone; } MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&com[0][0],&comall[0][0],3*nchunk,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < nchunk; i++) { comall[i][0] /= masstotal[i]; comall[i][1] /= masstotal[i]; comall[i][2] /= masstotal[i]; } // MSD is difference between current and initial COM // cominit does not yet exist when called from constructor if (firstflag) return; double dx,dy,dz; for (int i = 0; i < nchunk; i++) { dx = comall[i][0] - cominit[i][0]; dy = comall[i][1] - cominit[i][1]; dz = comall[i][2] - cominit[i][2]; msd[i][0] = dx*dx; msd[i][1] = dy*dy; msd[i][2] = dz*dz; msd[i][3] = dx*dx + dy*dy + dz*dz; } } /* ---------------------------------------------------------------------- lock methods: called by fix ave/time these methods insure vector/array size is locked for Nfreq epoch by passing lock info along to compute chunk/atom ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- increment lock counter ------------------------------------------------------------------------- */ void ComputeMSDChunk::lock_enable() { cchunk->lockcount++; } /* ---------------------------------------------------------------------- decrement lock counter in compute chunk/atom, it if still exists ------------------------------------------------------------------------- */ void ComputeMSDChunk::lock_disable() { int icompute = modify->find_compute(idchunk); if (icompute >= 0) { cchunk = (ComputeChunkAtom *) modify->compute[icompute]; cchunk->lockcount--; } } /* ---------------------------------------------------------------------- calculate and return # of chunks = length of vector/array ------------------------------------------------------------------------- */ int ComputeMSDChunk::lock_length() { nchunk = cchunk->setup_chunks(); return nchunk; } /* ---------------------------------------------------------------------- set the lock from startstep to stopstep ------------------------------------------------------------------------- */ void ComputeMSDChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep) { cchunk->lock(fixptr,startstep,stopstep); } /* ---------------------------------------------------------------------- unset the lock ------------------------------------------------------------------------- */ void ComputeMSDChunk::unlock(Fix *fixptr) { cchunk->unlock(fixptr); } /* ---------------------------------------------------------------------- one-time allocate of per-chunk arrays ------------------------------------------------------------------------- */ -void ComputeMSDChunk::allocate(int n) +void ComputeMSDChunk::allocate() { - size_array_rows = nchunk = n; memory->create(massproc,nchunk,"msd/chunk:massproc"); memory->create(masstotal,nchunk,"msd/chunk:masstotal"); memory->create(com,nchunk,3,"msd/chunk:com"); memory->create(comall,nchunk,3,"msd/chunk:comall"); memory->create(cominit,nchunk,3,"msd/chunk:cominit"); memory->create(msd,nchunk,4,"msd/chunk:msd"); array = msd; } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputeMSDChunk::memory_usage() { double bytes = (bigint) nchunk * 2 * sizeof(double); bytes += (bigint) nchunk * 3*3 * sizeof(double); bytes += (bigint) nchunk * 4 * sizeof(double); return bytes; } diff --git a/src/compute_msd_chunk.h b/src/compute_msd_chunk.h index 8562aa976..269fb153b 100644 --- a/src/compute_msd_chunk.h +++ b/src/compute_msd_chunk.h @@ -1,78 +1,78 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #ifdef COMPUTE_CLASS ComputeStyle(msd/chunk,ComputeMSDChunk) #else #ifndef LMP_COMPUTE_MSD_CHUNK_H #define LMP_COMPUTE_MSD_CHUNK_H #include "compute.h" namespace LAMMPS_NS { class ComputeMSDChunk : public Compute { public: ComputeMSDChunk(class LAMMPS *, int, char **); ~ComputeMSDChunk(); void init(); void setup(); void compute_array(); void lock_enable(); void lock_disable(); int lock_length(); void lock(class Fix *, bigint, bigint); void unlock(class Fix *); double memory_usage(); private: int nchunk; char *idchunk; class ComputeChunkAtom *cchunk; double *massproc,*masstotal; double **com,**comall,**cominit; double **msd; int firstflag; - void allocate(int); + void allocate(); }; } #endif #endif /* ERROR/WARNING messages: E: Illegal ... command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Compute com/molecule requires molecular atom style Self-explanatory. E: Molecule count changed in compute com/molecule Number of molecules must remain constant over time. */ diff --git a/src/compute_property_chunk.cpp b/src/compute_property_chunk.cpp index 28dffb926..0fc67118f 100644 --- a/src/compute_property_chunk.cpp +++ b/src/compute_property_chunk.cpp @@ -1,337 +1,338 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "string.h" #include "compute_property_chunk.h" #include "atom.h" #include "update.h" #include "modify.h" #include "compute_chunk_atom.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputePropertyChunk::ComputePropertyChunk(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg < 5) error->all(FLERR,"Illegal compute property/chunk command"); // ID of compute chunk/atom int n = strlen(arg[3]) + 1; idchunk = new char[n]; strcpy(idchunk,arg[3]); init(); // parse values nvalues = narg - 4; pack_choice = new FnPtrPack[nvalues]; countflag = 0; int i; for (int iarg = 4; iarg < narg; iarg++) { i = iarg-4; if (strcmp(arg[iarg],"count") == 0) { pack_choice[i] = &ComputePropertyChunk::pack_count; countflag = 1; } else if (strcmp(arg[iarg],"id") == 0) { if (!cchunk->compress) error->all(FLERR,"Compute chunk/atom stores no IDs for " "compute property/chunk"); pack_choice[i] = &ComputePropertyChunk::pack_id; } else if (strcmp(arg[iarg],"coord1") == 0) { if (cchunk->ncoord < 1) error->all(FLERR,"Compute chunk/atom stores no coord1 for " "compute property/chunk"); pack_choice[i] = &ComputePropertyChunk::pack_coord1; } else if (strcmp(arg[iarg],"coord2") == 0) { if (cchunk->ncoord < 2) error->all(FLERR,"Compute chunk/atom stores no coord2 for " "compute property/chunk"); pack_choice[i] = &ComputePropertyChunk::pack_coord2; } else if (strcmp(arg[iarg],"coord3") == 0) { if (cchunk->ncoord < 3) error->all(FLERR,"Compute chunk/atom stores no coord3 for " "compute property/chunk"); pack_choice[i] = &ComputePropertyChunk::pack_coord3; } else error->all(FLERR, "Invalid keyword in compute property/chunk command"); } // initialization nchunk = 1; maxchunk = 0; vector = NULL; array = NULL; count_one = count_all = NULL; allocate(); if (nvalues == 1) { vector_flag = 1; size_vector = 0; size_vector_variable = 1; extvector = 0; } else { array_flag = 1; size_array_cols = nvalues; size_array_rows = 0; size_array_rows_variable = 1; extarray = 0; } } /* ---------------------------------------------------------------------- */ ComputePropertyChunk::~ComputePropertyChunk() { delete [] idchunk; delete [] pack_choice; memory->destroy(vector); memory->destroy(array); memory->destroy(count_one); memory->destroy(count_all); } /* ---------------------------------------------------------------------- */ void ComputePropertyChunk::init() { int icompute = modify->find_compute(idchunk); if (icompute < 0) error->all(FLERR,"Chunk/atom compute does not exist for " "compute property/chunk"); cchunk = (ComputeChunkAtom *) modify->compute[icompute]; if (strcmp(cchunk->style,"chunk/atom") != 0) error->all(FLERR,"Compute property/chunk does not use chunk/atom compute"); } /* ---------------------------------------------------------------------- */ void ComputePropertyChunk::compute_vector() { invoked_vector = update->ntimestep; // compute chunk/atom assigns atoms to chunk IDs // if need count, extract ichunk index vector from compute // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms nchunk = cchunk->setup_chunks(); if (nchunk > maxchunk) allocate(); + if (nvalues == 1) size_vector = nchunk; + else size_array_rows = nchunk; if (countflag) { cchunk->compute_ichunk(); ichunk = cchunk->ichunk; } // fill vector buf = vector; (this->*pack_choice[0])(0); } /* ---------------------------------------------------------------------- */ void ComputePropertyChunk::compute_array() { invoked_array = update->ntimestep; // compute chunk/atom assigns atoms to chunk IDs // if need count, extract ichunk index vector from compute // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms nchunk = cchunk->setup_chunks(); if (nchunk > maxchunk) allocate(); + if (nvalues == 1) size_vector = nchunk; + else size_array_rows = nchunk; if (countflag) { cchunk->compute_ichunk(); ichunk = cchunk->ichunk; } // fill array if (array) buf = &array[0][0]; for (int n = 0; n < nvalues; n++) (this->*pack_choice[n])(n); } /* ---------------------------------------------------------------------- lock methods: called by fix ave/time these methods insure vector/array size is locked for Nfreq epoch by passing lock info along to compute chunk/atom ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- increment lock counter ------------------------------------------------------------------------- */ void ComputePropertyChunk::lock_enable() { cchunk->lockcount++; } /* ---------------------------------------------------------------------- decrement lock counter in compute chunk/atom, it if still exists ------------------------------------------------------------------------- */ void ComputePropertyChunk::lock_disable() { int icompute = modify->find_compute(idchunk); if (icompute >= 0) { cchunk = (ComputeChunkAtom *) modify->compute[icompute]; cchunk->lockcount--; } } /* ---------------------------------------------------------------------- calculate and return # of chunks = length of vector/array ------------------------------------------------------------------------- */ int ComputePropertyChunk::lock_length() { nchunk = cchunk->setup_chunks(); return nchunk; } /* ---------------------------------------------------------------------- set the lock from startstep to stopstep ------------------------------------------------------------------------- */ void ComputePropertyChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep) { cchunk->lock(fixptr,startstep,stopstep); } /* ---------------------------------------------------------------------- unset the lock ------------------------------------------------------------------------- */ void ComputePropertyChunk::unlock(Fix *fixptr) { cchunk->unlock(fixptr); } /* ---------------------------------------------------------------------- free and reallocate per-chunk arrays ------------------------------------------------------------------------- */ void ComputePropertyChunk::allocate() { memory->destroy(vector); memory->destroy(array); memory->destroy(count_one); memory->destroy(count_all); - - if (nvalues == 1) size_vector = maxchunk = nchunk; - else size_array_rows = maxchunk = nchunk; + maxchunk = nchunk; if (nvalues == 1) memory->create(vector,maxchunk,"property/chunk:vector"); else memory->create(array,maxchunk,nvalues,"property/chunk:array"); - if (countflag) { memory->create(count_one,maxchunk,"property/chunk:count_one"); memory->create(count_all,maxchunk,"property/chunk:count_all"); } } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputePropertyChunk::memory_usage() { double bytes = (bigint) nchunk * nvalues * sizeof(double); if (countflag) bytes += (bigint) nchunk * 2 * sizeof(int); return bytes; } /* ---------------------------------------------------------------------- one method for every keyword compute property/chunk can output the property is packed into buf starting at n with stride nvalues customize a new keyword by adding a method ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ void ComputePropertyChunk::pack_count(int n) { int index; for (int m = 0; m < nchunk; m++) count_one[m] = 0; int *mask = atom->mask; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; count_one[index]++; } } MPI_Allreduce(count_one,count_all,nchunk,MPI_INT,MPI_SUM,world); for (int m = 0; m < nchunk; m++) { buf[n] = count_all[m]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyChunk::pack_id(int n) { int *origID = cchunk->chunkID; for (int m = 0; m < nchunk; m++) { buf[n] = origID[m]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyChunk::pack_coord1(int n) { double **coord = cchunk->coord; for (int m = 0; m < nchunk; m++) { buf[n] = coord[m][0]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyChunk::pack_coord2(int n) { double **coord = cchunk->coord; for (int m = 0; m < nchunk; m++) { buf[n] = coord[m][1]; n += nvalues; } } /* ---------------------------------------------------------------------- */ void ComputePropertyChunk::pack_coord3(int n) { double **coord = cchunk->coord; for (int m = 0; m < nchunk; m++) { buf[n] = coord[m][2]; n += nvalues; } } diff --git a/src/compute_temp_chunk.cpp b/src/compute_temp_chunk.cpp index 66b16ad2e..7767582ea 100644 --- a/src/compute_temp_chunk.cpp +++ b/src/compute_temp_chunk.cpp @@ -1,407 +1,408 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "string.h" #include "compute_temp_chunk.h" #include "atom.h" #include "update.h" #include "force.h" #include "modify.h" #include "compute_chunk_atom.h" #include "domain.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeTempChunk::ComputeTempChunk(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg < 4) error->all(FLERR,"Illegal compute temp/chunk command"); vector_flag = 1; - size_vector = 1; + size_vector = 0; size_vector_variable = 1; extvector = 0; // ID of compute chunk/atom int n = strlen(arg[3]) + 1; idchunk = new char[n]; strcpy(idchunk,arg[3]); biasflag = 0; init(); // optional args comflag = 0; biasflag = 0; id_bias = NULL; adof = domain->dimension; cdof = 0.0; int iarg = 4; while (iarg < narg) { if (strcmp(arg[iarg],"com") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/chunk command"); if (strcmp(arg[iarg+1],"yes") == 0) comflag = 1; else if (strcmp(arg[iarg+1],"no") == 0) comflag = 0; else error->all(FLERR,"Illegal compute temp/chunk command"); iarg += 2; } else if (strcmp(arg[iarg],"bias") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/chunk command"); biasflag = 1; int n = strlen(arg[iarg+1]) + 1; id_bias = new char[n]; strcpy(id_bias,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"adof") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/chunk command"); adof = force->numeric(FLERR,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"cdof") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/chunk command"); cdof = force->numeric(FLERR,arg[iarg+1]); iarg += 2; } else error->all(FLERR,"Illegal compute temp/chunk command"); } if (comflag && biasflag) error->all(FLERR,"Cannot use both com and bias with compute temp/chunk"); // error check on bias compute if (biasflag) { int i = modify->find_compute(id_bias); if (i < 0) error->all(FLERR,"Could not find compute ID for temperature bias"); tbias = modify->compute[i]; if (tbias->tempflag == 0) error->all(FLERR,"Bias compute does not calculate temperature"); if (tbias->tempbias == 0) error->all(FLERR,"Bias compute does not calculate a velocity bias"); } // chunk-based data nchunk = 1; maxchunk = 0; ke = keall = NULL; count = countall = NULL; massproc = masstotal = NULL; vcm = vcmall = NULL; allocate(); } /* ---------------------------------------------------------------------- */ ComputeTempChunk::~ComputeTempChunk() { delete [] idchunk; delete [] id_bias; memory->destroy(ke); memory->destroy(keall); memory->destroy(count); memory->destroy(countall); memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(vcm); memory->destroy(vcmall); } /* ---------------------------------------------------------------------- */ void ComputeTempChunk::init() { int icompute = modify->find_compute(idchunk); if (icompute < 0) error->all(FLERR,"Chunk/atom compute does not exist for " "compute temp/chunk"); cchunk = (ComputeChunkAtom *) modify->compute[icompute]; if (strcmp(cchunk->style,"chunk/atom") != 0) error->all(FLERR,"Compute temp/chunk does not use chunk/atom compute"); if (biasflag) { int i = modify->find_compute(id_bias); if (i < 0) error->all(FLERR,"Could not find compute ID for temperature bias"); tbias = modify->compute[i]; } } /* ---------------------------------------------------------------------- */ void ComputeTempChunk::compute_vector() { int index; invoked_vector = update->ntimestep; // compute chunk/atom assigns atoms to chunk IDs // extract ichunk index vector from compute // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms nchunk = cchunk->setup_chunks(); cchunk->compute_ichunk(); int *ichunk = cchunk->ichunk; if (nchunk > maxchunk) allocate(); + size_vector = nchunk; // calculate COM velocity for each chunk if (comflag) vcm_compute(); // remove velocity bias if (biasflag) { if (tbias->invoked_scalar != update->ntimestep) tbias->compute_scalar(); tbias->remove_bias_all(); } // zero local per-chunk values for (int i = 0; i < nchunk; i++) { count[i] = 0; ke[i] = 0.0; } // compute temperature for each chunk // option for removing COM velocity double **v = atom->v; double *mass = atom->mass; double *rmass = atom->rmass; int *mask = atom->mask; int *type = atom->type; int nlocal = atom->nlocal; if (!comflag) { if (rmass) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; ke[index] += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * rmass[i]; count[index]++; } } else { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; ke[index] += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * mass[type[i]]; count[index]++; } } } else { double vx,vy,vz; if (rmass) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; vx = v[i][0] - vcmall[index][0]; vy = v[i][1] - vcmall[index][1]; vz = v[i][2] - vcmall[index][2]; ke[index] += (vx*vx + vy*vy + vz*vz) * rmass[i]; count[index]++; } } else { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; vx = v[i][0] - vcmall[index][0]; vy = v[i][1] - vcmall[index][1]; vz = v[i][2] - vcmall[index][2]; ke[index] += (vx*vx + vy*vy + vz*vz) * mass[type[i]]; count[index]++; } } } MPI_Allreduce(ke,keall,nchunk,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(count,countall,nchunk,MPI_INT,MPI_SUM,world); // restore velocity bias if (biasflag) tbias->restore_bias_all(); // normalize temperatures by per-chunk DOF double dof,tfactor; double mvv2e = force->mvv2e; double boltz = force->boltz; for (int i = 0; i < nchunk; i++) { dof = cdof + adof*countall[i]; if (dof > 0.0) tfactor = mvv2e / (dof * boltz); else tfactor = 0.0; keall[i] *= tfactor; } } /* ---------------------------------------------------------------------- calculate velocity of COM for each chunk ------------------------------------------------------------------------- */ void ComputeTempChunk::vcm_compute() { int index; double massone; int *ichunk = cchunk->ichunk; for (int i = 0; i < nchunk; i++) { vcm[i][0] = vcm[i][1] = vcm[i][2] = 0.0; massproc[i] = 0.0; } double **v = atom->v; int *mask = atom->mask; int *type = atom->type; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; vcm[index][0] += v[i][0] * massone; vcm[index][1] += v[i][1] * massone; vcm[index][2] += v[i][2] * massone; massproc[index] += massone; } MPI_Allreduce(&vcm[0][0],&vcmall[0][0],3*nchunk,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < nchunk; i++) { vcmall[i][0] /= masstotal[i]; vcmall[i][1] /= masstotal[i]; vcmall[i][2] /= masstotal[i]; } } /* ---------------------------------------------------------------------- lock methods: called by fix ave/time these methods insure vector/array size is locked for Nfreq epoch by passing lock info along to compute chunk/atom ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- increment lock counter ------------------------------------------------------------------------- */ void ComputeTempChunk::lock_enable() { cchunk->lockcount++; } /* ---------------------------------------------------------------------- decrement lock counter in compute chunk/atom, it if still exists ------------------------------------------------------------------------- */ void ComputeTempChunk::lock_disable() { int icompute = modify->find_compute(idchunk); if (icompute >= 0) { cchunk = (ComputeChunkAtom *) modify->compute[icompute]; cchunk->lockcount--; } } /* ---------------------------------------------------------------------- calculate and return # of chunks = length of vector/array ------------------------------------------------------------------------- */ int ComputeTempChunk::lock_length() { nchunk = cchunk->setup_chunks(); return nchunk; } /* ---------------------------------------------------------------------- set the lock from startstep to stopstep ------------------------------------------------------------------------- */ void ComputeTempChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep) { cchunk->lock(fixptr,startstep,stopstep); } /* ---------------------------------------------------------------------- unset the lock ------------------------------------------------------------------------- */ void ComputeTempChunk::unlock(Fix *fixptr) { cchunk->unlock(fixptr); } /* ---------------------------------------------------------------------- free and reallocate per-chunk arrays ------------------------------------------------------------------------- */ void ComputeTempChunk::allocate() { memory->destroy(ke); memory->destroy(keall); memory->destroy(count); memory->destroy(countall); - size_vector = maxchunk = nchunk; + maxchunk = nchunk; memory->create(ke,maxchunk,"temp/chunk:ke"); memory->create(keall,maxchunk,"temp/chunk:keall"); memory->create(count,maxchunk,"temp/chunk:count"); memory->create(countall,maxchunk,"temp/chunk:countall"); vector = keall; if (comflag) { memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(vcm); memory->destroy(vcmall); memory->create(massproc,maxchunk,"vcm/chunk:massproc"); memory->create(masstotal,maxchunk,"vcm/chunk:masstotal"); memory->create(vcm,maxchunk,3,"vcm/chunk:vcm"); memory->create(vcmall,maxchunk,3,"vcm/chunk:vcmall"); } } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputeTempChunk::memory_usage() { double bytes = (bigint) maxchunk * 2 * sizeof(double); bytes = (bigint) maxchunk * 2 * sizeof(int); if (comflag) { bytes += (bigint) maxchunk * 2 * sizeof(double); bytes += (bigint) maxchunk * 2*3 * sizeof(double); } return bytes; } diff --git a/src/compute_torque_chunk.cpp b/src/compute_torque_chunk.cpp index 8b29cc690..0568e2364 100644 --- a/src/compute_torque_chunk.cpp +++ b/src/compute_torque_chunk.cpp @@ -1,252 +1,253 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "string.h" #include "compute_torque_chunk.h" #include "atom.h" #include "update.h" #include "modify.h" #include "compute_chunk_atom.h" #include "domain.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeTorqueChunk::ComputeTorqueChunk(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg != 4) error->all(FLERR,"Illegal compute inertia/chunk command"); array_flag = 1; size_array_cols = 3; size_array_rows = 0; size_array_rows_variable = 1; extarray = 0; // ID of compute chunk/atom int n = strlen(arg[6]) + 1; idchunk = new char[n]; strcpy(idchunk,arg[6]); init(); // chunk-based data nchunk = 1; maxchunk = 0; massproc = masstotal = NULL; com = comall = NULL; torque = torqueall = NULL; allocate(); } /* ---------------------------------------------------------------------- */ ComputeTorqueChunk::~ComputeTorqueChunk() { delete [] idchunk; memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(com); memory->destroy(comall); memory->destroy(torque); memory->destroy(torqueall); } /* ---------------------------------------------------------------------- */ void ComputeTorqueChunk::init() { int icompute = modify->find_compute(idchunk); if (icompute < 0) error->all(FLERR,"Chunk/atom compute does not exist for " "compute torque/chunk"); cchunk = (ComputeChunkAtom *) modify->compute[icompute]; if (strcmp(cchunk->style,"chunk/atom") != 0) error->all(FLERR,"Compute torque/chunk does not use chunk/atom compute"); } /* ---------------------------------------------------------------------- */ void ComputeTorqueChunk::compute_array() { int i,j,index; double dx,dy,dz,massone; double unwrap[3]; invoked_array = update->ntimestep; // compute chunk/atom assigns atoms to chunk IDs // extract ichunk index vector from compute // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms nchunk = cchunk->setup_chunks(); cchunk->compute_ichunk(); int *ichunk = cchunk->ichunk; if (nchunk > maxchunk) allocate(); + size_array_rows = nchunk; // zero local per-chunk values for (int i = 0; i < nchunk; i++) { massproc[i] = 0.0; com[i][0] = com[i][1] = com[i][2] = 0.0; torque[i][0] = torque[i][1] = torque[i][2] = 0.0; } // compute COM for each chunk double **x = atom->x; int *mask = atom->mask; int *type = atom->type; imageint *image = atom->image; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; domain->unmap(x[i],image[i],unwrap); massproc[index] += massone; com[index][0] += unwrap[0] * massone; com[index][1] += unwrap[1] * massone; com[index][2] += unwrap[2] * massone; } MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&com[0][0],&comall[0][0],3*nchunk,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < nchunk; i++) { comall[i][0] /= masstotal[i]; comall[i][1] /= masstotal[i]; comall[i][2] /= masstotal[i]; } // compute torque on each chunk double **f = atom->f; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; domain->unmap(x[i],image[i],unwrap); dx = unwrap[0] - comall[index][0]; dy = unwrap[1] - comall[index][1]; dz = unwrap[2] - comall[index][2]; torque[i][0] += dy*f[i][2] - dz*f[i][1]; torque[i][1] += dz*f[i][0] - dx*f[i][2]; torque[i][2] += dx*f[i][1] - dy*f[i][0]; } MPI_Allreduce(&torque[0][0],&torqueall[0][0],3*nchunk, MPI_DOUBLE,MPI_SUM,world); } /* ---------------------------------------------------------------------- lock methods: called by fix ave/time these methods insure vector/array size is locked for Nfreq epoch by passing lock info along to compute chunk/atom ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- increment lock counter ------------------------------------------------------------------------- */ void ComputeTorqueChunk::lock_enable() { cchunk->lockcount++; } /* ---------------------------------------------------------------------- decrement lock counter in compute chunk/atom, it if still exists ------------------------------------------------------------------------- */ void ComputeTorqueChunk::lock_disable() { int icompute = modify->find_compute(idchunk); if (icompute >= 0) { cchunk = (ComputeChunkAtom *) modify->compute[icompute]; cchunk->lockcount--; } } /* ---------------------------------------------------------------------- calculate and return # of chunks = length of vector/array ------------------------------------------------------------------------- */ int ComputeTorqueChunk::lock_length() { nchunk = cchunk->setup_chunks(); return nchunk; } /* ---------------------------------------------------------------------- set the lock from startstep to stopstep ------------------------------------------------------------------------- */ void ComputeTorqueChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep) { cchunk->lock(fixptr,startstep,stopstep); } /* ---------------------------------------------------------------------- unset the lock ------------------------------------------------------------------------- */ void ComputeTorqueChunk::unlock(Fix *fixptr) { cchunk->unlock(fixptr); } /* ---------------------------------------------------------------------- free and reallocate per-chunk arrays ------------------------------------------------------------------------- */ void ComputeTorqueChunk::allocate() { memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(com); memory->destroy(comall); memory->destroy(torque); memory->destroy(torqueall); - size_array_rows = maxchunk = nchunk; + maxchunk = nchunk; memory->create(massproc,maxchunk,"torque/chunk:massproc"); memory->create(masstotal,maxchunk,"torque/chunk:masstotal"); memory->create(com,maxchunk,3,"torque/chunk:com"); memory->create(comall,maxchunk,3,"torque/chunk:comall"); memory->create(torque,maxchunk,6,"torque/chunk:torque"); memory->create(torqueall,maxchunk,6,"torque/chunk:torqueall"); array = torqueall; } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputeTorqueChunk::memory_usage() { double bytes = (bigint) maxchunk * 2 * sizeof(double); bytes += (bigint) maxchunk * 2*3 * sizeof(double); bytes += (bigint) maxchunk * 2*3 * sizeof(double); return bytes; } diff --git a/src/compute_vcm_chunk.cpp b/src/compute_vcm_chunk.cpp index 68e08c7ab..d7d7b8342 100644 --- a/src/compute_vcm_chunk.cpp +++ b/src/compute_vcm_chunk.cpp @@ -1,237 +1,238 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "string.h" #include "compute_vcm_chunk.h" #include "atom.h" #include "update.h" #include "modify.h" #include "compute_chunk_atom.h" #include "domain.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; enum{ONCE,NFREQ,EVERY}; /* ---------------------------------------------------------------------- */ ComputeVCMChunk::ComputeVCMChunk(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg != 4) error->all(FLERR,"Illegal compute vcm/chunk command"); array_flag = 1; size_array_cols = 3; size_array_rows = 0; size_array_rows_variable = 1; extarray = 0; // ID of compute chunk/atom int n = strlen(arg[6]) + 1; idchunk = new char[n]; strcpy(idchunk,arg[6]); init(); // chunk-based data nchunk = 1; maxchunk = 0; massproc = masstotal = NULL; vcm = vcmall = NULL; allocate(); firstflag = massneed = 1; } /* ---------------------------------------------------------------------- */ ComputeVCMChunk::~ComputeVCMChunk() { delete [] idchunk; memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(vcm); memory->destroy(vcmall); } /* ---------------------------------------------------------------------- */ void ComputeVCMChunk::init() { int icompute = modify->find_compute(idchunk); if (icompute < 0) error->all(FLERR,"Chunk/atom compute does not exist for compute vcm/chunk"); cchunk = (ComputeChunkAtom *) modify->compute[icompute]; if (strcmp(cchunk->style,"chunk/atom") != 0) error->all(FLERR,"Compute vcm/chunk does not use chunk/atom compute"); } /* ---------------------------------------------------------------------- */ void ComputeVCMChunk::setup() { // one-time calculation of per-chunk mass // done in setup, so that ComputeChunkAtom::setup() is already called if (firstflag && cchunk->idsflag == ONCE) { firstflag = massneed = 0; compute_array(); } } /* ---------------------------------------------------------------------- */ void ComputeVCMChunk::compute_array() { int index; double massone; invoked_array = update->ntimestep; // compute chunk/atom assigns atoms to chunk IDs // extract ichunk index vector from compute // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms nchunk = cchunk->setup_chunks(); cchunk->compute_ichunk(); int *ichunk = cchunk->ichunk; if (nchunk > maxchunk) allocate(); + size_array_rows = nchunk; // zero local per-chunk values for (int i = 0; i < nchunk; i++) vcm[i][0] = vcm[i][1] = vcm[i][2] = 0.0; if (massneed) for (int i = 0; i < nchunk; i++) massproc[i] = 0.0; // compute VCM for each chunk double **v = atom->v; int *mask = atom->mask; int *type = atom->type; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { index = ichunk[i]-1; if (index < 0) continue; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; vcm[index][0] += v[i][0] * massone; vcm[index][1] += v[i][1] * massone; vcm[index][2] += v[i][2] * massone; if (massneed) massproc[index] += massone; } MPI_Allreduce(&vcm[0][0],&vcmall[0][0],3*nchunk,MPI_DOUBLE,MPI_SUM,world); if (massneed) MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < nchunk; i++) { vcmall[i][0] /= masstotal[i]; vcmall[i][1] /= masstotal[i]; vcmall[i][2] /= masstotal[i]; } } /* ---------------------------------------------------------------------- lock methods: called by fix ave/time these methods insure vector/array size is locked for Nfreq epoch by passing lock info along to compute chunk/atom ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- increment lock counter ------------------------------------------------------------------------- */ void ComputeVCMChunk::lock_enable() { cchunk->lockcount++; } /* ---------------------------------------------------------------------- decrement lock counter in compute chunk/atom, it if still exists ------------------------------------------------------------------------- */ void ComputeVCMChunk::lock_disable() { int icompute = modify->find_compute(idchunk); if (icompute >= 0) { cchunk = (ComputeChunkAtom *) modify->compute[icompute]; cchunk->lockcount--; } } /* ---------------------------------------------------------------------- calculate and return # of chunks = length of vector/array ------------------------------------------------------------------------- */ int ComputeVCMChunk::lock_length() { nchunk = cchunk->setup_chunks(); return nchunk; } /* ---------------------------------------------------------------------- set the lock from startstep to stopstep ------------------------------------------------------------------------- */ void ComputeVCMChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep) { cchunk->lock(fixptr,startstep,stopstep); } /* ---------------------------------------------------------------------- unset the lock ------------------------------------------------------------------------- */ void ComputeVCMChunk::unlock(Fix *fixptr) { cchunk->unlock(fixptr); } /* ---------------------------------------------------------------------- free and reallocate per-chunk arrays ------------------------------------------------------------------------- */ void ComputeVCMChunk::allocate() { memory->destroy(massproc); memory->destroy(masstotal); memory->destroy(vcm); memory->destroy(vcmall); - size_array_rows = maxchunk = nchunk; + maxchunk = nchunk; memory->create(massproc,maxchunk,"vcm/chunk:massproc"); memory->create(masstotal,maxchunk,"vcm/chunk:masstotal"); memory->create(vcm,maxchunk,3,"vcm/chunk:vcm"); memory->create(vcmall,maxchunk,3,"vcm/chunk:vcmall"); array = vcmall; } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputeVCMChunk::memory_usage() { double bytes = (bigint) maxchunk * 2 * sizeof(double); bytes += (bigint) maxchunk * 2*3 * sizeof(double); return bytes; }