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 /* ----------------------------------------------------------------------
16 Contributing author: Axel Kohlmeyer (ICTP, Italy)
17 ------------------------------------------------------------------------- */
18
19 #include "fix_oneway.h"
20
21 #include "atom.h"
22 #include "domain.h"
23 #include "error.h"
24 #include "region.h"
25
26 #include <cstring>
27
28 using namespace LAMMPS_NS;
29 using namespace FixConst;
30
31 enum{NONE=-1,X=0,Y=1,Z=2,XYZMASK=3,MINUS=4,PLUS=0};
32
33 /* ---------------------------------------------------------------------- */
34
FixOneWay(LAMMPS * lmp,int narg,char ** arg)35 FixOneWay::FixOneWay(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
36 {
37 direction = NONE;
38 regionidx = 0;
39 regionstr = nullptr;
40
41 if (narg < 6) error->all(FLERR,"Illegal fix oneway command");
42
43 nevery = utils::inumeric(FLERR,arg[3],false,lmp);
44 if (nevery < 1) error->all(FLERR,"Illegal fix oneway command");
45
46 regionstr = utils::strdup(arg[4]);
47
48 if (strcmp(arg[5], "x") == 0) direction = X|PLUS;
49 if (strcmp(arg[5], "X") == 0) direction = X|PLUS;
50 if (strcmp(arg[5], "y") == 0) direction = Y|PLUS;
51 if (strcmp(arg[5], "Y") == 0) direction = Y|PLUS;
52 if (strcmp(arg[5], "z") == 0) direction = Z|PLUS;
53 if (strcmp(arg[5], "Z") == 0) direction = Z|PLUS;
54 if (strcmp(arg[5],"-x") == 0) direction = X|MINUS;
55 if (strcmp(arg[5],"-X") == 0) direction = X|MINUS;
56 if (strcmp(arg[5],"-y") == 0) direction = Y|MINUS;
57 if (strcmp(arg[5],"-Y") == 0) direction = Y|MINUS;
58 if (strcmp(arg[5],"-z") == 0) direction = Z|MINUS;
59 if (strcmp(arg[5],"-Z") == 0) direction = Z|MINUS;
60
61 global_freq = nevery;
62 }
63
64 /* ---------------------------------------------------------------------- */
65
~FixOneWay()66 FixOneWay::~FixOneWay()
67 {
68 if (regionstr) delete[] regionstr;
69 }
70
71 /* ---------------------------------------------------------------------- */
72
setmask()73 int FixOneWay::setmask()
74 {
75 return END_OF_STEP;
76 }
77
78 /* ---------------------------------------------------------------------- */
79
init()80 void FixOneWay::init()
81 {
82 regionidx = domain->find_region(regionstr);
83 if (regionidx < 0)
84 error->all(FLERR,"Region for fix oneway does not exist");
85 }
86
87 /* ---------------------------------------------------------------------- */
88
end_of_step()89 void FixOneWay::end_of_step()
90 {
91 Region *region = domain->regions[regionidx];
92 region->prematch();
93
94 const int idx = direction & XYZMASK;
95 const double * const * const x = atom->x;
96 double * const * const v = atom->v;
97 const int *mask = atom->mask;
98 const int nlocal = atom->nlocal;
99
100 for (int i = 0; i < nlocal; ++i) {
101 if ((mask[i] & groupbit) && region->match(x[i][0],x[i][1],x[i][2])) {
102 if (direction & MINUS) {
103 if (v[i][idx] > 0.0) v[i][idx] = -v[i][idx];
104 } else {
105 if (v[i][idx] < 0.0) v[i][idx] = -v[i][idx];
106 }
107 }
108 }
109 }
110
111