~ubuntu-branches/debian/sid/lammps/sid

« back to all changes in this revision

Viewing changes to src/compute_com_chunk.cpp

  • Committer: Package Import Robot
  • Author(s): Anton Gladky
  • Date: 2015-04-29 23:44:49 UTC
  • mfrom: (5.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20150429234449-mbhy9utku6hp6oq8
Tags: 0~20150313.gitfa668e1-1
Upload into unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ----------------------------------------------------------------------
 
2
   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
 
3
   http://lammps.sandia.gov, Sandia National Laboratories
 
4
   Steve Plimpton, sjplimp@sandia.gov
 
5
 
 
6
   Copyright (2003) Sandia Corporation.  Under the terms of Contract
 
7
   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
 
8
   certain rights in this software.  This software is distributed under
 
9
   the GNU General Public License.
 
10
 
 
11
   See the README file in the top-level LAMMPS directory.
 
12
------------------------------------------------------------------------- */
 
13
 
 
14
#include "string.h"
 
15
#include "compute_com_chunk.h"
 
16
#include "atom.h"
 
17
#include "update.h"
 
18
#include "modify.h"
 
19
#include "compute_chunk_atom.h"
 
20
#include "domain.h"
 
21
#include "memory.h"
 
22
#include "error.h"
 
23
 
 
24
using namespace LAMMPS_NS;
 
25
 
 
26
enum{ONCE,NFREQ,EVERY};
 
27
 
 
28
/* ---------------------------------------------------------------------- */
 
29
 
 
30
ComputeCOMChunk::ComputeCOMChunk(LAMMPS *lmp, int narg, char **arg) :
 
31
  Compute(lmp, narg, arg)
 
32
{
 
33
  if (narg != 4) error->all(FLERR,"Illegal compute com/chunk command");
 
34
 
 
35
  array_flag = 1;
 
36
  size_array_cols = 3;
 
37
  size_array_rows = 0;
 
38
  size_array_rows_variable = 1;
 
39
  extarray = 0;
 
40
 
 
41
  // ID of compute chunk/atom
 
42
 
 
43
  int n = strlen(arg[3]) + 1;
 
44
  idchunk = new char[n];
 
45
  strcpy(idchunk,arg[3]);
 
46
 
 
47
  init();
 
48
 
 
49
  // chunk-based data
 
50
 
 
51
  nchunk = 1;
 
52
  maxchunk = 0;
 
53
  massproc = masstotal = NULL;
 
54
  com = comall = NULL;
 
55
  allocate();
 
56
 
 
57
  firstflag = massneed = 1;
 
58
}
 
59
 
 
60
/* ---------------------------------------------------------------------- */
 
61
 
 
62
ComputeCOMChunk::~ComputeCOMChunk()
 
63
{
 
64
  delete [] idchunk;
 
65
  memory->destroy(massproc);
 
66
  memory->destroy(masstotal);
 
67
  memory->destroy(com);
 
68
  memory->destroy(comall);
 
69
}
 
70
 
 
71
/* ---------------------------------------------------------------------- */
 
72
 
 
73
void ComputeCOMChunk::init()
 
74
{
 
75
  int icompute = modify->find_compute(idchunk);
 
76
  if (icompute < 0)
 
77
    error->all(FLERR,"Chunk/atom compute does not exist for compute com/chunk");
 
78
  cchunk = (ComputeChunkAtom *) modify->compute[icompute];
 
79
  if (strcmp(cchunk->style,"chunk/atom") != 0)
 
80
    error->all(FLERR,"Compute com/chunk does not use chunk/atom compute");
 
81
}
 
82
 
 
83
/* ---------------------------------------------------------------------- */
 
84
 
 
85
void ComputeCOMChunk::setup()
 
86
{
 
87
  // one-time calculation of per-chunk mass
 
88
  // done in setup, so that ComputeChunkAtom::setup() is already called
 
89
 
 
90
  if (firstflag && cchunk->idsflag == ONCE) {
 
91
    firstflag = massneed = 0;
 
92
    compute_array();
 
93
  }
 
94
}
 
95
 
 
96
/* ---------------------------------------------------------------------- */
 
97
 
 
98
void ComputeCOMChunk::compute_array()
 
99
{
 
100
  int index;
 
101
  double massone;
 
102
  double unwrap[3];
 
103
 
 
104
  invoked_array = update->ntimestep;
 
105
 
 
106
  // compute chunk/atom assigns atoms to chunk IDs
 
107
  // extract ichunk index vector from compute
 
108
  // ichunk = 1 to Nchunk for included atoms, 0 for excluded atoms
 
109
 
 
110
  nchunk = cchunk->setup_chunks();
 
111
  cchunk->compute_ichunk();
 
112
  int *ichunk = cchunk->ichunk;
 
113
 
 
114
  if (nchunk > maxchunk) allocate();
 
115
  size_array_rows = nchunk;
 
116
 
 
117
  // zero local per-chunk values
 
118
 
 
119
  for (int i = 0; i < nchunk; i++)
 
120
    com[i][0] = com[i][1] = com[i][2] = 0.0;
 
121
  if (massneed)
 
122
    for (int i = 0; i < nchunk; i++) massproc[i] = 0.0;
 
123
 
 
124
  // compute COM for each chunk
 
125
 
 
126
  double **x = atom->x;
 
127
  int *mask = atom->mask;
 
128
  int *type = atom->type;
 
129
  imageint *image = atom->image;
 
130
  double *mass = atom->mass;
 
131
  double *rmass = atom->rmass;
 
132
  int nlocal = atom->nlocal;
 
133
 
 
134
  for (int i = 0; i < nlocal; i++)
 
135
    if (mask[i] & groupbit) {
 
136
      index = ichunk[i]-1;
 
137
      if (index < 0) continue;
 
138
      if (rmass) massone = rmass[i];
 
139
      else massone = mass[type[i]];
 
140
      domain->unmap(x[i],image[i],unwrap);
 
141
      com[index][0] += unwrap[0] * massone;
 
142
      com[index][1] += unwrap[1] * massone;
 
143
      com[index][2] += unwrap[2] * massone;
 
144
      if (massneed) massproc[index] += massone;
 
145
    }
 
146
 
 
147
  MPI_Allreduce(&com[0][0],&comall[0][0],3*nchunk,MPI_DOUBLE,MPI_SUM,world);
 
148
  if (massneed)
 
149
    MPI_Allreduce(massproc,masstotal,nchunk,MPI_DOUBLE,MPI_SUM,world);
 
150
 
 
151
  for (int i = 0; i < nchunk; i++) {
 
152
    if (masstotal[i] > 0.0) {
 
153
      comall[i][0] /= masstotal[i];
 
154
      comall[i][1] /= masstotal[i];
 
155
      comall[i][2] /= masstotal[i];
 
156
    } else comall[i][0] = comall[i][1] = comall[i][2] = 0.0;
 
157
  }
 
158
}
 
159
 
 
160
/* ----------------------------------------------------------------------
 
161
   lock methods: called by fix ave/time
 
162
   these methods insure vector/array size is locked for Nfreq epoch
 
163
     by passing lock info along to compute chunk/atom
 
164
------------------------------------------------------------------------- */
 
165
 
 
166
/* ----------------------------------------------------------------------
 
167
   increment lock counter
 
168
------------------------------------------------------------------------- */
 
169
 
 
170
void ComputeCOMChunk::lock_enable()
 
171
{
 
172
  cchunk->lockcount++;
 
173
}
 
174
 
 
175
/* ----------------------------------------------------------------------
 
176
   decrement lock counter in compute chunk/atom, it if still exists
 
177
------------------------------------------------------------------------- */
 
178
 
 
179
void ComputeCOMChunk::lock_disable()
 
180
{
 
181
  int icompute = modify->find_compute(idchunk);
 
182
  if (icompute >= 0) {
 
183
    cchunk = (ComputeChunkAtom *) modify->compute[icompute];
 
184
    cchunk->lockcount--;
 
185
  }
 
186
}
 
187
 
 
188
/* ----------------------------------------------------------------------
 
189
   calculate and return # of chunks = length of vector/array
 
190
------------------------------------------------------------------------- */
 
191
 
 
192
int ComputeCOMChunk::lock_length()
 
193
{
 
194
  nchunk = cchunk->setup_chunks();
 
195
  return nchunk;
 
196
}
 
197
 
 
198
/* ----------------------------------------------------------------------
 
199
   set the lock from startstep to stopstep
 
200
------------------------------------------------------------------------- */
 
201
 
 
202
void ComputeCOMChunk::lock(Fix *fixptr, bigint startstep, bigint stopstep)
 
203
{
 
204
  cchunk->lock(fixptr,startstep,stopstep);
 
205
}
 
206
 
 
207
/* ----------------------------------------------------------------------
 
208
   unset the lock
 
209
------------------------------------------------------------------------- */
 
210
 
 
211
void ComputeCOMChunk::unlock(Fix *fixptr)
 
212
{
 
213
  cchunk->unlock(fixptr);
 
214
}
 
215
 
 
216
/* ----------------------------------------------------------------------
 
217
   free and reallocate per-chunk arrays
 
218
------------------------------------------------------------------------- */
 
219
 
 
220
void ComputeCOMChunk::allocate()
 
221
{
 
222
  memory->destroy(massproc);
 
223
  memory->destroy(masstotal);
 
224
  memory->destroy(com);
 
225
  memory->destroy(comall);
 
226
  maxchunk = nchunk;
 
227
  memory->create(massproc,maxchunk,"com/chunk:massproc");
 
228
  memory->create(masstotal,maxchunk,"com/chunk:masstotal");
 
229
  memory->create(com,maxchunk,3,"com/chunk:com");
 
230
  memory->create(comall,maxchunk,3,"com/chunk:comall");
 
231
  array = comall;
 
232
}
 
233
 
 
234
/* ----------------------------------------------------------------------
 
235
   memory usage of local data
 
236
------------------------------------------------------------------------- */
 
237
 
 
238
double ComputeCOMChunk::memory_usage()
 
239
{
 
240
  double bytes = (bigint) maxchunk * 2 * sizeof(double);
 
241
  bytes += (bigint) maxchunk * 2*3 * sizeof(double);
 
242
  return bytes;
 
243
}