1 /* ----------------------------------------------------------------------
2 This is the
3
4 ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗
5 ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝
6 ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗
7 ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║
8 ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║
9 ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝®
10
11 DEM simulation engine, released by
12 DCS Computing Gmbh, Linz, Austria
13 http://www.dcs-computing.com, office@dcs-computing.com
14
15 LIGGGHTS® is part of CFDEM®project:
16 http://www.liggghts.com | http://www.cfdem.com
17
18 Core developer and main author:
19 Christoph Kloss, christoph.kloss@dcs-computing.com
20
21 LIGGGHTS® is open-source, distributed under the terms of the GNU Public
22 License, version 2 or later. It is distributed in the hope that it will
23 be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
24 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have
25 received a copy of the GNU General Public License along with LIGGGHTS®.
26 If not, see http://www.gnu.org/licenses . See also top-level README
27 and LICENSE files.
28
29 LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH,
30 the producer of the LIGGGHTS® software and the CFDEM®coupling software
31 See http://www.cfdem.com/terms-trademark-policy for details.
32
33 -------------------------------------------------------------------------
34 Contributing author and copyright for this file:
35 This file is from LAMMPS
36 LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
37 http://lammps.sandia.gov, Sandia National Laboratories
38 Steve Plimpton, sjplimp@sandia.gov
39
40 Copyright (2003) Sandia Corporation. Under the terms of Contract
41 DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
42 certain rights in this software. This software is distributed under
43 the GNU General Public License.
44 ------------------------------------------------------------------------- */
45
46 #include <string.h>
47 #include "compute_property_molecule.h"
48 #include "atom.h"
49 #include "update.h"
50 #include "memory.h"
51 #include "error.h"
52
53 using namespace LAMMPS_NS;
54
55 /* ---------------------------------------------------------------------- */
56
ComputePropertyMolecule(LAMMPS * lmp,int & iarg,int narg,char ** arg)57 ComputePropertyMolecule::ComputePropertyMolecule(LAMMPS *lmp, int &iarg, int narg, char **arg) :
58 Compute(lmp, iarg, narg, arg)
59 {
60 if (narg < iarg+1) error->all(FLERR,"Illegal compute property/molecule command");
61
62 if (atom->molecular == 0)
63 error->all(FLERR,"Compute property/molecule requires molecular atom style");
64
65 nvalues = narg - iarg;
66
67 pack_choice = new FnPtrPack[nvalues];
68
69 int i;
70 const int arg_offset = iarg;
71 for (; iarg < narg; iarg++) {
72 i = iarg-arg_offset;
73
74 if (strcmp(arg[iarg],"mol") == 0)
75 pack_choice[i] = &ComputePropertyMolecule::pack_mol;
76 else if (strcmp(arg[iarg],"count") == 0)
77 pack_choice[i] = &ComputePropertyMolecule::pack_count;
78 else error->all(FLERR,"Invalid keyword in compute property/molecule command");
79 }
80
81 // setup molecule-based data
82
83 nmolecules = molecules_in_group(idlo,idhi);
84
85 vector = NULL;
86 array = NULL;
87
88 if (nvalues == 1) {
89 memory->create(vector,nmolecules,"property/molecule:vector");
90 vector_flag = 1;
91 size_vector = nmolecules;
92 extvector = 0;
93 } else {
94 memory->create(array,nmolecules,nvalues,"property/molecule:array");
95 array_flag = 1;
96 size_array_rows = nmolecules;
97 size_array_cols = nvalues;
98 extarray = 0;
99 }
100
101 // fill vector or array with molecule values
102
103 if (nvalues == 1) {
104 buf = vector;
105 (this->*pack_choice[0])(0);
106 } else {
107 if (array) buf = &array[0][0];
108 for (int n = 0; n < nvalues; n++)
109 (this->*pack_choice[n])(n);
110 }
111 }
112
113 /* ---------------------------------------------------------------------- */
114
~ComputePropertyMolecule()115 ComputePropertyMolecule::~ComputePropertyMolecule()
116 {
117 delete [] pack_choice;
118 memory->destroy(vector);
119 memory->destroy(array);
120 }
121
122 /* ---------------------------------------------------------------------- */
123
init()124 void ComputePropertyMolecule::init()
125 {
126 int ntmp = molecules_in_group(idlo,idhi);
127 if (ntmp != nmolecules)
128 error->all(FLERR,"Molecule count changed in compute property/molecule");
129 }
130
131 /* ---------------------------------------------------------------------- */
132
compute_vector()133 void ComputePropertyMolecule::compute_vector()
134 {
135 invoked_vector = update->ntimestep;
136 }
137
138 /* ---------------------------------------------------------------------- */
139
compute_array()140 void ComputePropertyMolecule::compute_array()
141 {
142 invoked_array = update->ntimestep;
143 }
144
145 /* ----------------------------------------------------------------------
146 memory usage of local data
147 ------------------------------------------------------------------------- */
148
memory_usage()149 double ComputePropertyMolecule::memory_usage()
150 {
151 double bytes = nmolecules*nvalues * sizeof(double);
152 if (molmap) bytes += (idhi-idlo+1) * sizeof(int);
153 return bytes;
154 }
155
156 /* ----------------------------------------------------------------------
157 one method for every keyword compute property/molecule can output
158 the atom property is packed into buf starting at n with stride nvalues
159 customize a new keyword by adding a method
160 ------------------------------------------------------------------------- */
161
pack_mol(int n)162 void ComputePropertyMolecule::pack_mol(int n)
163 {
164 for (int m = idlo; m <= idhi; m++)
165 if (molmap == NULL || molmap[m-idlo] >= 0) {
166 buf[n] = m;
167 n += nvalues;
168 }
169 }
170
171 /* ---------------------------------------------------------------------- */
172
pack_count(int n)173 void ComputePropertyMolecule::pack_count(int n)
174 {
175 int i,m,imol;
176
177 int *count_one = new int[nmolecules];
178 for (m = 0; m < nmolecules; m++) count_one[m] = 0;
179
180 int *molecule = atom->molecule;
181 int *mask = atom->mask;
182 int nlocal = atom->nlocal;
183
184 for (i = 0; i < nlocal; i++)
185 if (mask[i] & groupbit) {
186 imol = molecule[i];
187 if (molmap) imol = molmap[imol-idlo];
188 else imol--;
189 count_one[imol]++;
190 }
191
192 int *count_all = new int[nmolecules];
193 MPI_Allreduce(count_one,count_all,nmolecules,MPI_INT,MPI_SUM,world);
194
195 for (m = 0; m < nmolecules; m++)
196 if (molmap == NULL || molmap[m] >= 0) {
197 buf[n] = count_all[m];
198 n += nvalues;
199 }
200
201 delete [] count_one;
202 delete [] count_all;
203 }
204