1 /* ----------------------------------------------------------------------
2    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
3    https://www.lammps.org/, 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 "imbalance_group.h"
15 
16 #include "atom.h"
17 #include "error.h"
18 #include "group.h"
19 
20 using namespace LAMMPS_NS;
21 
22 /* -------------------------------------------------------------------- */
23 
ImbalanceGroup(LAMMPS * lmp)24 ImbalanceGroup::ImbalanceGroup(LAMMPS *lmp) : Imbalance(lmp), id(nullptr), factor(nullptr) {}
25 
26 /* -------------------------------------------------------------------- */
27 
~ImbalanceGroup()28 ImbalanceGroup::~ImbalanceGroup()
29 {
30   delete[] id;
31   delete[] factor;
32 }
33 
34 /* -------------------------------------------------------------------- */
35 
options(int narg,char ** arg)36 int ImbalanceGroup::options(int narg, char **arg)
37 {
38   if (narg < 3) error->all(FLERR, "Illegal balance weight command");
39 
40   num = utils::inumeric(FLERR, arg[0], false, lmp);
41   if (num < 1) error->all(FLERR, "Illegal balance weight command");
42   if (2 * num + 1 > narg) error->all(FLERR, "Illegal balance weight command");
43 
44   id = new int[num];
45   factor = new double[num];
46   for (int i = 0; i < num; ++i) {
47     id[i] = group->find(arg[2 * i + 1]);
48     if (id[i] < 0) error->all(FLERR, "Unknown group in balance weight command: {}", arg[2 * i + 1]);
49     factor[i] = utils::numeric(FLERR, arg[2 * i + 2], false, lmp);
50     if (factor[i] <= 0.0) error->all(FLERR, "Illegal balance weight command");
51   }
52   return 2 * num + 1;
53 }
54 
55 /* -------------------------------------------------------------------- */
56 
compute(double * weight)57 void ImbalanceGroup::compute(double *weight)
58 {
59   const int *const mask = atom->mask;
60   const int *const bitmask = group->bitmask;
61   const int nlocal = atom->nlocal;
62 
63   if (num == 0) return;
64 
65   for (int i = 0; i < nlocal; ++i) {
66     const int imask = mask[i];
67     for (int j = 0; j < num; ++j) {
68       if (imask & bitmask[id[j]]) weight[i] *= factor[j];
69     }
70   }
71 }
72 
73 /* -------------------------------------------------------------------- */
74 
info()75 std::string ImbalanceGroup::info()
76 {
77   std::string mesg = "";
78 
79   if (num > 0) {
80     const char *const *const names = group->names;
81 
82     mesg += "  group weights:";
83     for (int i = 0; i < num; ++i) mesg += fmt::format(" {}={}", names[id[i]], factor[i]);
84     mesg += "\n";
85   }
86   return mesg;
87 }
88