Introduce ComputeChunk class with shared functionality of all /chunk computes

This commit is contained in:
Axel Kohlmeyer
2023-03-18 05:55:03 -04:00
parent fce1f8e0af
commit 1ccb0f8d8d
29 changed files with 958 additions and 2050 deletions

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -22,11 +21,9 @@
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "force.h" #include "force.h"
#include "pair.h"
#include "math_special.h" #include "math_special.h"
#include "memory.h" #include "memory.h"
#include "modify.h" #include "pair.h"
#include "update.h"
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
@ -39,13 +36,10 @@ enum { MASSCENTER, GEOMCENTER };
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeDipoleTIP4PChunk::ComputeDipoleTIP4PChunk(LAMMPS *lmp, int narg, char **arg) : ComputeDipoleTIP4PChunk::ComputeDipoleTIP4PChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), ComputeChunk(lmp, narg, arg), massproc(nullptr), masstotal(nullptr), chrgproc(nullptr),
idchunk(nullptr), massproc(nullptr), masstotal(nullptr), chrgproc(nullptr), chrgtotal(nullptr), com(nullptr), comall(nullptr), dipole(nullptr), dipoleall(nullptr)
chrgtotal(nullptr), com(nullptr),
comall(nullptr), dipole(nullptr), dipoleall(nullptr)
{ {
if ((narg != 4) && (narg != 5)) if ((narg != 4) && (narg != 5)) error->all(FLERR, "Illegal compute dipole/tip4p/chunk command");
error->all(FLERR,"Illegal compute dipole/tip4p/chunk command");
array_flag = 1; array_flag = 1;
size_array_cols = 4; size_array_cols = 4;
@ -53,32 +47,25 @@ ComputeDipoleTIP4PChunk::ComputeDipoleTIP4PChunk(LAMMPS *lmp, int narg, char **a
size_array_rows_variable = 1; size_array_rows_variable = 1;
extarray = 0; extarray = 0;
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
usecenter = MASSCENTER; usecenter = MASSCENTER;
if (narg == 5) { if (narg == 5) {
if (strncmp(arg[4],"geom",4) == 0) usecenter = GEOMCENTER; if (strncmp(arg[4], "geom", 4) == 0)
else if (strcmp(arg[4],"mass") == 0) usecenter = MASSCENTER; usecenter = GEOMCENTER;
else error->all(FLERR,"Illegal compute dipole/tip4p/chunk command"); else if (strcmp(arg[4], "mass") == 0)
usecenter = MASSCENTER;
else
error->all(FLERR, "Illegal compute dipole/tip4p/chunk command");
} }
ComputeDipoleTIP4PChunk::init(); ComputeDipoleTIP4PChunk::init();
ComputeDipoleTIP4PChunk::allocate();
// chunk-based data
nchunk = 1;
maxchunk = 0;
allocate();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeDipoleTIP4PChunk::~ComputeDipoleTIP4PChunk() ComputeDipoleTIP4PChunk::~ComputeDipoleTIP4PChunk()
{ {
delete[] idchunk;
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(chrgproc); memory->destroy(chrgproc);
@ -93,14 +80,10 @@ ComputeDipoleTIP4PChunk::~ComputeDipoleTIP4PChunk()
void ComputeDipoleTIP4PChunk::init() void ComputeDipoleTIP4PChunk::init()
{ {
int icompute = modify->find_compute(idchunk); ComputeChunk::init();
if (icompute < 0)
error->all(FLERR,"Chunk/atom compute does not exist for compute dipole/tip4p/chunk");
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->compute[icompute]);
if (strcmp(cchunk->style,"chunk/atom") != 0)
error->all(FLERR,"Compute dipole/tip4p/chunk does not use chunk/atom compute");
if (!force->pair) error->all(FLERR, "Pair style must be defined for compute dipole/tip4p/chunk"); if (!force->pair)
error->all(FLERR, "A pair style must be defined for compute dipole/tip4p/chunk");
int itmp; int itmp;
double *p_qdist = (double *) force->pair->extract("qdist", itmp); double *p_qdist = (double *) force->pair->extract("qdist", itmp);
@ -134,19 +117,9 @@ void ComputeDipoleTIP4PChunk::compute_array()
double massone; double massone;
double unwrap[3]; double unwrap[3];
invoked_array = update->ntimestep; ComputeChunk::compute_array();
// 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; int *ichunk = cchunk->ichunk;
if (nchunk > maxchunk) allocate();
size_array_rows = nchunk;
// zero local per-chunk values // zero local per-chunk values
for (i = 0; i < nchunk; i++) { for (i = 0; i < nchunk; i++) {
@ -175,9 +148,12 @@ void ComputeDipoleTIP4PChunk::compute_array()
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (usecenter == MASSCENTER) { if (usecenter == MASSCENTER) {
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
} else massone = 1.0; // usecenter == GEOMCENTER else
massone = mass[type[i]];
} else
massone = 1.0; // usecenter == GEOMCENTER
domain->unmap(x[i], image[i], unwrap); domain->unmap(x[i], image[i], unwrap);
massproc[index] += massone; massproc[index] += massone;
if (atom->q_flag) chrgproc[index] += q[i]; if (atom->q_flag) chrgproc[index] += q[i];
@ -233,74 +209,18 @@ void ComputeDipoleTIP4PChunk::compute_array()
dipoleall[i][1] -= chrgtotal[i] * comall[i][1]; dipoleall[i][1] -= chrgtotal[i] * comall[i][1];
dipoleall[i][2] -= chrgtotal[i] * comall[i][2]; dipoleall[i][2] -= chrgtotal[i] * comall[i][2];
// compute total dipole moment // compute total dipole moment
dipoleall[i][3] = sqrt(square(dipoleall[i][0]) dipoleall[i][3] =
+ square(dipoleall[i][1]) sqrt(square(dipoleall[i][0]) + square(dipoleall[i][1]) + square(dipoleall[i][2]));
+ square(dipoleall[i][2]));
} }
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure vector/array size is locked for Nfreq epoch
by passing lock info along to compute chunk/atom
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
increment lock counter
------------------------------------------------------------------------- */
void ComputeDipoleTIP4PChunk::lock_enable()
{
cchunk->lockcount++;
}
/* ----------------------------------------------------------------------
decrement lock counter in compute chunk/atom, it if still exists
------------------------------------------------------------------------- */
void ComputeDipoleTIP4PChunk::lock_disable()
{
int icompute = modify->find_compute(idchunk);
if (icompute >= 0) {
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->compute[icompute]);
cchunk->lockcount--;
}
}
/* ----------------------------------------------------------------------
calculate and return # of chunks = length of vector/array
------------------------------------------------------------------------- */
int ComputeDipoleTIP4PChunk::lock_length()
{
nchunk = cchunk->setup_chunks();
return nchunk;
}
/* ----------------------------------------------------------------------
set the lock from startstep to stopstep
------------------------------------------------------------------------- */
void ComputeDipoleTIP4PChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep)
{
cchunk->lock(fixptr,startstep,stopstep);
}
/* ----------------------------------------------------------------------
unset the lock
------------------------------------------------------------------------- */
void ComputeDipoleTIP4PChunk::unlock(Fix *fixptr)
{
cchunk->unlock(fixptr);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
free and reallocate per-chunk arrays free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void ComputeDipoleTIP4PChunk::allocate() void ComputeDipoleTIP4PChunk::allocate()
{ {
ComputeChunk::allocate();
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(chrgproc); memory->destroy(chrgproc);
@ -327,7 +247,7 @@ void ComputeDipoleTIP4PChunk::allocate()
double ComputeDipoleTIP4PChunk::memory_usage() double ComputeDipoleTIP4PChunk::memory_usage()
{ {
double bytes = (bigint) maxchunk * 2 * sizeof(double); double bytes = (double) maxchunk * 2 * sizeof(double) + ComputeChunk::memory_usage();
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
bytes += (double) maxchunk * 2 * 4 * sizeof(double); bytes += (double) maxchunk * 2 * 4 * sizeof(double);
return bytes; return bytes;

View File

@ -20,31 +20,21 @@ ComputeStyle(dipole/tip4p/chunk,ComputeDipoleTIP4PChunk);
#ifndef LMP_COMPUTE_DIPOLE_TIP4P_CHUNK_H #ifndef LMP_COMPUTE_DIPOLE_TIP4P_CHUNK_H
#define LMP_COMPUTE_DIPOLE_TIP4P_CHUNK_H #define LMP_COMPUTE_DIPOLE_TIP4P_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class Fix; class Fix;
class ComputeDipoleTIP4PChunk : public Compute { class ComputeDipoleTIP4PChunk : public ComputeChunk {
public: public:
ComputeDipoleTIP4PChunk(class LAMMPS *, int, char **); ComputeDipoleTIP4PChunk(class LAMMPS *, int, char **);
~ComputeDipoleTIP4PChunk() override; ~ComputeDipoleTIP4PChunk() override;
void init() override; void init() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(Fix *, bigint, bigint) override;
void unlock(Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk, maxchunk;
char *idchunk;
class ComputeChunkAtom *cchunk;
double *massproc, *masstotal; double *massproc, *masstotal;
double *chrgproc, *chrgtotal; double *chrgproc, *chrgtotal;
double **com, **comall; double **com, **comall;
@ -55,10 +45,8 @@ class ComputeDipoleTIP4PChunk : public Compute {
double alpha; double alpha;
void find_M(int i, double *xM); void find_M(int i, double *xM);
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
#endif #endif
#endif #endif

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -67,22 +66,22 @@ ComputeGyrationShapeChunk::~ComputeGyrationShapeChunk()
void ComputeGyrationShapeChunk::init() void ComputeGyrationShapeChunk::init()
{ {
// check that the compute gyration command exist // check that the compute gyration command exist
int icompute = modify->find_compute(id_gyration_chunk);
if (icompute < 0) c_gyration_chunk = modify->get_compute_by_id(id_gyration_chunk);
error->all(FLERR,"Compute gyration/chunk ID does not exist for " if (!c_gyration_chunk)
"compute gyration/shape/chunk"); error->all(FLERR,
"Compute gyration/chunk ID {} does not exist for compute gyration/shape/chunk",
id_gyration_chunk);
// check the id_gyration_chunk corresponds really to a compute gyration/chunk command // check the id_gyration_chunk corresponds really to a compute gyration/chunk command
c_gyration_chunk = (Compute *) modify->compute[icompute];
if (strcmp(c_gyration_chunk->style, "gyration/chunk") != 0) if (strcmp(c_gyration_chunk->style, "gyration/chunk") != 0)
error->all(FLERR,"Compute gyration/shape/chunk does not point to " error->all(FLERR, "Compute {} is not of style gyration/chunk", id_gyration_chunk);
"gyration compute/chunk");
// check the compute gyration/chunk command computes the whole gyration tensor // check the compute gyration/chunk command computes the whole gyration tensor
if (c_gyration_chunk->array_flag == 0) if (c_gyration_chunk->array_flag == 0)
error->all(FLERR,"Compute gyration/chunk where gyration/shape/chunk points to " error->all(FLERR, "Compute gyration/chunk {} does not calculate the gyration tensor",
"does not calculate the gyration tensor"); id_gyration_chunk);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -108,7 +107,7 @@ void ComputeGyrationShapeChunk::compute_array()
invoked_array = update->ntimestep; invoked_array = update->ntimestep;
c_gyration_chunk->compute_array(); c_gyration_chunk->compute_array();
current_nchunks = c_gyration_chunk->size_array_rows; // how to check for the number of chunks in the gyration/chunk? current_nchunks = c_gyration_chunk->size_array_rows;
if (former_nchunks != current_nchunks) allocate(); if (former_nchunks != current_nchunks) allocate();
double **gyration_tensor = c_gyration_chunk->array; double **gyration_tensor = c_gyration_chunk->array;
@ -126,7 +125,9 @@ void ComputeGyrationShapeChunk::compute_array()
ione[1][2] = ione[2][1] = gyration_tensor[ichunk][5]; ione[1][2] = ione[2][1] = gyration_tensor[ichunk][5];
int ierror = MathEigen::jacobi3(ione, evalues, evectors); int ierror = MathEigen::jacobi3(ione, evalues, evectors);
if (ierror) error->all(FLERR, "Insufficient Jacobi rotations " if (ierror)
error->all(FLERR,
"Insufficient Jacobi rotations "
"for gyration/shape"); "for gyration/shape");
// sort the eigenvalues according to their size with bubble sort // sort the eigenvalues according to their size with bubble sort

View File

@ -18,17 +18,13 @@
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "memory.h" #include "memory.h"
#include "modify.h"
#include "update.h"
#include <cstring>
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeAngmomChunk::ComputeAngmomChunk(LAMMPS *lmp, int narg, char **arg) : ComputeAngmomChunk::ComputeAngmomChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), idchunk(nullptr), massproc(nullptr), masstotal(nullptr), com(nullptr), ComputeChunk(lmp, narg, arg), massproc(nullptr), masstotal(nullptr), com(nullptr),
comall(nullptr), angmom(nullptr), angmomall(nullptr) comall(nullptr), angmom(nullptr), angmomall(nullptr)
{ {
if (narg != 4) error->all(FLERR, "Illegal compute angmom/chunk command"); if (narg != 4) error->all(FLERR, "Illegal compute angmom/chunk command");
@ -39,24 +35,14 @@ ComputeAngmomChunk::ComputeAngmomChunk(LAMMPS *lmp, int narg, char **arg) :
size_array_rows_variable = 1; size_array_rows_variable = 1;
extarray = 0; extarray = 0;
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
ComputeAngmomChunk::init(); ComputeAngmomChunk::init();
ComputeAngmomChunk::allocate();
// chunk-based data
nchunk = 1;
maxchunk = 0;
allocate();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeAngmomChunk::~ComputeAngmomChunk() ComputeAngmomChunk::~ComputeAngmomChunk()
{ {
delete[] idchunk;
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(com); memory->destroy(com);
@ -67,35 +53,15 @@ ComputeAngmomChunk::~ComputeAngmomChunk()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void ComputeAngmomChunk::init()
{
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->get_compute_by_id(idchunk));
if (!cchunk) error->all(FLERR, "Chunk/atom compute does not exist for compute angmom/chunk");
if (strcmp(cchunk->style, "chunk/atom") != 0)
error->all(FLERR, "Compute angmom/chunk does not use chunk/atom compute");
}
/* ---------------------------------------------------------------------- */
void ComputeAngmomChunk::compute_array() void ComputeAngmomChunk::compute_array()
{ {
ComputeChunk::compute_array();
int i, index; int i, index;
double dx, dy, dz, massone; double dx, dy, dz, massone;
double unwrap[3]; 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; int *ichunk = cchunk->ichunk;
if (nchunk > maxchunk) allocate();
size_array_rows = nchunk;
// zero local per-chunk values // zero local per-chunk values
for (i = 0; i < nchunk; i++) { for (i = 0; i < nchunk; i++) {
@ -164,59 +130,6 @@ void ComputeAngmomChunk::compute_array()
MPI_Allreduce(&angmom[0][0], &angmomall[0][0], 3 * nchunk, MPI_DOUBLE, MPI_SUM, world); MPI_Allreduce(&angmom[0][0], &angmomall[0][0], 3 * nchunk, MPI_DOUBLE, MPI_SUM, world);
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure vector/array size is locked for Nfreq epoch
by passing lock info along to compute chunk/atom
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
increment lock counter
------------------------------------------------------------------------- */
void ComputeAngmomChunk::lock_enable()
{
cchunk->lockcount++;
}
/* ----------------------------------------------------------------------
decrement lock counter in compute chunk/atom, it if still exists
------------------------------------------------------------------------- */
void ComputeAngmomChunk::lock_disable()
{
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->get_compute_by_id(idchunk));
if (cchunk) cchunk->lockcount--;
}
/* ----------------------------------------------------------------------
calculate and return # of chunks = length of vector/array
------------------------------------------------------------------------- */
int ComputeAngmomChunk::lock_length()
{
nchunk = cchunk->setup_chunks();
return nchunk;
}
/* ----------------------------------------------------------------------
set the lock from startstep to stopstep
------------------------------------------------------------------------- */
void ComputeAngmomChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep)
{
cchunk->lock(fixptr, startstep, stopstep);
}
/* ----------------------------------------------------------------------
unset the lock
------------------------------------------------------------------------- */
void ComputeAngmomChunk::unlock(Fix *fixptr)
{
cchunk->unlock(fixptr);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
free and reallocate per-chunk arrays free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
@ -245,7 +158,8 @@ void ComputeAngmomChunk::allocate()
double ComputeAngmomChunk::memory_usage() double ComputeAngmomChunk::memory_usage()
{ {
double bytes = (bigint) maxchunk * 2 * sizeof(double); double bytes = ComputeChunk::memory_usage();
bytes += (bigint) maxchunk * 2 * sizeof(double);
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
return bytes; return bytes;

View File

@ -20,39 +20,25 @@ ComputeStyle(angmom/chunk,ComputeAngmomChunk);
#ifndef LMP_COMPUTE_ANGMOM_CHUNK_H #ifndef LMP_COMPUTE_ANGMOM_CHUNK_H
#define LMP_COMPUTE_ANGMOM_CHUNK_H #define LMP_COMPUTE_ANGMOM_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class Fix;
class ComputeAngmomChunk : public Compute { class ComputeAngmomChunk : public ComputeChunk {
public: public:
ComputeAngmomChunk(class LAMMPS *, int, char **); ComputeAngmomChunk(class LAMMPS *, int, char **);
~ComputeAngmomChunk() override; ~ComputeAngmomChunk() override;
void init() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(Fix *, bigint, bigint) override;
void unlock(Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk, maxchunk;
char *idchunk;
class ComputeChunkAtom *cchunk;
double *massproc, *masstotal; double *massproc, *masstotal;
double **com, **comall; double **com, **comall;
double **angmom, **angmomall; double **angmom, **angmomall;
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
#endif #endif
#endif #endif

156
src/compute_chunk.cpp Normal file
View File

@ -0,0 +1,156 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
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 "compute_chunk.h"
#include "compute_chunk_atom.h"
#include "error.h"
#include "modify.h"
#include "update.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeChunk::ComputeChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), idchunk(nullptr), cchunk(nullptr)
{
if (narg < 4) utils::missing_cmd_args(FLERR, std::string("compute ") + style, error);
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
ComputeChunk::init();
// chunk-based data
nchunk = 1;
maxchunk = 0;
firstflag = 1;
massneed = 1;
}
/* ---------------------------------------------------------------------- */
ComputeChunk::~ComputeChunk()
{
delete[] idchunk;
}
/* ---------------------------------------------------------------------- */
void ComputeChunk::init()
{
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->get_compute_by_id(idchunk));
if (!cchunk)
error->all(FLERR, "Chunk/atom compute {} does not exist or is incorrect style for compute {}",
idchunk, style);
}
/* ----------------------------------------------------------------------
common code used by all /chunk computes
------------------------------------------------------------------------- */
void ComputeChunk::compute_vector()
{
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();
if (nchunk > maxchunk) allocate();
size_vector = nchunk;
}
/* ---------------------------------------------------------------------- */
void ComputeChunk::compute_array()
{
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();
if (nchunk > maxchunk) allocate();
size_array_rows = nchunk;
}
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure vector/array size is locked for Nfreq epoch
by passing lock info along to compute chunk/atom
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
increment lock counter
------------------------------------------------------------------------- */
void ComputeChunk::lock_enable()
{
cchunk->lockcount++;
}
/* ----------------------------------------------------------------------
decrement lock counter in compute chunk/atom, it if still exists
------------------------------------------------------------------------- */
void ComputeChunk::lock_disable()
{
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->get_compute_by_id(idchunk));
if (!cchunk) cchunk->lockcount--;
}
/* ----------------------------------------------------------------------
calculate and return # of chunks = length of vector/array
------------------------------------------------------------------------- */
int ComputeChunk::lock_length()
{
nchunk = cchunk->setup_chunks();
return nchunk;
}
/* ----------------------------------------------------------------------
set the lock from startstep to stopstep
------------------------------------------------------------------------- */
void ComputeChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep)
{
cchunk->lock(fixptr, startstep, stopstep);
}
/* ----------------------------------------------------------------------
unset the lock
------------------------------------------------------------------------- */
void ComputeChunk::unlock(Fix *fixptr)
{
cchunk->unlock(fixptr);
}
/* ----------------------------------------------------------------------
memory usage of local data
------------------------------------------------------------------------- */
double ComputeChunk::memory_usage()
{
return sizeof(ComputeChunk) + sizeof(ComputeChunkAtom);
}

49
src/compute_chunk.h Normal file
View File

@ -0,0 +1,49 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
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.
------------------------------------------------------------------------- */
#ifndef LMP_COMPUTE_CHUNK_H
#define LMP_COMPUTE_CHUNK_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeChunkAtom;
class Fix;
class ComputeChunk : public Compute {
public:
char *idchunk; // fields accessed by other classes
ComputeChunk(class LAMMPS *, int, char **);
~ComputeChunk() override;
void init() override;
void compute_vector() override;
void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(Fix *, bigint, bigint) override;
void unlock(Fix *) override;
double memory_usage() override;
protected:
int nchunk, maxchunk;
int firstflag, massneed;
ComputeChunkAtom *cchunk;
virtual void allocate(){};
};
} // namespace LAMMPS_NS
#endif

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -19,10 +18,6 @@
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "memory.h" #include "memory.h"
#include "modify.h"
#include "update.h"
#include <cstring>
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -31,8 +26,8 @@ enum{ONCE,NFREQ,EVERY};
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeCOMChunk::ComputeCOMChunk(LAMMPS *lmp, int narg, char **arg) : ComputeCOMChunk::ComputeCOMChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), ComputeChunk(lmp, narg, arg), masstotal(nullptr), massproc(nullptr), com(nullptr),
idchunk(nullptr), masstotal(nullptr), massproc(nullptr), com(nullptr), comall(nullptr) comall(nullptr)
{ {
if (narg != 4) error->all(FLERR, "Illegal compute com/chunk command"); if (narg != 4) error->all(FLERR, "Illegal compute com/chunk command");
@ -42,26 +37,14 @@ ComputeCOMChunk::ComputeCOMChunk(LAMMPS *lmp, int narg, char **arg) :
size_array_rows_variable = 1; size_array_rows_variable = 1;
extarray = 0; extarray = 0;
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
ComputeCOMChunk::init(); ComputeCOMChunk::init();
ComputeCOMChunk::allocate();
// chunk-based data
nchunk = 1;
maxchunk = 0;
allocate();
firstflag = massneed = 1;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeCOMChunk::~ComputeCOMChunk() ComputeCOMChunk::~ComputeCOMChunk()
{ {
delete [] idchunk;
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(com); memory->destroy(com);
@ -70,18 +53,6 @@ ComputeCOMChunk::~ComputeCOMChunk()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
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 = dynamic_cast<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() void ComputeCOMChunk::setup()
{ {
// one-time calculation of per-chunk mass // one-time calculation of per-chunk mass
@ -101,23 +72,12 @@ void ComputeCOMChunk::compute_array()
double massone; double massone;
double unwrap[3]; double unwrap[3];
invoked_array = update->ntimestep; ComputeChunk::compute_array();
// 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; int *ichunk = cchunk->ichunk;
if (nchunk > maxchunk) allocate();
size_array_rows = nchunk;
// zero local per-chunk values // zero local per-chunk values
for (int i = 0; i < nchunk; i++) for (int i = 0; i < nchunk; i++) com[i][0] = com[i][1] = com[i][2] = 0.0;
com[i][0] = com[i][1] = com[i][2] = 0.0;
if (massneed) if (massneed)
for (int i = 0; i < nchunk; i++) massproc[i] = 0.0; for (int i = 0; i < nchunk; i++) massproc[i] = 0.0;
@ -135,8 +95,10 @@ void ComputeCOMChunk::compute_array()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
domain->unmap(x[i], image[i], unwrap); domain->unmap(x[i], image[i], unwrap);
com[index][0] += unwrap[0] * massone; com[index][0] += unwrap[0] * massone;
com[index][1] += unwrap[1] * massone; com[index][1] += unwrap[1] * massone;
@ -145,74 +107,18 @@ void ComputeCOMChunk::compute_array()
} }
MPI_Allreduce(&com[0][0], &comall[0][0], 3 * nchunk, MPI_DOUBLE, MPI_SUM, world); MPI_Allreduce(&com[0][0], &comall[0][0], 3 * nchunk, MPI_DOUBLE, MPI_SUM, world);
if (massneed) if (massneed) MPI_Allreduce(massproc, masstotal, nchunk, MPI_DOUBLE, MPI_SUM, world);
MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world);
for (int i = 0; i < nchunk; i++) { for (int i = 0; i < nchunk; i++) {
if (masstotal[i] > 0.0) { if (masstotal[i] > 0.0) {
comall[i][0] /= masstotal[i]; comall[i][0] /= masstotal[i];
comall[i][1] /= masstotal[i]; comall[i][1] /= masstotal[i];
comall[i][2] /= masstotal[i]; comall[i][2] /= masstotal[i];
} else comall[i][0] = comall[i][1] = comall[i][2] = 0.0; } else
comall[i][0] = comall[i][1] = comall[i][2] = 0.0;
} }
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure 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 = dynamic_cast<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 free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
@ -237,7 +143,8 @@ void ComputeCOMChunk::allocate()
double ComputeCOMChunk::memory_usage() double ComputeCOMChunk::memory_usage()
{ {
double bytes = (bigint) maxchunk * 2 * sizeof(double); double bytes = ComputeChunk::memory_usage();
bytes += (bigint) maxchunk * 2 * sizeof(double);
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
return bytes; return bytes;
} }

View File

@ -20,42 +20,26 @@ ComputeStyle(com/chunk,ComputeCOMChunk);
#ifndef LMP_COMPUTE_COM_CHUNK_H #ifndef LMP_COMPUTE_COM_CHUNK_H
#define LMP_COMPUTE_COM_CHUNK_H #define LMP_COMPUTE_COM_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class Fix; class ComputeCOMChunk : public ComputeChunk {
class ComputeCOMChunk : public Compute {
public: public:
char *idchunk; // fields accessed by other classes
double *masstotal; double *masstotal;
ComputeCOMChunk(class LAMMPS *, int, char **); ComputeCOMChunk(class LAMMPS *, int, char **);
~ComputeCOMChunk() override; ~ComputeCOMChunk() override;
void init() override;
void setup() override; void setup() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(Fix *, bigint, bigint) override;
void unlock(Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk, maxchunk;
int firstflag, massneed;
class ComputeChunkAtom *cchunk;
double *massproc; double *massproc;
double **com, **comall; double **com, **comall;
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
#endif #endif
#endif #endif

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -22,8 +21,6 @@
#include "force.h" #include "force.h"
#include "math_special.h" #include "math_special.h"
#include "memory.h" #include "memory.h"
#include "modify.h"
#include "update.h"
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
@ -36,13 +33,10 @@ enum { MASSCENTER, GEOMCENTER };
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeDipoleChunk::ComputeDipoleChunk(LAMMPS *lmp, int narg, char **arg) : ComputeDipoleChunk::ComputeDipoleChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), ComputeChunk(lmp, narg, arg), massproc(nullptr), masstotal(nullptr), chrgproc(nullptr),
idchunk(nullptr), massproc(nullptr), masstotal(nullptr), chrgproc(nullptr), chrgtotal(nullptr), com(nullptr), comall(nullptr), dipole(nullptr), dipoleall(nullptr)
chrgtotal(nullptr), com(nullptr),
comall(nullptr), dipole(nullptr), dipoleall(nullptr)
{ {
if ((narg != 4) && (narg != 5)) if ((narg != 4) && (narg != 5)) error->all(FLERR, "Illegal compute dipole/chunk command");
error->all(FLERR,"Illegal compute dipole/chunk command");
array_flag = 1; array_flag = 1;
size_array_cols = 4; size_array_cols = 4;
@ -50,32 +44,25 @@ ComputeDipoleChunk::ComputeDipoleChunk(LAMMPS *lmp, int narg, char **arg) :
size_array_rows_variable = 1; size_array_rows_variable = 1;
extarray = 0; extarray = 0;
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
usecenter = MASSCENTER; usecenter = MASSCENTER;
if (narg == 5) { if (narg == 5) {
if (strncmp(arg[4],"geom",4) == 0) usecenter = GEOMCENTER; if (strncmp(arg[4], "geom", 4) == 0)
else if (strcmp(arg[4],"mass") == 0) usecenter = MASSCENTER; usecenter = GEOMCENTER;
else error->all(FLERR,"Illegal compute dipole/chunk command"); else if (strcmp(arg[4], "mass") == 0)
usecenter = MASSCENTER;
else
error->all(FLERR, "Illegal compute dipole/chunk command");
} }
ComputeDipoleChunk::init(); ComputeDipoleChunk::init();
ComputeDipoleChunk::allocate();
// chunk-based data
nchunk = 1;
maxchunk = 0;
allocate();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeDipoleChunk::~ComputeDipoleChunk() ComputeDipoleChunk::~ComputeDipoleChunk()
{ {
delete [] idchunk;
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(chrgproc); memory->destroy(chrgproc);
@ -90,17 +77,10 @@ ComputeDipoleChunk::~ComputeDipoleChunk()
void ComputeDipoleChunk::init() void ComputeDipoleChunk::init()
{ {
int icompute = modify->find_compute(idchunk); ComputeChunk::init();
if (icompute < 0)
error->all(FLERR,"Chunk/atom compute does not exist for "
"compute dipole/chunk");
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->compute[icompute]);
if (strcmp(cchunk->style,"chunk/atom") != 0)
error->all(FLERR,"Compute dipole/chunk does not use chunk/atom compute");
if ((force->pair_match("/tip4p/",0) != nullptr) && (comm->me == 0)) if ((force->pair_match("tip4p/", 0) != nullptr) && (comm->me == 0))
error->warning(FLERR,"Computed dipole moments may be incorrect when " error->warning(FLERR, "Dipole moments may be incorrect when sing a TIP4P pair style");
"using a tip4p pair style");
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -111,19 +91,9 @@ void ComputeDipoleChunk::compute_array()
double massone; double massone;
double unwrap[3]; double unwrap[3];
invoked_array = update->ntimestep; ComputeChunk::compute_array();
// 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; int *ichunk = cchunk->ichunk;
if (nchunk > maxchunk) allocate();
size_array_rows = nchunk;
// zero local per-chunk values // zero local per-chunk values
for (i = 0; i < nchunk; i++) { for (i = 0; i < nchunk; i++) {
@ -150,9 +120,12 @@ void ComputeDipoleChunk::compute_array()
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (usecenter == MASSCENTER) { if (usecenter == MASSCENTER) {
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
} else massone = 1.0; // usecenter == GEOMCENTER else
massone = mass[type[i]];
} else
massone = 1.0; // usecenter == GEOMCENTER
domain->unmap(x[i], image[i], unwrap); domain->unmap(x[i], image[i], unwrap);
massproc[index] += massone; massproc[index] += massone;
@ -194,8 +167,7 @@ void ComputeDipoleChunk::compute_array()
} }
} }
MPI_Allreduce(&dipole[0][0],&dipoleall[0][0],4*nchunk, MPI_Allreduce(&dipole[0][0], &dipoleall[0][0], 4 * nchunk, MPI_DOUBLE, MPI_SUM, world);
MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < nchunk; i++) { for (i = 0; i < nchunk; i++) {
// correct for position dependence with charged chunks // correct for position dependence with charged chunks
@ -203,74 +175,17 @@ void ComputeDipoleChunk::compute_array()
dipoleall[i][1] -= chrgtotal[i] * comall[i][1]; dipoleall[i][1] -= chrgtotal[i] * comall[i][1];
dipoleall[i][2] -= chrgtotal[i] * comall[i][2]; dipoleall[i][2] -= chrgtotal[i] * comall[i][2];
// compute total dipole moment // compute total dipole moment
dipoleall[i][3] = sqrt(square(dipoleall[i][0]) dipoleall[i][3] =
+ square(dipoleall[i][1]) sqrt(square(dipoleall[i][0]) + square(dipoleall[i][1]) + square(dipoleall[i][2]));
+ square(dipoleall[i][2]));
} }
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure vector/array size is locked for Nfreq epoch
by passing lock info along to compute chunk/atom
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
increment lock counter
------------------------------------------------------------------------- */
void ComputeDipoleChunk::lock_enable()
{
cchunk->lockcount++;
}
/* ----------------------------------------------------------------------
decrement lock counter in compute chunk/atom, it if still exists
------------------------------------------------------------------------- */
void ComputeDipoleChunk::lock_disable()
{
int icompute = modify->find_compute(idchunk);
if (icompute >= 0) {
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->compute[icompute]);
cchunk->lockcount--;
}
}
/* ----------------------------------------------------------------------
calculate and return # of chunks = length of vector/array
------------------------------------------------------------------------- */
int ComputeDipoleChunk::lock_length()
{
nchunk = cchunk->setup_chunks();
return nchunk;
}
/* ----------------------------------------------------------------------
set the lock from startstep to stopstep
------------------------------------------------------------------------- */
void ComputeDipoleChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep)
{
cchunk->lock(fixptr,startstep,stopstep);
}
/* ----------------------------------------------------------------------
unset the lock
------------------------------------------------------------------------- */
void ComputeDipoleChunk::unlock(Fix *fixptr)
{
cchunk->unlock(fixptr);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
free and reallocate per-chunk arrays free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void ComputeDipoleChunk::allocate() void ComputeDipoleChunk::allocate()
{ {
ComputeChunk::allocate();
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(chrgproc); memory->destroy(chrgproc);
@ -297,7 +212,8 @@ void ComputeDipoleChunk::allocate()
double ComputeDipoleChunk::memory_usage() double ComputeDipoleChunk::memory_usage()
{ {
double bytes = (bigint) maxchunk * 2 * sizeof(double); double bytes = ComputeChunk::memory_usage();
bytes += (bigint) maxchunk * 2 * sizeof(double);
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
bytes += (double) maxchunk * 2 * 4 * sizeof(double); bytes += (double) maxchunk * 2 * 4 * sizeof(double);
return bytes; return bytes;

View File

@ -20,38 +20,28 @@ ComputeStyle(dipole/chunk,ComputeDipoleChunk);
#ifndef LMP_COMPUTE_DIPOLE_CHUNK_H #ifndef LMP_COMPUTE_DIPOLE_CHUNK_H
#define LMP_COMPUTE_DIPOLE_CHUNK_H #define LMP_COMPUTE_DIPOLE_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class Fix; class Fix;
class ComputeDipoleChunk : public Compute { class ComputeDipoleChunk : public ComputeChunk {
public: public:
ComputeDipoleChunk(class LAMMPS *, int, char **); ComputeDipoleChunk(class LAMMPS *, int, char **);
~ComputeDipoleChunk() override; ~ComputeDipoleChunk() override;
void init() override; void init() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(Fix *, bigint, bigint) override;
void unlock(Fix *) override;
double memory_usage() override; double memory_usage() override;
private: protected:
int nchunk, maxchunk;
char *idchunk;
class ComputeChunkAtom *cchunk;
double *massproc, *masstotal; double *massproc, *masstotal;
double *chrgproc, *chrgtotal; double *chrgproc, *chrgtotal;
double **com, **comall; double **com, **comall;
double **dipole, **dipoleall; double **dipole, **dipoleall;
int usecenter; int usecenter;
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -14,31 +13,23 @@
#include "compute_gyration_chunk.h" #include "compute_gyration_chunk.h"
#include <cmath>
#include <cstring>
#include "atom.h" #include "atom.h"
#include "update.h"
#include "modify.h"
#include "compute_chunk_atom.h" #include "compute_chunk_atom.h"
#include "domain.h" #include "domain.h"
#include "memory.h"
#include "error.h" #include "error.h"
#include "memory.h"
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeGyrationChunk::ComputeGyrationChunk(LAMMPS *lmp, int narg, char **arg) : ComputeGyrationChunk::ComputeGyrationChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), ComputeChunk(lmp, narg, arg), massproc(nullptr), masstotal(nullptr), com(nullptr),
idchunk(nullptr), massproc(nullptr), masstotal(nullptr), com(nullptr), comall(nullptr), comall(nullptr), rg(nullptr), rgall(nullptr), rgt(nullptr), rgtall(nullptr)
rg(nullptr), rgall(nullptr), rgt(nullptr), rgtall(nullptr)
{ {
if (narg < 4) error->all(FLERR,"Illegal compute gyration/chunk command");
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
ComputeGyrationChunk::init(); ComputeGyrationChunk::init();
// optional args // optional args
@ -49,7 +40,8 @@ ComputeGyrationChunk::ComputeGyrationChunk(LAMMPS *lmp, int narg, char **arg) :
if (strcmp(arg[iarg], "tensor") == 0) { if (strcmp(arg[iarg], "tensor") == 0) {
tensor = 1; tensor = 1;
iarg++; iarg++;
} else error->all(FLERR,"Illegal compute gyration/chunk command"); } else
error->all(FLERR, "Illegal compute gyration/chunk command");
} }
if (tensor) { if (tensor) {
@ -65,18 +57,13 @@ ComputeGyrationChunk::ComputeGyrationChunk(LAMMPS *lmp, int narg, char **arg) :
extvector = 0; extvector = 0;
} }
// chunk-based data ComputeGyrationChunk::allocate();
nchunk = 1;
maxchunk = 0;
allocate();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeGyrationChunk::~ComputeGyrationChunk() ComputeGyrationChunk::~ComputeGyrationChunk()
{ {
delete [] idchunk;
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(com); memory->destroy(com);
@ -89,26 +76,13 @@ ComputeGyrationChunk::~ComputeGyrationChunk()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
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 = dynamic_cast<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() void ComputeGyrationChunk::compute_vector()
{ {
int i, index; int i, index;
double dx, dy, dz, massone; double dx, dy, dz, massone;
double unwrap[3]; double unwrap[3];
invoked_array = update->ntimestep; ComputeChunk::compute_vector();
com_chunk(); com_chunk();
int *ichunk = cchunk->ichunk; int *ichunk = cchunk->ichunk;
@ -133,16 +107,17 @@ void ComputeGyrationChunk::compute_vector()
dx = unwrap[0] - comall[index][0]; dx = unwrap[0] - comall[index][0];
dy = unwrap[1] - comall[index][1]; dy = unwrap[1] - comall[index][1];
dz = unwrap[2] - comall[index][2]; dz = unwrap[2] - comall[index][2];
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
rg[index] += (dx * dx + dy * dy + dz * dz) * massone; rg[index] += (dx * dx + dy * dy + dz * dz) * massone;
} }
MPI_Allreduce(rg, rgall, nchunk, MPI_DOUBLE, MPI_SUM, world); MPI_Allreduce(rg, rgall, nchunk, MPI_DOUBLE, MPI_SUM, world);
for (i = 0; i < nchunk; i++) for (i = 0; i < nchunk; i++)
if (masstotal[i] > 0.0) if (masstotal[i] > 0.0) rgall[i] = sqrt(rgall[i] / masstotal[i]);
rgall[i] = sqrt(rgall[i]/masstotal[i]);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -153,7 +128,7 @@ void ComputeGyrationChunk::compute_array()
double dx, dy, dz, massone; double dx, dy, dz, massone;
double unwrap[3]; double unwrap[3];
invoked_array = update->ntimestep; ComputeChunk::compute_array();
com_chunk(); com_chunk();
int *ichunk = cchunk->ichunk; int *ichunk = cchunk->ichunk;
@ -177,8 +152,10 @@ void ComputeGyrationChunk::compute_array()
dx = unwrap[0] - comall[index][0]; dx = unwrap[0] - comall[index][0];
dy = unwrap[1] - comall[index][1]; dy = unwrap[1] - comall[index][1];
dz = unwrap[2] - comall[index][2]; dz = unwrap[2] - comall[index][2];
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
rgt[index][0] += dx * dx * massone; rgt[index][0] += dx * dx * massone;
rgt[index][1] += dy * dy * massone; rgt[index][1] += dy * dy * massone;
rgt[index][2] += dz * dz * massone; rgt[index][2] += dz * dz * massone;
@ -187,18 +164,15 @@ void ComputeGyrationChunk::compute_array()
rgt[index][5] += dy * dz * massone; rgt[index][5] += dy * dz * massone;
} }
if (nchunk) if (nchunk) MPI_Allreduce(&rgt[0][0], &rgtall[0][0], nchunk * 6, MPI_DOUBLE, MPI_SUM, world);
MPI_Allreduce(&rgt[0][0],&rgtall[0][0],nchunk*6,MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < nchunk; i++) { for (i = 0; i < nchunk; i++) {
if (masstotal[i] > 0.0) { if (masstotal[i] > 0.0) {
for (j = 0; j < 6; j++) for (j = 0; j < 6; j++) rgtall[i][j] = rgtall[i][j] / masstotal[i];
rgtall[i][j] = rgtall[i][j]/masstotal[i];
} }
} }
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
calculate per-chunk COM, used by both scalar and tensor calculate per-chunk COM, used by both scalar and tensor
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
@ -209,18 +183,8 @@ void ComputeGyrationChunk::com_chunk()
double massone; double massone;
double unwrap[3]; 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; int *ichunk = cchunk->ichunk;
if (nchunk > maxchunk) allocate();
if (tensor) size_array_rows = nchunk;
else size_vector = nchunk;
// zero local per-chunk values // zero local per-chunk values
for (int i = 0; i < nchunk; i++) { for (int i = 0; i < nchunk; i++) {
@ -242,8 +206,10 @@ void ComputeGyrationChunk::com_chunk()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
domain->unmap(x[i], image[i], unwrap); domain->unmap(x[i], image[i], unwrap);
massproc[index] += massone; massproc[index] += massone;
com[index][0] += unwrap[0] * massone; com[index][0] += unwrap[0] * massone;
@ -263,68 +229,13 @@ void ComputeGyrationChunk::com_chunk()
} }
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure 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 = dynamic_cast<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 free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void ComputeGyrationChunk::allocate() void ComputeGyrationChunk::allocate()
{ {
ComputeChunk::allocate();
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(com); memory->destroy(com);
@ -355,9 +266,12 @@ void ComputeGyrationChunk::allocate()
double ComputeGyrationChunk::memory_usage() double ComputeGyrationChunk::memory_usage()
{ {
double bytes = (bigint) maxchunk * 2 * sizeof(double); double bytes = ComputeChunk::memory_usage();
bytes += (bigint) maxchunk * 2 * sizeof(double);
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
if (tensor) bytes += (double) maxchunk * 2*6 * sizeof(double); if (tensor)
else bytes += (double) maxchunk * 2 * sizeof(double); bytes += (double) maxchunk * 2 * 6 * sizeof(double);
else
bytes += (double) maxchunk * 2 * sizeof(double);
return bytes; return bytes;
} }

View File

@ -20,31 +20,21 @@ ComputeStyle(gyration/chunk,ComputeGyrationChunk);
#ifndef LMP_COMPUTE_GYRATION_CHUNK_H #ifndef LMP_COMPUTE_GYRATION_CHUNK_H
#define LMP_COMPUTE_GYRATION_CHUNK_H #define LMP_COMPUTE_GYRATION_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class ComputeGyrationChunk : public Compute { class ComputeGyrationChunk : public ComputeChunk {
public: public:
ComputeGyrationChunk(class LAMMPS *, int, char **); ComputeGyrationChunk(class LAMMPS *, int, char **);
~ComputeGyrationChunk() override; ~ComputeGyrationChunk() override;
void init() override;
void compute_vector() override; void compute_vector() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(class Fix *, bigint, bigint) override;
void unlock(class Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk, maxchunk;
char *idchunk;
class ComputeChunkAtom *cchunk;
int tensor; int tensor;
double *massproc, *masstotal; double *massproc, *masstotal;
@ -53,7 +43,7 @@ class ComputeGyrationChunk : public Compute {
double **rgt, **rgtall; double **rgt, **rgtall;
void com_chunk(); void com_chunk();
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -14,23 +13,19 @@
#include "compute_inertia_chunk.h" #include "compute_inertia_chunk.h"
#include <cstring>
#include "atom.h" #include "atom.h"
#include "update.h"
#include "modify.h"
#include "compute_chunk_atom.h" #include "compute_chunk_atom.h"
#include "domain.h" #include "domain.h"
#include "memory.h"
#include "error.h" #include "error.h"
#include "memory.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeInertiaChunk::ComputeInertiaChunk(LAMMPS *lmp, int narg, char **arg) : ComputeInertiaChunk::ComputeInertiaChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), ComputeChunk(lmp, narg, arg), massproc(nullptr), masstotal(nullptr), com(nullptr),
idchunk(nullptr), massproc(nullptr), masstotal(nullptr), com(nullptr), comall(nullptr), comall(nullptr), inertia(nullptr), inertiaall(nullptr)
inertia(nullptr), inertiaall(nullptr)
{ {
if (narg != 4) error->all(FLERR, "Illegal compute inertia/chunk command"); if (narg != 4) error->all(FLERR, "Illegal compute inertia/chunk command");
@ -40,24 +35,14 @@ ComputeInertiaChunk::ComputeInertiaChunk(LAMMPS *lmp, int narg, char **arg) :
size_array_rows_variable = 1; size_array_rows_variable = 1;
extarray = 0; extarray = 0;
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
ComputeInertiaChunk::init(); ComputeInertiaChunk::init();
ComputeInertiaChunk::allocate();
// chunk-based data
nchunk = 1;
maxchunk = 0;
allocate();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeInertiaChunk::~ComputeInertiaChunk() ComputeInertiaChunk::~ComputeInertiaChunk()
{ {
delete [] idchunk;
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(com); memory->destroy(com);
@ -68,38 +53,15 @@ ComputeInertiaChunk::~ComputeInertiaChunk()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
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 = dynamic_cast<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() void ComputeInertiaChunk::compute_array()
{ {
int i, j, index; int i, j, index;
double dx, dy, dz, massone; double dx, dy, dz, massone;
double unwrap[3]; double unwrap[3];
invoked_array = update->ntimestep; ComputeChunk::compute_array();
// 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; int *ichunk = cchunk->ichunk;
if (nchunk > maxchunk) allocate();
size_array_rows = nchunk;
// zero local per-chunk values // zero local per-chunk values
for (i = 0; i < nchunk; i++) { for (i = 0; i < nchunk; i++) {
@ -122,8 +84,10 @@ void ComputeInertiaChunk::compute_array()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
domain->unmap(x[i], image[i], unwrap); domain->unmap(x[i], image[i], unwrap);
massproc[index] += massone; massproc[index] += massone;
com[index][0] += unwrap[0] * massone; com[index][0] += unwrap[0] * massone;
@ -148,8 +112,10 @@ void ComputeInertiaChunk::compute_array()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
domain->unmap(x[i], image[i], unwrap); domain->unmap(x[i], image[i], unwrap);
dx = unwrap[0] - comall[index][0]; dx = unwrap[0] - comall[index][0];
dy = unwrap[1] - comall[index][1]; dy = unwrap[1] - comall[index][1];
@ -162,67 +128,8 @@ void ComputeInertiaChunk::compute_array()
inertia[index][5] -= massone * dx * dz; inertia[index][5] -= massone * dx * dz;
} }
MPI_Allreduce(&inertia[0][0],&inertiaall[0][0],6*nchunk, MPI_Allreduce(&inertia[0][0], &inertiaall[0][0], 6 * nchunk, MPI_DOUBLE, MPI_SUM, world);
MPI_DOUBLE,MPI_SUM,world);
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure 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 = dynamic_cast<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 free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
@ -251,7 +158,8 @@ void ComputeInertiaChunk::allocate()
double ComputeInertiaChunk::memory_usage() double ComputeInertiaChunk::memory_usage()
{ {
double bytes = (bigint) maxchunk * 2 * sizeof(double); double bytes = ComputeChunk::memory_usage();
bytes += (bigint) maxchunk * 2 * sizeof(double);
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
bytes += (double) maxchunk * 2 * 6 * sizeof(double); bytes += (double) maxchunk * 2 * 6 * sizeof(double);
return bytes; return bytes;

View File

@ -20,38 +20,25 @@ ComputeStyle(inertia/chunk,ComputeInertiaChunk);
#ifndef LMP_COMPUTE_INERTIA_CHUNK_H #ifndef LMP_COMPUTE_INERTIA_CHUNK_H
#define LMP_COMPUTE_INERTIA_CHUNK_H #define LMP_COMPUTE_INERTIA_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class ComputeInertiaChunk : public Compute { class ComputeInertiaChunk : public ComputeChunk {
public: public:
ComputeInertiaChunk(class LAMMPS *, int, char **); ComputeInertiaChunk(class LAMMPS *, int, char **);
~ComputeInertiaChunk() override; ~ComputeInertiaChunk() override;
void init() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(class Fix *, bigint, bigint) override;
void unlock(class Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk, maxchunk;
char *idchunk;
class ComputeChunkAtom *cchunk;
double *massproc, *masstotal; double *massproc, *masstotal;
double **com, **comall; double **com, **comall;
double **inertia, **inertiaall; double **inertia, **inertiaall;
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
#endif #endif
#endif #endif

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -22,17 +21,14 @@
#include "group.h" #include "group.h"
#include "memory.h" #include "memory.h"
#include "modify.h" #include "modify.h"
#include "update.h"
#include <cstring>
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeMSDChunk::ComputeMSDChunk(LAMMPS *lmp, int narg, char **arg) : ComputeMSDChunk::ComputeMSDChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), idchunk(nullptr), id_fix(nullptr), massproc(nullptr), ComputeChunk(lmp, narg, arg), id_fix(nullptr), massproc(nullptr), masstotal(nullptr),
masstotal(nullptr), com(nullptr), comall(nullptr), msd(nullptr) com(nullptr), comall(nullptr), msd(nullptr)
{ {
if (narg != 4) error->all(FLERR, "Illegal compute msd/chunk command"); if (narg != 4) error->all(FLERR, "Illegal compute msd/chunk command");
@ -42,11 +38,6 @@ ComputeMSDChunk::ComputeMSDChunk(LAMMPS *lmp, int narg, char **arg) :
size_array_rows_variable = 1; size_array_rows_variable = 1;
extarray = 0; extarray = 0;
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
firstflag = 1;
ComputeMSDChunk::init(); ComputeMSDChunk::init();
// create a new fix STORE style for reference positions // create a new fix STORE style for reference positions
@ -70,7 +61,6 @@ ComputeMSDChunk::~ComputeMSDChunk()
if (modify->nfix) modify->delete_fix(id_fix); if (modify->nfix) modify->delete_fix(id_fix);
delete[] id_fix; delete[] id_fix;
delete[] idchunk;
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(com); memory->destroy(com);
@ -82,12 +72,7 @@ ComputeMSDChunk::~ComputeMSDChunk()
void ComputeMSDChunk::init() void ComputeMSDChunk::init()
{ {
int icompute = modify->find_compute(idchunk); ComputeChunk::init();
if (icompute < 0)
error->all(FLERR,"Chunk/atom compute does not exist for compute msd/chunk");
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->compute[icompute]);
if (strcmp(cchunk->style,"chunk/atom") != 0)
error->all(FLERR,"Compute msd/chunk does not use chunk/atom compute");
// set fix which stores reference atom coords // set fix which stores reference atom coords
// if firstflag, will be created in setup() // if firstflag, will be created in setup()
@ -132,24 +117,14 @@ void ComputeMSDChunk::compute_array()
double massone; double massone;
double unwrap[3]; double unwrap[3];
invoked_array = update->ntimestep; int oldnchunk = nchunk;
ComputeChunk::compute_array();
// 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; int *ichunk = cchunk->ichunk;
// first time call, allocate per-chunk arrays // first time call, allocate per-chunk arrays
// thereafter, require nchunk remain the same // thereafter, require nchunk remain the same
if (firstflag) { if (!firstflag && (oldnchunk != nchunk))
nchunk = n;
allocate();
size_array_rows = nchunk;
} else if (n != nchunk)
error->all(FLERR, "Compute msd/chunk nchunk is not static"); error->all(FLERR, "Compute msd/chunk nchunk is not static");
// zero local per-chunk values // zero local per-chunk values
@ -173,8 +148,10 @@ void ComputeMSDChunk::compute_array()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
domain->unmap(x[i], image[i], unwrap); domain->unmap(x[i], image[i], unwrap);
massproc[index] += massone; massproc[index] += massone;
com[index][0] += unwrap[0] * massone; com[index][0] += unwrap[0] * massone;
@ -212,68 +189,13 @@ void ComputeMSDChunk::compute_array()
} }
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure 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 = dynamic_cast<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 one-time allocate of per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void ComputeMSDChunk::allocate() void ComputeMSDChunk::allocate()
{ {
ComputeChunk::allocate();
memory->create(massproc, nchunk, "msd/chunk:massproc"); memory->create(massproc, nchunk, "msd/chunk:massproc");
memory->create(masstotal, nchunk, "msd/chunk:masstotal"); memory->create(masstotal, nchunk, "msd/chunk:masstotal");
memory->create(com, nchunk, 3, "msd/chunk:com"); memory->create(com, nchunk, 3, "msd/chunk:com");
@ -288,7 +210,8 @@ void ComputeMSDChunk::allocate()
double ComputeMSDChunk::memory_usage() double ComputeMSDChunk::memory_usage()
{ {
double bytes = (bigint) nchunk * 2 * sizeof(double); double bytes = ComputeChunk::memory_usage();
bytes += (bigint) nchunk * 2 * sizeof(double);
bytes += (double) nchunk * 2 * 3 * sizeof(double); bytes += (double) nchunk * 2 * 3 * sizeof(double);
bytes += (double) nchunk * 4 * sizeof(double); bytes += (double) nchunk * 4 * sizeof(double);
return bytes; return bytes;

View File

@ -20,11 +20,11 @@ ComputeStyle(msd/chunk,ComputeMSDChunk);
#ifndef LMP_COMPUTE_MSD_CHUNK_H #ifndef LMP_COMPUTE_MSD_CHUNK_H
#define LMP_COMPUTE_MSD_CHUNK_H #define LMP_COMPUTE_MSD_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class ComputeMSDChunk : public Compute { class ComputeMSDChunk : public ComputeChunk {
public: public:
ComputeMSDChunk(class LAMMPS *, int, char **); ComputeMSDChunk(class LAMMPS *, int, char **);
~ComputeMSDChunk() override; ~ComputeMSDChunk() override;
@ -32,27 +32,17 @@ class ComputeMSDChunk : public Compute {
void setup() override; void setup() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(class Fix *, bigint, bigint) override;
void unlock(class Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk;
char *idchunk;
class ComputeChunkAtom *cchunk;
char *id_fix; char *id_fix;
class FixStoreGlobal *fix; class FixStoreGlobal *fix;
int firstflag;
double *massproc, *masstotal; double *massproc, *masstotal;
double **com, **comall; double **com, **comall;
double **msd; double **msd;
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
#endif #endif

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -14,16 +13,13 @@
#include "compute_omega_chunk.h" #include "compute_omega_chunk.h"
#include <cstring>
#include "atom.h" #include "atom.h"
#include "update.h"
#include "modify.h"
#include "compute_chunk_atom.h" #include "compute_chunk_atom.h"
#include "domain.h" #include "domain.h"
#include "math_extra.h"
#include "math_eigen.h"
#include "memory.h"
#include "error.h" #include "error.h"
#include "math_eigen.h"
#include "math_extra.h"
#include "memory.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -32,9 +28,9 @@ using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeOmegaChunk::ComputeOmegaChunk(LAMMPS *lmp, int narg, char **arg) : ComputeOmegaChunk::ComputeOmegaChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), ComputeChunk(lmp, narg, arg), massproc(nullptr), masstotal(nullptr), com(nullptr),
idchunk(nullptr),massproc(nullptr),masstotal(nullptr),com(nullptr),comall(nullptr), comall(nullptr), inertia(nullptr), inertiaall(nullptr), angmom(nullptr), angmomall(nullptr),
inertia(nullptr),inertiaall(nullptr),angmom(nullptr),angmomall(nullptr),omega(nullptr) omega(nullptr)
{ {
if (narg != 4) error->all(FLERR, "Illegal compute omega/chunk command"); if (narg != 4) error->all(FLERR, "Illegal compute omega/chunk command");
@ -44,24 +40,14 @@ ComputeOmegaChunk::ComputeOmegaChunk(LAMMPS *lmp, int narg, char **arg) :
size_array_rows_variable = 1; size_array_rows_variable = 1;
extarray = 0; extarray = 0;
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
ComputeOmegaChunk::init(); ComputeOmegaChunk::init();
ComputeOmegaChunk::allocate();
// chunk-based data
nchunk = 1;
maxchunk = 0;
allocate();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeOmegaChunk::~ComputeOmegaChunk() ComputeOmegaChunk::~ComputeOmegaChunk()
{ {
delete [] idchunk;
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(com); memory->destroy(com);
@ -75,33 +61,13 @@ ComputeOmegaChunk::~ComputeOmegaChunk()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void ComputeOmegaChunk::init()
{
int icompute = modify->find_compute(idchunk);
if (icompute < 0)
error->all(FLERR,"Chunk/atom compute does not exist for "
"compute omega/chunk");
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->compute[icompute]);
if (strcmp(cchunk->style,"chunk/atom") != 0)
error->all(FLERR,"Compute omega/chunk does not use chunk/atom compute");
}
/* ---------------------------------------------------------------------- */
void ComputeOmegaChunk::compute_array() void ComputeOmegaChunk::compute_array()
{ {
int i, j, m, index; int i, j, m, index;
double dx, dy, dz, massone; double dx, dy, dz, massone;
double unwrap[3]; double unwrap[3];
invoked_array = update->ntimestep; ComputeChunk::compute_array();
// 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; int *ichunk = cchunk->ichunk;
if (nchunk > maxchunk) allocate(); if (nchunk > maxchunk) allocate();
@ -131,8 +97,10 @@ void ComputeOmegaChunk::compute_array()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
domain->unmap(x[i], image[i], unwrap); domain->unmap(x[i], image[i], unwrap);
massproc[index] += massone; massproc[index] += massone;
com[index][0] += unwrap[0] * massone; com[index][0] += unwrap[0] * massone;
@ -157,8 +125,10 @@ void ComputeOmegaChunk::compute_array()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
domain->unmap(x[i], image[i], unwrap); domain->unmap(x[i], image[i], unwrap);
dx = unwrap[0] - comall[index][0]; dx = unwrap[0] - comall[index][0];
dy = unwrap[1] - comall[index][1]; dy = unwrap[1] - comall[index][1];
@ -171,8 +141,7 @@ void ComputeOmegaChunk::compute_array()
inertia[index][5] -= massone * dx * dz; inertia[index][5] -= massone * dx * dz;
} }
MPI_Allreduce(&inertia[0][0],&inertiaall[0][0],6*nchunk, MPI_Allreduce(&inertia[0][0], &inertiaall[0][0], 6 * nchunk, MPI_DOUBLE, MPI_SUM, world);
MPI_DOUBLE,MPI_SUM,world);
// compute angmom for each chunk // compute angmom for each chunk
@ -186,15 +155,16 @@ void ComputeOmegaChunk::compute_array()
dx = unwrap[0] - comall[index][0]; dx = unwrap[0] - comall[index][0];
dy = unwrap[1] - comall[index][1]; dy = unwrap[1] - comall[index][1];
dz = unwrap[2] - comall[index][2]; dz = unwrap[2] - comall[index][2];
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
angmom[index][0] += massone * (dy * v[i][2] - dz * v[i][1]); angmom[index][0] += massone * (dy * v[i][2] - dz * v[i][1]);
angmom[index][1] += massone * (dz * v[i][0] - dx * v[i][2]); angmom[index][1] += massone * (dz * v[i][0] - dx * v[i][2]);
angmom[index][2] += massone * (dx * v[i][1] - dy * v[i][0]); angmom[index][2] += massone * (dx * v[i][1] - dy * v[i][0]);
} }
MPI_Allreduce(&angmom[0][0],&angmomall[0][0],3*nchunk, MPI_Allreduce(&angmom[0][0], &angmomall[0][0], 3 * nchunk, MPI_DOUBLE, MPI_SUM, world);
MPI_DOUBLE,MPI_SUM,world);
// compute omega for each chunk // compute omega for each chunk
@ -237,16 +207,12 @@ void ComputeOmegaChunk::compute_array()
invdeterminant = 1.0 / determinant; invdeterminant = 1.0 / determinant;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++) inverse[i][j] *= invdeterminant;
inverse[i][j] *= invdeterminant;
mall = &angmomall[m][0]; mall = &angmomall[m][0];
omega[m][0] = inverse[0][0]*mall[0] + inverse[0][1]*mall[1] + omega[m][0] = inverse[0][0] * mall[0] + inverse[0][1] * mall[1] + inverse[0][2] * mall[2];
inverse[0][2]*mall[2]; omega[m][1] = inverse[1][0] * mall[0] + inverse[1][1] * mall[1] + inverse[1][2] * mall[2];
omega[m][1] = inverse[1][0]*mall[0] + inverse[1][1]*mall[1] + omega[m][2] = inverse[2][0] * mall[0] + inverse[2][1] * mall[1] + inverse[2][2] * mall[2];
inverse[1][2]*mall[2];
omega[m][2] = inverse[2][0]*mall[0] + inverse[2][1]*mall[1] +
inverse[2][2]*mall[2];
// handle each (nearly) singular I matrix // handle each (nearly) singular I matrix
// due to 2-atom chunk or linear molecule // due to 2-atom chunk or linear molecule
@ -254,8 +220,7 @@ void ComputeOmegaChunk::compute_array()
} else { } else {
int ierror = MathEigen::jacobi3(ione, idiag, evectors); int ierror = MathEigen::jacobi3(ione, idiag, evectors);
if (ierror) error->all(FLERR, if (ierror) error->all(FLERR, "Insufficient Jacobi rotations for omega/chunk");
"Insufficient Jacobi rotations for omega/chunk");
ex[0] = evectors[0][0]; ex[0] = evectors[0][0];
ex[1] = evectors[1][0]; ex[1] = evectors[1][0];
@ -289,69 +254,13 @@ void ComputeOmegaChunk::compute_array()
} }
} }
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure vector/array size is locked for Nfreq epoch
by passing lock info along to compute chunk/atom
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
increment lock counter
------------------------------------------------------------------------- */
void ComputeOmegaChunk::lock_enable()
{
cchunk->lockcount++;
}
/* ----------------------------------------------------------------------
decrement lock counter in compute chunk/atom, it if still exists
------------------------------------------------------------------------- */
void ComputeOmegaChunk::lock_disable()
{
int icompute = modify->find_compute(idchunk);
if (icompute >= 0) {
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->compute[icompute]);
cchunk->lockcount--;
}
}
/* ----------------------------------------------------------------------
calculate and return # of chunks = length of vector/array
------------------------------------------------------------------------- */
int ComputeOmegaChunk::lock_length()
{
nchunk = cchunk->setup_chunks();
return nchunk;
}
/* ----------------------------------------------------------------------
set the lock from startstep to stopstep
------------------------------------------------------------------------- */
void ComputeOmegaChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep)
{
cchunk->lock(fixptr,startstep,stopstep);
}
/* ----------------------------------------------------------------------
unset the lock
------------------------------------------------------------------------- */
void ComputeOmegaChunk::unlock(Fix *fixptr)
{
cchunk->unlock(fixptr);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
free and reallocate per-chunk arrays free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void ComputeOmegaChunk::allocate() void ComputeOmegaChunk::allocate()
{ {
ComputeChunk::allocate();
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(com); memory->destroy(com);
@ -380,7 +289,8 @@ void ComputeOmegaChunk::allocate()
double ComputeOmegaChunk::memory_usage() double ComputeOmegaChunk::memory_usage()
{ {
double bytes = (bigint) maxchunk * 2 * sizeof(double); double bytes = ComputeChunk::memory_usage();
bytes += (bigint) maxchunk * 2 * sizeof(double);
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
bytes += (double) maxchunk * 2 * 6 * sizeof(double); bytes += (double) maxchunk * 2 * 6 * sizeof(double);
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);

View File

@ -20,40 +20,28 @@ ComputeStyle(omega/chunk,ComputeOmegaChunk);
#ifndef LMP_COMPUTE_OMEGA_CHUNK_H #ifndef LMP_COMPUTE_OMEGA_CHUNK_H
#define LMP_COMPUTE_OMEGA_CHUNK_H #define LMP_COMPUTE_OMEGA_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class ComputeOmegaChunk : public Compute { class ComputeOmegaChunk : public ComputeChunk {
public: public:
ComputeOmegaChunk(class LAMMPS *, int, char **); ComputeOmegaChunk(class LAMMPS *, int, char **);
~ComputeOmegaChunk() override; ~ComputeOmegaChunk() override;
void init() override;
void compute_array() override;
void lock_enable() override; void compute_array() override;
void lock_disable() override;
int lock_length() override;
void lock(class Fix *, bigint, bigint) override;
void unlock(class Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk, maxchunk;
char *idchunk;
class ComputeChunkAtom *cchunk;
double *massproc, *masstotal; double *massproc, *masstotal;
double **com, **comall; double **com, **comall;
double **inertia, **inertiaall; double **inertia, **inertiaall;
double **angmom, **angmomall; double **angmom, **angmomall;
double **omega; double **omega;
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
#endif #endif
#endif #endif

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -14,27 +13,21 @@
#include "compute_property_chunk.h" #include "compute_property_chunk.h"
#include <cstring>
#include "atom.h" #include "atom.h"
#include "update.h"
#include "modify.h"
#include "compute_chunk_atom.h" #include "compute_chunk_atom.h"
#include "memory.h"
#include "error.h" #include "error.h"
#include "memory.h"
#include <cstring>
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputePropertyChunk::ComputePropertyChunk(LAMMPS *lmp, int narg, char **arg) : ComputePropertyChunk::ComputePropertyChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), ComputeChunk(lmp, narg, arg), count_one(nullptr), count_all(nullptr)
idchunk(nullptr), count_one(nullptr), count_all(nullptr)
{ {
if (narg < 5) error->all(FLERR,"Illegal compute property/chunk command"); if (narg < 5) utils::missing_cmd_args(FLERR, "compute property/chunk", error);
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
ComputePropertyChunk::init(); ComputePropertyChunk::init();
@ -53,33 +46,25 @@ ComputePropertyChunk::ComputePropertyChunk(LAMMPS *lmp, int narg, char **arg) :
countflag = 1; countflag = 1;
} else if (strcmp(arg[iarg], "id") == 0) { } else if (strcmp(arg[iarg], "id") == 0) {
if (!cchunk->compress) if (!cchunk->compress)
error->all(FLERR,"Compute chunk/atom stores no IDs for " error->all(FLERR, "Compute chunk/atom stores no IDs for compute property/chunk");
"compute property/chunk");
pack_choice[i] = &ComputePropertyChunk::pack_id; pack_choice[i] = &ComputePropertyChunk::pack_id;
} else if (strcmp(arg[iarg], "coord1") == 0) { } else if (strcmp(arg[iarg], "coord1") == 0) {
if (cchunk->ncoord < 1) if (cchunk->ncoord < 1)
error->all(FLERR,"Compute chunk/atom stores no coord1 for " error->all(FLERR, "Compute chunk/atom stores no coord1 for compute property/chunk");
"compute property/chunk");
pack_choice[i] = &ComputePropertyChunk::pack_coord1; pack_choice[i] = &ComputePropertyChunk::pack_coord1;
} else if (strcmp(arg[iarg], "coord2") == 0) { } else if (strcmp(arg[iarg], "coord2") == 0) {
if (cchunk->ncoord < 2) if (cchunk->ncoord < 2)
error->all(FLERR,"Compute chunk/atom stores no coord2 for " error->all(FLERR, "Compute chunk/atom stores no coord2 for compute property/chunk");
"compute property/chunk");
pack_choice[i] = &ComputePropertyChunk::pack_coord2; pack_choice[i] = &ComputePropertyChunk::pack_coord2;
} else if (strcmp(arg[iarg], "coord3") == 0) { } else if (strcmp(arg[iarg], "coord3") == 0) {
if (cchunk->ncoord < 3) if (cchunk->ncoord < 3)
error->all(FLERR,"Compute chunk/atom stores no coord3 for " error->all(FLERR, "Compute chunk/atom stores no coord3 for compute property/chunk");
"compute property/chunk");
pack_choice[i] = &ComputePropertyChunk::pack_coord3; pack_choice[i] = &ComputePropertyChunk::pack_coord3;
} else error->all(FLERR, } else
"Invalid keyword in compute property/chunk command"); error->all(FLERR, "Unkown keyword {} in compute property/chunk command", arg[iarg]);
} }
// initialization ComputePropertyChunk::allocate();
nchunk = 1;
maxchunk = 0;
allocate();
if (nvalues == 1) { if (nvalues == 1) {
vector_flag = 1; vector_flag = 1;
@ -99,7 +84,6 @@ ComputePropertyChunk::ComputePropertyChunk(LAMMPS *lmp, int narg, char **arg) :
ComputePropertyChunk::~ComputePropertyChunk() ComputePropertyChunk::~ComputePropertyChunk()
{ {
delete [] idchunk;
delete[] pack_choice; delete[] pack_choice;
memory->destroy(vector); memory->destroy(vector);
memory->destroy(array); memory->destroy(array);
@ -109,36 +93,11 @@ ComputePropertyChunk::~ComputePropertyChunk()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
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 = dynamic_cast<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() void ComputePropertyChunk::compute_vector()
{ {
invoked_vector = update->ntimestep; ComputeChunk::compute_vector();
// compute chunk/atom assigns atoms to chunk IDs if (countflag) ichunk = cchunk->ichunk;
// 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 // fill vector
@ -150,98 +109,31 @@ void ComputePropertyChunk::compute_vector()
void ComputePropertyChunk::compute_array() void ComputePropertyChunk::compute_array()
{ {
invoked_array = update->ntimestep; ComputeChunk::compute_array();
// compute chunk/atom assigns atoms to chunk IDs if (countflag) ichunk = cchunk->ichunk;
// 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 // fill array
if (array) buf = &array[0][0]; if (array) buf = &array[0][0];
for (int n = 0; n < nvalues; n++) for (int n = 0; n < nvalues; n++) (this->*pack_choice[n])(n);
(this->*pack_choice[n])(n);
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure 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 = dynamic_cast<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 free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void ComputePropertyChunk::allocate() void ComputePropertyChunk::allocate()
{ {
ComputeChunk::allocate();
memory->destroy(vector); memory->destroy(vector);
memory->destroy(array); memory->destroy(array);
memory->destroy(count_one); memory->destroy(count_one);
memory->destroy(count_all); memory->destroy(count_all);
maxchunk = nchunk; maxchunk = nchunk;
if (nvalues == 1) memory->create(vector,maxchunk,"property/chunk:vector"); if (nvalues == 1)
else memory->create(array,maxchunk,nvalues,"property/chunk:array"); memory->create(vector, maxchunk, "property/chunk:vector");
else
memory->create(array, maxchunk, nvalues, "property/chunk:array");
if (countflag) { if (countflag) {
memory->create(count_one, maxchunk, "property/chunk:count_one"); memory->create(count_one, maxchunk, "property/chunk:count_one");
memory->create(count_all, maxchunk, "property/chunk:count_all"); memory->create(count_all, maxchunk, "property/chunk:count_all");
@ -254,7 +146,8 @@ void ComputePropertyChunk::allocate()
double ComputePropertyChunk::memory_usage() double ComputePropertyChunk::memory_usage()
{ {
double bytes = (bigint) nchunk * nvalues * sizeof(double); double bytes = ComputeChunk::memory_usage();
bytes += (bigint) nchunk * nvalues * sizeof(double);
if (countflag) bytes += (double) nchunk * 2 * sizeof(int); if (countflag) bytes += (double) nchunk * 2 * sizeof(int);
return bytes; return bytes;
} }

View File

@ -20,37 +20,27 @@ ComputeStyle(property/chunk,ComputePropertyChunk);
#ifndef LMP_COMPUTE_CHUNK_MOLECULE_H #ifndef LMP_COMPUTE_CHUNK_MOLECULE_H
#define LMP_COMPUTE_CHUNK_MOLECULE_H #define LMP_COMPUTE_CHUNK_MOLECULE_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class ComputePropertyChunk : public Compute { class ComputePropertyChunk : public ComputeChunk {
public: public:
ComputePropertyChunk(class LAMMPS *, int, char **); ComputePropertyChunk(class LAMMPS *, int, char **);
~ComputePropertyChunk() override; ~ComputePropertyChunk() override;
void init() override;
void compute_vector() override; void compute_vector() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(class Fix *, bigint, bigint) override;
void unlock(class Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk, maxchunk;
char *idchunk;
class ComputeChunkAtom *cchunk;
int *ichunk; int *ichunk;
int nvalues, countflag; int nvalues, countflag;
double *buf; double *buf;
int *count_one, *count_all; int *count_one, *count_all;
void allocate(); void allocate() override;
typedef void (ComputePropertyChunk::*FnPtrPack)(int); typedef void (ComputePropertyChunk::*FnPtrPack)(int);
FnPtrPack *pack_choice; // ptrs to pack functions FnPtrPack *pack_choice; // ptrs to pack functions
@ -61,8 +51,6 @@ class ComputePropertyChunk : public Compute {
void pack_coord2(int); void pack_coord2(int);
void pack_coord3(int); void pack_coord3(int);
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
#endif #endif
#endif #endif

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -37,22 +36,23 @@ enum{ SUM, MINN, MAXX };
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), idchunk(nullptr), vlocal(nullptr), vglobal(nullptr), ComputeChunk(lmp, narg, arg), vlocal(nullptr), vglobal(nullptr), alocal(nullptr),
alocal(nullptr), aglobal(nullptr), varatom(nullptr), cchunk(nullptr), ichunk(nullptr) aglobal(nullptr), varatom(nullptr), ichunk(nullptr)
{ {
if (narg < 6) utils::missing_cmd_args(FLERR, "compute reduce/chunk", error); if (narg < 6) utils::missing_cmd_args(FLERR, "compute reduce/chunk", error);
// ID of compute chunk/atom ComputeChunk::init();
idchunk = utils::strdup(arg[3]);
init_chunk();
// mode // mode
if (strcmp(arg[4],"sum") == 0) mode = SUM; if (strcmp(arg[4], "sum") == 0)
else if (strcmp(arg[4],"min") == 0) mode = MINN; mode = SUM;
else if (strcmp(arg[4],"max") == 0) mode = MAXX; else if (strcmp(arg[4], "min") == 0)
else error->all(FLERR,"Unknown compute reduce/chunk mode: {}", arg[4]); mode = MINN;
else if (strcmp(arg[4], "max") == 0)
mode = MAXX;
else
error->all(FLERR, "Unknown compute reduce/chunk mode: {}", arg[4]);
int iarg = 5; int iarg = 5;
@ -116,9 +116,11 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) :
if (!val.val.f->peratom_flag) if (!val.val.f->peratom_flag)
error->all(FLERR, "Compute reduce/chunk fix {} does not calculate per-atom values", val.id); error->all(FLERR, "Compute reduce/chunk fix {} does not calculate per-atom values", val.id);
if ((val.argindex == 0) && (val.val.f->size_peratom_cols != 0)) if ((val.argindex == 0) && (val.val.f->size_peratom_cols != 0))
error->all(FLERR,"Compute reduce/chunk fix {} does not calculate a per-atom vector", val.id); error->all(FLERR, "Compute reduce/chunk fix {} does not calculate a per-atom vector",
val.id);
if (val.argindex && (val.val.f->size_peratom_cols == 0)) if (val.argindex && (val.val.f->size_peratom_cols == 0))
error->all(FLERR,"Compute reduce/chunk fix {} does not calculate a per-atom array", val.id); error->all(FLERR, "Compute reduce/chunk fix {} does not calculate a per-atom array",
val.id);
if (val.argindex && (val.argindex > val.val.f->size_peratom_cols)) if (val.argindex && (val.argindex > val.val.f->size_peratom_cols))
error->all(FLERR, "Compute reduce/chunk fix {} array is accessed out-of-range", val.id); error->all(FLERR, "Compute reduce/chunk fix {} array is accessed out-of-range", val.id);
@ -146,11 +148,13 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) :
// setup // setup
if (mode == SUM) initvalue = 0.0; if (mode == SUM)
else if (mode == MINN) initvalue = BIG; initvalue = 0.0;
else if (mode == MAXX) initvalue = -BIG; else if (mode == MINN)
initvalue = BIG;
else if (mode == MAXX)
initvalue = -BIG;
maxchunk = 0;
vlocal = vglobal = nullptr; vlocal = vglobal = nullptr;
alocal = aglobal = nullptr; alocal = aglobal = nullptr;
@ -162,8 +166,6 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) :
ComputeReduceChunk::~ComputeReduceChunk() ComputeReduceChunk::~ComputeReduceChunk()
{ {
delete[] idchunk;
memory->destroy(vlocal); memory->destroy(vlocal);
memory->destroy(vglobal); memory->destroy(vglobal);
memory->destroy(alocal); memory->destroy(alocal);
@ -176,7 +178,7 @@ ComputeReduceChunk::~ComputeReduceChunk()
void ComputeReduceChunk::init() void ComputeReduceChunk::init()
{ {
init_chunk(); ComputeChunk::init();
// set indices of all computes,fixes,variables // set indices of all computes,fixes,variables
@ -201,31 +203,12 @@ void ComputeReduceChunk::init()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void ComputeReduceChunk::init_chunk()
{
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->get_compute_by_id(idchunk));
if (!cchunk)
error->all(FLERR,"Compute chunk/atom {} does not exist or is incorrect style for "
"compute reduce/chunk", idchunk);
}
/* ---------------------------------------------------------------------- */
void ComputeReduceChunk::compute_vector() void ComputeReduceChunk::compute_vector()
{ {
invoked_vector = update->ntimestep; ComputeChunk::compute_vector();
// 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();
ichunk = cchunk->ichunk; ichunk = cchunk->ichunk;
if (!nchunk) return; if (!nchunk) return;
size_vector = nchunk;
if (nchunk > maxchunk) { if (nchunk > maxchunk) {
memory->destroy(vlocal); memory->destroy(vlocal);
memory->destroy(vglobal); memory->destroy(vglobal);
@ -253,19 +236,10 @@ void ComputeReduceChunk::compute_vector()
void ComputeReduceChunk::compute_array() void ComputeReduceChunk::compute_array()
{ {
invoked_array = update->ntimestep; ComputeChunk::compute_array();
// 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();
ichunk = cchunk->ichunk; ichunk = cchunk->ichunk;
if (!nchunk) return; if (!nchunk) return;
size_array_rows = nchunk;
if (nchunk > maxchunk) { if (nchunk > maxchunk) {
memory->destroy(alocal); memory->destroy(alocal);
memory->destroy(aglobal); memory->destroy(aglobal);
@ -282,11 +256,14 @@ void ComputeReduceChunk::compute_array()
// reduce the per-chunk values across all procs // reduce the per-chunk values across all procs
if (mode == SUM) if (mode == SUM)
MPI_Allreduce(&alocal[0][0],&aglobal[0][0],nchunk*values.size(),MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&alocal[0][0], &aglobal[0][0], nchunk * values.size(), MPI_DOUBLE, MPI_SUM,
world);
else if (mode == MINN) else if (mode == MINN)
MPI_Allreduce(&alocal[0][0],&aglobal[0][0],nchunk*values.size(),MPI_DOUBLE,MPI_MIN,world); MPI_Allreduce(&alocal[0][0], &aglobal[0][0], nchunk * values.size(), MPI_DOUBLE, MPI_MIN,
world);
else if (mode == MAXX) else if (mode == MAXX)
MPI_Allreduce(&alocal[0][0],&aglobal[0][0],nchunk*values.size(),MPI_DOUBLE,MPI_MAX,world); MPI_Allreduce(&alocal[0][0], &aglobal[0][0], nchunk * values.size(), MPI_DOUBLE, MPI_MAX,
world);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -386,7 +363,8 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride)
void ComputeReduceChunk::combine(double &one, double two) void ComputeReduceChunk::combine(double &one, double two)
{ {
if (mode == SUM) one += two; if (mode == SUM)
one += two;
else if (mode == MINN) { else if (mode == MINN) {
if (two < one) one = two; if (two < one) one = two;
} else if (mode == MAXX) { } else if (mode == MAXX) {
@ -394,67 +372,16 @@ void ComputeReduceChunk::combine(double &one, double two)
} }
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure vector/array size is locked for Nfreq epoch
by passing lock info along to compute chunk/atom
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
increment lock counter
------------------------------------------------------------------------- */
void ComputeReduceChunk::lock_enable()
{
cchunk->lockcount++;
}
/* ----------------------------------------------------------------------
decrement lock counter in compute chunk/atom, if it still exists
------------------------------------------------------------------------- */
void ComputeReduceChunk::lock_disable()
{
cchunk = dynamic_cast<ComputeChunkAtom *>(modify->get_compute_by_id(idchunk));
if (cchunk) cchunk->lockcount--;
}
/* ----------------------------------------------------------------------
calculate and return # of chunks = length of vector/array
------------------------------------------------------------------------- */
int ComputeReduceChunk::lock_length()
{
nchunk = cchunk->setup_chunks();
return nchunk;
}
/* ----------------------------------------------------------------------
set the lock from startstep to stopstep
------------------------------------------------------------------------- */
void ComputeReduceChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep)
{
cchunk->lock(fixptr,startstep,stopstep);
}
/* ----------------------------------------------------------------------
unset the lock
------------------------------------------------------------------------- */
void ComputeReduceChunk::unlock(Fix *fixptr)
{
cchunk->unlock(fixptr);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
memory usage of local data memory usage of local data
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
double ComputeReduceChunk::memory_usage() double ComputeReduceChunk::memory_usage()
{ {
double bytes = (bigint) maxatom * sizeof(double); double bytes = (double) maxatom * sizeof(double) + ComputeChunk::memory_usage();
if (values.size() == 1) bytes += (double) maxchunk * 2 * sizeof(double); if (values.size() == 1)
else bytes += (double) maxchunk * values.size() * 2 * sizeof(double); bytes += (double) maxchunk * 2 * sizeof(double);
else
bytes += (double) maxchunk * values.size() * 2 * sizeof(double);
return bytes; return bytes;
} }

View File

@ -20,11 +20,11 @@ ComputeStyle(reduce/chunk,ComputeReduceChunk);
#ifndef LMP_COMPUTE_REDUCE_CHUNK_H #ifndef LMP_COMPUTE_REDUCE_CHUNK_H
#define LMP_COMPUTE_REDUCE_CHUNK_H #define LMP_COMPUTE_REDUCE_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class ComputeReduceChunk : public Compute { class ComputeReduceChunk : public ComputeChunk {
public: public:
ComputeReduceChunk(class LAMMPS *, int, char **); ComputeReduceChunk(class LAMMPS *, int, char **);
~ComputeReduceChunk() override; ~ComputeReduceChunk() override;
@ -32,12 +32,6 @@ class ComputeReduceChunk : public Compute {
void compute_vector() override; void compute_vector() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(class Fix *, bigint, bigint) override;
void unlock(class Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
@ -53,19 +47,14 @@ class ComputeReduceChunk : public Compute {
}; };
std::vector<value_t> values; std::vector<value_t> values;
char *idchunk; int mode, maxatom;
int mode, nchunk;
int maxchunk, maxatom;
double initvalue; double initvalue;
double *vlocal, *vglobal; double *vlocal, *vglobal;
double **alocal, **aglobal; double **alocal, **aglobal;
double *varatom; double *varatom;
class ComputeChunkAtom *cchunk;
int *ichunk; int *ichunk;
void init_chunk();
void compute_one(int, double *, int); void compute_one(int, double *, int);
void combine(double &, double); void combine(double &, double);
}; };

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -32,22 +31,16 @@ enum{TEMP,KECOM,INTERNAL};
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeTempChunk::ComputeTempChunk(LAMMPS *lmp, int narg, char **arg) : ComputeTempChunk::ComputeTempChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), ComputeChunk(lmp, narg, arg), which(nullptr), id_bias(nullptr), sum(nullptr), sumall(nullptr),
which(nullptr), idchunk(nullptr), id_bias(nullptr), sum(nullptr), sumall(nullptr), count(nullptr), count(nullptr), countall(nullptr), massproc(nullptr), masstotal(nullptr), vcm(nullptr),
countall(nullptr), massproc(nullptr), masstotal(nullptr), vcm(nullptr), vcmall(nullptr) vcmall(nullptr)
{ {
if (narg < 4) error->all(FLERR,"Illegal compute temp/chunk command");
scalar_flag = vector_flag = 1; scalar_flag = vector_flag = 1;
size_vector = 6; size_vector = 6;
extscalar = 0; extscalar = 0;
extvector = 1; extvector = 1;
tempflag = 1; tempflag = 1;
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
biasflag = 0; biasflag = 0;
ComputeTempChunk::init(); ComputeTempChunk::init();
@ -59,10 +52,14 @@ ComputeTempChunk::ComputeTempChunk(LAMMPS *lmp, int narg, char **arg) :
int iarg = 4; int iarg = 4;
while (iarg < narg) { while (iarg < narg) {
if (strcmp(arg[iarg],"temp") == 0) which[nvalues] = TEMP; if (strcmp(arg[iarg], "temp") == 0)
else if (strcmp(arg[iarg],"kecom") == 0) which[nvalues] = KECOM; which[nvalues] = TEMP;
else if (strcmp(arg[iarg],"internal") == 0) which[nvalues] = INTERNAL; else if (strcmp(arg[iarg], "kecom") == 0)
else break; which[nvalues] = KECOM;
else if (strcmp(arg[iarg], "internal") == 0)
which[nvalues] = INTERNAL;
else
break;
iarg++; iarg++;
nvalues++; nvalues++;
} }
@ -93,20 +90,18 @@ ComputeTempChunk::ComputeTempChunk(LAMMPS *lmp, int narg, char **arg) :
if (iarg + 2 > narg) error->all(FLERR, "Illegal compute temp/chunk command"); if (iarg + 2 > narg) error->all(FLERR, "Illegal compute temp/chunk command");
cdof = utils::numeric(FLERR, arg[iarg + 1], false, lmp); cdof = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
iarg += 2; iarg += 2;
} else error->all(FLERR,"Illegal compute temp/chunk command"); } else
error->all(FLERR, "Illegal compute temp/chunk command");
} }
// error check on bias compute // error check on bias compute
if (biasflag) { if (biasflag) {
int i = modify->find_compute(id_bias); tbias = modify->get_compute_by_id(id_bias);
if (i < 0) if (!tbias) error->all(FLERR, "Could not find compute {} for temperature bias", id_bias);
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->tempflag == 0) if (tbias->tempbias == 0) error->all(FLERR, "Bias compute does not calculate a velocity bias");
error->all(FLERR,"Bias compute does not calculate temperature");
if (tbias->tempbias == 0)
error->all(FLERR,"Bias compute does not calculate a velocity bias");
} }
// this compute only calculates a bias, if comflag is set // this compute only calculates a bias, if comflag is set
@ -120,11 +115,6 @@ ComputeTempChunk::ComputeTempChunk(LAMMPS *lmp, int narg, char **arg) :
vector = new double[size_vector]; vector = new double[size_vector];
// chunk-based data
nchunk = 1;
maxchunk = 0;
if (nvalues) { if (nvalues) {
array_flag = 1; array_flag = 1;
size_array_cols = nvalues; size_array_cols = nvalues;
@ -133,7 +123,7 @@ ComputeTempChunk::ComputeTempChunk(LAMMPS *lmp, int narg, char **arg) :
extarray = 0; extarray = 0;
} }
allocate(); ComputeTempChunk::allocate();
comstep = -1; comstep = -1;
} }
@ -141,7 +131,6 @@ ComputeTempChunk::ComputeTempChunk(LAMMPS *lmp, int narg, char **arg) :
ComputeTempChunk::~ComputeTempChunk() ComputeTempChunk::~ComputeTempChunk()
{ {
delete [] idchunk;
delete[] which; delete[] which;
delete[] id_bias; delete[] id_bias;
delete[] vector; delete[] vector;
@ -160,19 +149,11 @@ ComputeTempChunk::~ComputeTempChunk()
void ComputeTempChunk::init() void ComputeTempChunk::init()
{ {
int icompute = modify->find_compute(idchunk); ComputeChunk::init();
if (icompute < 0)
error->all(FLERR,"Chunk/atom compute does not exist for "
"compute temp/chunk");
cchunk = dynamic_cast<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) { if (biasflag) {
int i = modify->find_compute(id_bias); tbias = modify->get_compute_by_id(id_bias);
if (i < 0) if (!tbias) error->all(FLERR, "Could not find compute ID {} for temperature bias", id_bias);
error->all(FLERR,"Could not find compute ID for temperature bias");
tbias = modify->compute[i];
} }
} }
@ -226,8 +207,7 @@ double ComputeTempChunk::compute_scalar()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * t += (v[i][0] * v[i][0] + v[i][1] * v[i][1] + v[i][2] * v[i][2]) * rmass[i];
rmass[i];
mycount++; mycount++;
} }
} else { } else {
@ -235,8 +215,7 @@ double ComputeTempChunk::compute_scalar()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * t += (v[i][0] * v[i][0] + v[i][1] * v[i][1] + v[i][2] * v[i][2]) * mass[type[i]];
mass[type[i]];
mycount++; mycount++;
} }
} }
@ -282,8 +261,7 @@ double ComputeTempChunk::compute_scalar()
double dof = nchunk * cdof + adof * allcount; double dof = nchunk * cdof + adof * allcount;
double tfactor = 0.0; double tfactor = 0.0;
if (dof > 0.0) tfactor = force->mvv2e / (dof * force->boltz); if (dof > 0.0) tfactor = force->mvv2e / (dof * force->boltz);
if (dof < 0.0 && allcount > 0.0) if (dof < 0.0 && allcount > 0.0) error->all(FLERR, "Temperature compute degrees of freedom < 0");
error->all(FLERR,"Temperature compute degrees of freedom < 0");
scalar *= tfactor; scalar *= tfactor;
return scalar; return scalar;
} }
@ -294,20 +272,9 @@ void ComputeTempChunk::compute_vector()
{ {
int i, index; int i, index;
invoked_vector = update->ntimestep; ComputeChunk::compute_vector();
// calculate chunk assignments,
// since only atoms in chunks contribute to global temperature
// 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; int *ichunk = cchunk->ichunk;
if (nchunk > maxchunk) allocate();
// remove velocity bias // remove velocity bias
if (biasflag) { if (biasflag) {
@ -337,8 +304,10 @@ void ComputeTempChunk::compute_vector()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
t[0] += massone * v[i][0] * v[i][0]; t[0] += massone * v[i][0] * v[i][0];
t[1] += massone * v[i][1] * v[i][1]; t[1] += massone * v[i][1] * v[i][1];
t[2] += massone * v[i][2] * v[i][2]; t[2] += massone * v[i][2] * v[i][2];
@ -352,8 +321,10 @@ void ComputeTempChunk::compute_vector()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
vx = v[i][0] - vcmall[index][0]; vx = v[i][0] - vcmall[index][0];
vy = v[i][1] - vcmall[index][1]; vy = v[i][1] - vcmall[index][1];
vz = v[i][2] - vcmall[index][2]; vz = v[i][2] - vcmall[index][2];
@ -380,17 +351,7 @@ void ComputeTempChunk::compute_vector()
void ComputeTempChunk::compute_array() void ComputeTempChunk::compute_array()
{ {
invoked_array = update->ntimestep; ComputeChunk::compute_array();
// 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();
if (nchunk > maxchunk) allocate();
size_array_rows = nchunk;
// remove velocity bias // remove velocity bias
@ -409,9 +370,12 @@ void ComputeTempChunk::compute_array()
// compute each value // compute each value
for (int i = 0; i < nvalues; i++) { for (int i = 0; i < nvalues; i++) {
if (which[i] == TEMP) temperature(i); if (which[i] == TEMP)
else if (which[i] == KECOM) kecom(i); temperature(i);
else if (which[i] == INTERNAL) internal(i); else if (which[i] == KECOM)
kecom(i);
else if (which[i] == INTERNAL)
internal(i);
} }
// restore velocity bias // restore velocity bias
@ -450,8 +414,10 @@ void ComputeTempChunk::vcm_compute()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
vcm[index][0] += v[i][0] * massone; vcm[index][0] += v[i][0] * massone;
vcm[index][1] += v[i][1] * massone; vcm[index][1] += v[i][1] * massone;
vcm[index][2] += v[i][2] * massone; vcm[index][2] += v[i][2] * massone;
@ -503,8 +469,7 @@ void ComputeTempChunk::temperature(int icol)
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
sum[index] += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * sum[index] += (v[i][0] * v[i][0] + v[i][1] * v[i][1] + v[i][2] * v[i][2]) * rmass[i];
rmass[i];
count[index]++; count[index]++;
} }
} else { } else {
@ -512,8 +477,7 @@ void ComputeTempChunk::temperature(int icol)
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
sum[index] += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * sum[index] += (v[i][0] * v[i][0] + v[i][1] * v[i][1] + v[i][2] * v[i][2]) * mass[type[i]];
mass[type[i]];
count[index]++; count[index]++;
} }
} }
@ -558,8 +522,10 @@ void ComputeTempChunk::temperature(int icol)
for (i = 0; i < nchunk; i++) { for (i = 0; i < nchunk; i++) {
dof = cdof + adof * countall[i]; dof = cdof + adof * countall[i];
if (dof > 0.0) tfactor = mvv2e / (dof * boltz); if (dof > 0.0)
else tfactor = 0.0; tfactor = mvv2e / (dof * boltz);
else
tfactor = 0.0;
array[i][icol] = tfactor * sumall[i]; array[i][icol] = tfactor * sumall[i];
} }
} }
@ -613,9 +579,7 @@ void ComputeTempChunk::kecom(int icol)
MPI_Allreduce(sum, sumall, nchunk, MPI_DOUBLE, MPI_SUM, world); MPI_Allreduce(sum, sumall, nchunk, MPI_DOUBLE, MPI_SUM, world);
double mvv2e = force->mvv2e; double mvv2e = force->mvv2e;
for (int i = 0; i < nchunk; i++) for (int i = 0; i < nchunk; i++) array[i][icol] = 0.5 * mvv2e * sumall[i];
array[i][icol] = 0.5 * mvv2e * sumall[i];
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -669,8 +633,7 @@ void ComputeTempChunk::internal(int icol)
MPI_Allreduce(sum, sumall, nchunk, MPI_DOUBLE, MPI_SUM, world); MPI_Allreduce(sum, sumall, nchunk, MPI_DOUBLE, MPI_SUM, world);
double mvv2e = force->mvv2e; double mvv2e = force->mvv2e;
for (int i = 0; i < nchunk; i++) for (int i = 0; i < nchunk; i++) array[i][icol] = 0.5 * mvv2e * sumall[i];
array[i][icol] = 0.5 * mvv2e * sumall[i];
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -751,68 +714,13 @@ void ComputeTempChunk::restore_bias_all()
} }
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure 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 = dynamic_cast<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 free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void ComputeTempChunk::allocate() void ComputeTempChunk::allocate()
{ {
ComputeChunk::allocate();
memory->destroy(sum); memory->destroy(sum);
memory->destroy(sumall); memory->destroy(sumall);
memory->destroy(count); memory->destroy(count);
@ -843,7 +751,7 @@ void ComputeTempChunk::allocate()
double ComputeTempChunk::memory_usage() double ComputeTempChunk::memory_usage()
{ {
double bytes = (bigint) maxchunk * 2 * sizeof(double); double bytes = (double) maxchunk * 2 * sizeof(double) + ComputeChunk::memory_usage();
bytes += (double) maxchunk * 2 * sizeof(int); bytes += (double) maxchunk * 2 * sizeof(int);
bytes += (double) maxchunk * nvalues * sizeof(double); bytes += (double) maxchunk * nvalues * sizeof(double);
if (comflag || nvalues) { if (comflag || nvalues) {

View File

@ -20,11 +20,11 @@ ComputeStyle(temp/chunk,ComputeTempChunk);
#ifndef LMP_COMPUTE_TEMP_CHUNK_H #ifndef LMP_COMPUTE_TEMP_CHUNK_H
#define LMP_COMPUTE_TEMP_CHUNK_H #define LMP_COMPUTE_TEMP_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class ComputeTempChunk : public Compute { class ComputeTempChunk : public ComputeChunk {
public: public:
ComputeTempChunk(class LAMMPS *, int, char **); ComputeTempChunk(class LAMMPS *, int, char **);
~ComputeTempChunk() override; ~ComputeTempChunk() override;
@ -38,20 +38,12 @@ class ComputeTempChunk : public Compute {
void restore_bias(int, double *) override; void restore_bias(int, double *) override;
void restore_bias_all() override; void restore_bias_all() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(class Fix *, bigint, bigint) override;
void unlock(class Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk, maxchunk, comflag, biasflag; int comflag, biasflag;
int nvalues; int nvalues;
int *which; int *which;
char *idchunk;
class ComputeChunkAtom *cchunk;
double adof, cdof; double adof, cdof;
char *id_bias; char *id_bias;
class Compute *tbias; // ptr to additional bias compute class Compute *tbias; // ptr to additional bias compute
@ -66,10 +58,8 @@ class ComputeTempChunk : public Compute {
void temperature(int); void temperature(int);
void kecom(int); void kecom(int);
void internal(int); void internal(int);
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
#endif #endif
#endif #endif

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -14,22 +13,19 @@
#include "compute_torque_chunk.h" #include "compute_torque_chunk.h"
#include <cstring>
#include "atom.h" #include "atom.h"
#include "update.h"
#include "modify.h"
#include "compute_chunk_atom.h" #include "compute_chunk_atom.h"
#include "domain.h" #include "domain.h"
#include "memory.h"
#include "error.h" #include "error.h"
#include "memory.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeTorqueChunk::ComputeTorqueChunk(LAMMPS *lmp, int narg, char **arg) : ComputeTorqueChunk::ComputeTorqueChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), ComputeChunk(lmp, narg, arg), massproc(nullptr), masstotal(nullptr), com(nullptr),
idchunk(nullptr), massproc(nullptr), masstotal(nullptr), com(nullptr), comall(nullptr), torque(nullptr), torqueall(nullptr) comall(nullptr), torque(nullptr), torqueall(nullptr)
{ {
if (narg != 4) error->all(FLERR, "Illegal compute torque/chunk command"); if (narg != 4) error->all(FLERR, "Illegal compute torque/chunk command");
@ -39,24 +35,14 @@ ComputeTorqueChunk::ComputeTorqueChunk(LAMMPS *lmp, int narg, char **arg) :
size_array_rows_variable = 1; size_array_rows_variable = 1;
extarray = 0; extarray = 0;
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
ComputeTorqueChunk::init(); ComputeTorqueChunk::init();
ComputeTorqueChunk::allocate();
// chunk-based data
nchunk = 1;
maxchunk = 0;
allocate();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeTorqueChunk::~ComputeTorqueChunk() ComputeTorqueChunk::~ComputeTorqueChunk()
{ {
delete [] idchunk;
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(com); memory->destroy(com);
@ -67,38 +53,15 @@ ComputeTorqueChunk::~ComputeTorqueChunk()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
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 = dynamic_cast<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() void ComputeTorqueChunk::compute_array()
{ {
int i, index; int i, index;
double dx, dy, dz, massone; double dx, dy, dz, massone;
double unwrap[3]; double unwrap[3];
invoked_array = update->ntimestep; ComputeChunk::compute_array();
// 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; int *ichunk = cchunk->ichunk;
if (nchunk > maxchunk) allocate();
size_array_rows = nchunk;
// zero local per-chunk values // zero local per-chunk values
for (i = 0; i < nchunk; i++) { for (i = 0; i < nchunk; i++) {
@ -121,8 +84,10 @@ void ComputeTorqueChunk::compute_array()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
domain->unmap(x[i], image[i], unwrap); domain->unmap(x[i], image[i], unwrap);
massproc[index] += massone; massproc[index] += massone;
com[index][0] += unwrap[0] * massone; com[index][0] += unwrap[0] * massone;
@ -158,72 +123,15 @@ void ComputeTorqueChunk::compute_array()
torque[index][2] += dx * f[i][1] - dy * f[i][0]; torque[index][2] += dx * f[i][1] - dy * f[i][0];
} }
MPI_Allreduce(&torque[0][0],&torqueall[0][0],3*nchunk, MPI_Allreduce(&torque[0][0], &torqueall[0][0], 3 * nchunk, MPI_DOUBLE, MPI_SUM, world);
MPI_DOUBLE,MPI_SUM,world);
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure 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 = dynamic_cast<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 free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void ComputeTorqueChunk::allocate() void ComputeTorqueChunk::allocate()
{ {
ComputeChunk::allocate();
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(com); memory->destroy(com);
@ -246,7 +154,7 @@ void ComputeTorqueChunk::allocate()
double ComputeTorqueChunk::memory_usage() double ComputeTorqueChunk::memory_usage()
{ {
double bytes = (bigint) maxchunk * 2 * sizeof(double); double bytes = (double) maxchunk * 2 * sizeof(double) + ComputeChunk::memory_usage();
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
return bytes; return bytes;

View File

@ -20,35 +20,24 @@ ComputeStyle(torque/chunk,ComputeTorqueChunk);
#ifndef LMP_COMPUTE_TORQUE_CHUNK_H #ifndef LMP_COMPUTE_TORQUE_CHUNK_H
#define LMP_COMPUTE_TORQUE_CHUNK_H #define LMP_COMPUTE_TORQUE_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class ComputeTorqueChunk : public Compute { class ComputeTorqueChunk : public ComputeChunk {
public: public:
ComputeTorqueChunk(class LAMMPS *, int, char **); ComputeTorqueChunk(class LAMMPS *, int, char **);
~ComputeTorqueChunk() override; ~ComputeTorqueChunk() override;
void init() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(class Fix *, bigint, bigint) override;
void unlock(class Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk, maxchunk;
char *idchunk;
class ComputeChunkAtom *cchunk;
double *massproc, *masstotal; double *massproc, *masstotal;
double **com, **comall; double **com, **comall;
double **torque, **torqueall; double **torque, **torqueall;
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS

View File

@ -1,4 +1,3 @@
// clang-format off
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories https://www.lammps.org/, Sandia National Laboratories
@ -14,13 +13,10 @@
#include "compute_vcm_chunk.h" #include "compute_vcm_chunk.h"
#include <cstring>
#include "atom.h" #include "atom.h"
#include "update.h"
#include "modify.h"
#include "compute_chunk_atom.h" #include "compute_chunk_atom.h"
#include "memory.h"
#include "error.h" #include "error.h"
#include "memory.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -29,8 +25,8 @@ enum{ONCE,NFREQ,EVERY};
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeVCMChunk::ComputeVCMChunk(LAMMPS *lmp, int narg, char **arg) : ComputeVCMChunk::ComputeVCMChunk(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), ComputeChunk(lmp, narg, arg), massproc(nullptr), masstotal(nullptr), vcm(nullptr),
idchunk(nullptr), massproc(nullptr), masstotal(nullptr), vcm(nullptr), vcmall(nullptr) vcmall(nullptr)
{ {
if (narg != 4) error->all(FLERR, "Illegal compute vcm/chunk command"); if (narg != 4) error->all(FLERR, "Illegal compute vcm/chunk command");
@ -40,26 +36,14 @@ ComputeVCMChunk::ComputeVCMChunk(LAMMPS *lmp, int narg, char **arg) :
size_array_rows_variable = 1; size_array_rows_variable = 1;
extarray = 0; extarray = 0;
// ID of compute chunk/atom
idchunk = utils::strdup(arg[3]);
ComputeVCMChunk::init(); ComputeVCMChunk::init();
ComputeVCMChunk::allocate();
// chunk-based data
nchunk = 1;
maxchunk = 0;
allocate();
firstflag = massneed = 1;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeVCMChunk::~ComputeVCMChunk() ComputeVCMChunk::~ComputeVCMChunk()
{ {
delete [] idchunk;
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(vcm); memory->destroy(vcm);
@ -68,18 +52,6 @@ ComputeVCMChunk::~ComputeVCMChunk()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
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 = dynamic_cast<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() void ComputeVCMChunk::setup()
{ {
// one-time calculation of per-chunk mass // one-time calculation of per-chunk mass
@ -98,23 +70,12 @@ void ComputeVCMChunk::compute_array()
int index; int index;
double massone; double massone;
invoked_array = update->ntimestep; ComputeChunk::compute_array();
// 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; int *ichunk = cchunk->ichunk;
if (nchunk > maxchunk) allocate();
size_array_rows = nchunk;
// zero local per-chunk values // zero local per-chunk values
for (int i = 0; i < nchunk; i++) for (int i = 0; i < nchunk; i++) vcm[i][0] = vcm[i][1] = vcm[i][2] = 0.0;
vcm[i][0] = vcm[i][1] = vcm[i][2] = 0.0;
if (massneed) if (massneed)
for (int i = 0; i < nchunk; i++) massproc[i] = 0.0; for (int i = 0; i < nchunk; i++) massproc[i] = 0.0;
@ -131,8 +92,10 @@ void ComputeVCMChunk::compute_array()
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
index = ichunk[i] - 1; index = ichunk[i] - 1;
if (index < 0) continue; if (index < 0) continue;
if (rmass) massone = rmass[i]; if (rmass)
else massone = mass[type[i]]; massone = rmass[i];
else
massone = mass[type[i]];
vcm[index][0] += v[i][0] * massone; vcm[index][0] += v[i][0] * massone;
vcm[index][1] += v[i][1] * massone; vcm[index][1] += v[i][1] * massone;
vcm[index][2] += v[i][2] * massone; vcm[index][2] += v[i][2] * massone;
@ -140,80 +103,25 @@ void ComputeVCMChunk::compute_array()
} }
MPI_Allreduce(&vcm[0][0], &vcmall[0][0], 3 * nchunk, MPI_DOUBLE, MPI_SUM, world); MPI_Allreduce(&vcm[0][0], &vcmall[0][0], 3 * nchunk, MPI_DOUBLE, MPI_SUM, world);
if (massneed) if (massneed) MPI_Allreduce(massproc, masstotal, nchunk, MPI_DOUBLE, MPI_SUM, world);
MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world);
for (int i = 0; i < nchunk; i++) { for (int i = 0; i < nchunk; i++) {
if (masstotal[i] > 0.0) { if (masstotal[i] > 0.0) {
vcmall[i][0] /= masstotal[i]; vcmall[i][0] /= masstotal[i];
vcmall[i][1] /= masstotal[i]; vcmall[i][1] /= masstotal[i];
vcmall[i][2] /= masstotal[i]; vcmall[i][2] /= masstotal[i];
} else vcmall[i][0] = vcmall[i][1] = vcmall[i][2] = 0.0; } else
vcmall[i][0] = vcmall[i][1] = vcmall[i][2] = 0.0;
} }
} }
/* ----------------------------------------------------------------------
lock methods: called by fix ave/time
these methods ensure 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 = dynamic_cast<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 free and reallocate per-chunk arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void ComputeVCMChunk::allocate() void ComputeVCMChunk::allocate()
{ {
ComputeChunk::allocate();
memory->destroy(massproc); memory->destroy(massproc);
memory->destroy(masstotal); memory->destroy(masstotal);
memory->destroy(vcm); memory->destroy(vcm);
@ -232,7 +140,7 @@ void ComputeVCMChunk::allocate()
double ComputeVCMChunk::memory_usage() double ComputeVCMChunk::memory_usage()
{ {
double bytes = (bigint) maxchunk * 2 * sizeof(double); double bytes = (double) maxchunk * 2 * sizeof(double) + ComputeChunk::memory_usage();
bytes += (double) maxchunk * 2 * 3 * sizeof(double); bytes += (double) maxchunk * 2 * 3 * sizeof(double);
return bytes; return bytes;
} }

View File

@ -20,39 +20,26 @@ ComputeStyle(vcm/chunk,ComputeVCMChunk);
#ifndef LMP_COMPUTE_VCM_CHUNK_H #ifndef LMP_COMPUTE_VCM_CHUNK_H
#define LMP_COMPUTE_VCM_CHUNK_H #define LMP_COMPUTE_VCM_CHUNK_H
#include "compute.h" #include "compute_chunk.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class ComputeVCMChunk : public Compute { class ComputeVCMChunk : public ComputeChunk {
public: public:
ComputeVCMChunk(class LAMMPS *, int, char **); ComputeVCMChunk(class LAMMPS *, int, char **);
~ComputeVCMChunk() override; ~ComputeVCMChunk() override;
void init() override;
void setup() override; void setup() override;
void compute_array() override; void compute_array() override;
void lock_enable() override;
void lock_disable() override;
int lock_length() override;
void lock(class Fix *, bigint, bigint) override;
void unlock(class Fix *) override;
double memory_usage() override; double memory_usage() override;
private: private:
int nchunk, maxchunk;
int firstflag, massneed;
char *idchunk;
class ComputeChunkAtom *cchunk;
double *massproc, *masstotal; double *massproc, *masstotal;
double **vcm, **vcmall; double **vcm, **vcmall;
void allocate(); void allocate() override;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
#endif #endif
#endif #endif