1 // clang-format off
2 /* ----------------------------------------------------------------------
3 LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
4 https://www.lammps.org/, Sandia National Laboratories
5 Steve Plimpton, sjplimp@sandia.gov
6
7 Copyright (2003) Sandia Corporation. Under the terms of Contract
8 DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
9 certain rights in this software. This software is distributed under
10 the GNU General Public License.
11
12 See the README file in the top-level LAMMPS directory.
13 ------------------------------------------------------------------------- */
14
15 #include "compute.h"
16
17 #include "atom_masks.h"
18 #include "domain.h"
19 #include "error.h"
20 #include "fix.h"
21 #include "group.h"
22 #include "memory.h"
23 #include "modify.h"
24
25 #include <cstring>
26
27 using namespace LAMMPS_NS;
28
29 #define DELTA 4
30 #define BIG MAXTAGINT
31
32 // allocate space for static class instance variable and initialize it
33
34 int Compute::instance_total = 0;
35
36 /* ---------------------------------------------------------------------- */
37
Compute(LAMMPS * lmp,int narg,char ** arg)38 Compute::Compute(LAMMPS *lmp, int narg, char **arg) :
39 Pointers(lmp),
40 id(nullptr), style(nullptr),
41 vector(nullptr), array(nullptr), vector_atom(nullptr),
42 array_atom(nullptr), vector_local(nullptr), array_local(nullptr), extlist(nullptr),
43 tlist(nullptr), vbiasall(nullptr)
44 {
45 instance_me = instance_total++;
46
47 if (narg < 3) error->all(FLERR,"Illegal compute command");
48
49 // compute ID, group, and style
50 // ID must be all alphanumeric chars or underscores
51
52 id = utils::strdup(arg[0]);
53 if (!utils::is_id(id))
54 error->all(FLERR,"Compute ID must be alphanumeric or underscore characters");
55
56 igroup = group->find(arg[1]);
57 if (igroup == -1) error->all(FLERR,"Could not find compute group ID");
58 groupbit = group->bitmask[igroup];
59
60 style = utils::strdup(arg[2]);
61
62 // set child class defaults
63
64 scalar_flag = vector_flag = array_flag = 0;
65 peratom_flag = local_flag = 0;
66 size_vector_variable = size_array_rows_variable = 0;
67
68 tempflag = pressflag = peflag = 0;
69 pressatomflag = peatomflag = 0;
70 create_attribute = 0;
71 tempbias = 0;
72
73 timeflag = 0;
74 comm_forward = comm_reverse = 0;
75 dynamic = 0;
76 dynamic_group_allow = 1;
77
78 invoked_scalar = invoked_vector = invoked_array = -1;
79 invoked_peratom = invoked_local = -1;
80 invoked_flag = INVOKED_NONE;
81
82 // set modify defaults
83
84 extra_dof = domain->dimension;
85 dynamic_user = 0;
86 fix_dof = 0;
87
88 // setup list of timesteps
89
90 ntime = maxtime = 0;
91
92 // data masks
93
94 execution_space = Host;
95 datamask_read = ALL_MASK;
96 datamask_modify = ALL_MASK;
97
98 copymode = 0;
99 kokkosable = 0;
100 }
101
102 /* ---------------------------------------------------------------------- */
103
~Compute()104 Compute::~Compute()
105 {
106 if (copymode) return;
107
108 delete [] id;
109 delete [] style;
110 memory->destroy(tlist);
111 }
112
113 /* ---------------------------------------------------------------------- */
114
modify_params(int narg,char ** arg)115 void Compute::modify_params(int narg, char **arg)
116 {
117 if (narg == 0) error->all(FLERR,"Illegal compute_modify command");
118
119 int iarg = 0;
120 while (iarg < narg) {
121 // added more specific keywords in Mar17
122 // at some point, remove generic extra and dynamic
123 if (strcmp(arg[iarg],"extra") == 0 ||
124 strcmp(arg[iarg],"extra/dof") == 0) {
125 if (iarg+2 > narg) error->all(FLERR,"Illegal compute_modify command");
126 extra_dof = utils::numeric(FLERR,arg[iarg+1],false,lmp);
127 iarg += 2;
128 } else if (strcmp(arg[iarg],"dynamic") == 0 ||
129 strcmp(arg[iarg],"dynamic/dof") == 0) {
130 if (iarg+2 > narg) error->all(FLERR,"Illegal compute_modify command");
131 if (strcmp(arg[iarg+1],"no") == 0) dynamic_user = 0;
132 else if (strcmp(arg[iarg+1],"yes") == 0) dynamic_user = 1;
133 else error->all(FLERR,"Illegal compute_modify command");
134 iarg += 2;
135 } else error->all(FLERR,"Illegal compute_modify command");
136 }
137 }
138
139 /* ----------------------------------------------------------------------
140 calculate adjustment in DOF due to fixes
141 ------------------------------------------------------------------------- */
142
adjust_dof_fix()143 void Compute::adjust_dof_fix()
144 {
145 Fix **fix = modify->fix;
146 int nfix = modify->nfix;
147
148 fix_dof = 0;
149 for (int i = 0; i < nfix; i++)
150 if (fix[i]->dof_flag)
151 fix_dof += fix[i]->dof(igroup);
152 }
153
154 /* ----------------------------------------------------------------------
155 reset extra_dof to its default value
156 ------------------------------------------------------------------------- */
157
reset_extra_dof()158 void Compute::reset_extra_dof()
159 {
160 extra_dof = domain->dimension;
161 }
162
163 /* ---------------------------------------------------------------------- */
164
reset_extra_compute_fix(const char *)165 void Compute::reset_extra_compute_fix(const char *)
166 {
167 error->all(FLERR,
168 "Compute does not allow an extra compute or fix to be reset");
169 }
170
171 /* ----------------------------------------------------------------------
172 add ntimestep to list of timesteps the compute will be called on
173 do not add if already in list
174 search from top downward, since list of times is in decreasing order
175 ------------------------------------------------------------------------- */
176
addstep(bigint ntimestep)177 void Compute::addstep(bigint ntimestep)
178 {
179 // i = location in list to insert ntimestep
180
181 int i;
182 for (i = ntime-1; i >= 0; i--) {
183 if (ntimestep == tlist[i]) return;
184 if (ntimestep < tlist[i]) break;
185 }
186 i++;
187
188 // extend list as needed
189
190 if (ntime == maxtime) {
191 maxtime += DELTA;
192 memory->grow(tlist,maxtime,"compute:tlist");
193 }
194
195 // move remainder of list upward and insert ntimestep
196
197 for (int j = ntime-1; j >= i; j--) tlist[j+1] = tlist[j];
198 tlist[i] = ntimestep;
199 ntime++;
200 }
201
202 /* ----------------------------------------------------------------------
203 return 1/0 if ntimestep is or is not in list of calling timesteps
204 if value(s) on top of list are less than ntimestep, delete them
205 search from top downward, since list of times is in decreasing order
206 ------------------------------------------------------------------------- */
207
matchstep(bigint ntimestep)208 int Compute::matchstep(bigint ntimestep)
209 {
210 for (int i = ntime-1; i >= 0; i--) {
211 if (ntimestep < tlist[i]) return 0;
212 if (ntimestep == tlist[i]) return 1;
213 if (ntimestep > tlist[i]) ntime--;
214 }
215 return 0;
216 }
217
218 /* ----------------------------------------------------------------------
219 clean out list of timesteps to call the compute on
220 ------------------------------------------------------------------------- */
221
clearstep()222 void Compute::clearstep()
223 {
224 ntime = 0;
225 }
226