1 /* ----------------------------------------------------------------------
2    SPARTA - Stochastic PArallel Rarefied-gas Time-accurate Analyzer
3    http://sparta.sandia.gov
4    Steve Plimpton, sjplimp@sandia.gov, Michael Gallis, magalli@sandia.gov
5    Sandia National Laboratories
6 
7    Copyright (2014) 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 SPARTA directory.
13 ------------------------------------------------------------------------- */
14 
15 #include "math.h"
16 #include "stdlib.h"
17 #include "string.h"
18 #include "surf_collide_diffuse_kokkos.h"
19 #include "surf.h"
20 #include "surf_react.h"
21 #include "input.h"
22 #include "variable.h"
23 #include "particle.h"
24 #include "domain.h"
25 #include "update.h"
26 #include "modify.h"
27 #include "comm.h"
28 #include "random_mars.h"
29 #include "random_knuth.h"
30 #include "math_const.h"
31 #include "math_extra.h"
32 #include "error.h"
33 #include "particle_kokkos.h"
34 #include "sparta_masks.h"
35 #include "collide.h"
36 
37 using namespace SPARTA_NS;
38 using namespace MathConst;
39 
40 /* ---------------------------------------------------------------------- */
41 
SurfCollideDiffuseKokkos(SPARTA * sparta,int narg,char ** arg)42 SurfCollideDiffuseKokkos::SurfCollideDiffuseKokkos(SPARTA *sparta, int narg, char **arg) :
43   SurfCollideDiffuse(sparta, narg, arg),
44   rand_pool(12345 + comm->me
45 #ifdef SPARTA_KOKKOS_EXACT
46             , sparta
47 #endif
48            )
49 {
50 #ifdef SPARTA_KOKKOS_EXACT
51   rand_pool.init(random);
52 #endif
53 
54   k_nsingle = DAT::tdual_int_scalar("SurfCollide:nsingle");
55   d_nsingle = k_nsingle.d_view;
56   h_nsingle = k_nsingle.h_view;
57 }
58 
SurfCollideDiffuseKokkos(SPARTA * sparta)59 SurfCollideDiffuseKokkos::SurfCollideDiffuseKokkos(SPARTA *sparta) :
60   SurfCollideDiffuse(sparta),
61   rand_pool(12345 // seed doesn't matter since it will just be copied over
62 #ifdef SPARTA_KOKKOS_EXACT
63             , sparta
64 #endif
65            )
66 {
67   // ID and style
68   // ID must be all alphanumeric chars or underscores
69 
70   int narg = 4;
71   const char* arg[] = {"sc_kk_diffuse_copy","diffuse","300.0","1.0"};
72 
73   int n = strlen(arg[0]) + 1;
74   id = new char[n];
75   strcpy(id,arg[0]);
76 
77   for (int i = 0; i < n-1; i++)
78     if (!isalnum(id[i]) && id[i] != '_')
79       error->all(FLERR,"Surf_collide ID must be alphanumeric or "
80                  "underscore characters");
81 
82   dynamicflag = 1;
83   n = strlen(arg[1]) + 1;
84   style = new char[n];
85   strcpy(style,arg[1]);
86 
87   vector_flag = 1;
88   size_vector = 2;
89 
90   nsingle = ntotal = 0;
91 
92   copy = 0;
93 
94   if (narg < 4) error->all(FLERR,"Illegal surf_collide diffuse command");
95 
96   allowreact = 1;
97 
98   tstr = NULL;
99 
100   if (strstr(arg[2],"v_") == arg[2]) {
101     int n = strlen(&arg[2][2]) + 1;
102     tstr = new char[n];
103     strcpy(tstr,&arg[2][2]);
104   } else {
105     twall = input->numeric(FLERR,(char*)arg[2]);
106     if (twall <= 0.0) error->all(FLERR,"Surf_collide diffuse temp <= 0.0");
107   }
108 
109   acc = input->numeric(FLERR,arg[3]);
110   if (acc < 0.0 || acc > 1.0)
111     error->all(FLERR,"Illegal surf_collide diffuse command");
112 
113   // optional args
114 
115   tflag = rflag = 0;
116 
117   int iarg = 4;
118   while (iarg < narg) {
119     if (strcmp(arg[iarg],"translate") == 0) {
120       if (iarg+4 > narg)
121         error->all(FLERR,"Illegal surf_collide diffuse command");
122       tflag = 1;
123       vx = atof(arg[iarg+1]);
124       vy = atof(arg[iarg+2]);
125       vz = atof(arg[iarg+3]);
126       iarg += 4;
127     } else if (strcmp(arg[iarg],"rotate") == 0) {
128       if (iarg+7 > narg)
129         error->all(FLERR,"Illegal surf_collide diffuse command");
130       rflag = 1;
131       px = atof(arg[iarg+1]);
132       py = atof(arg[iarg+2]);
133       pz = atof(arg[iarg+3]);
134       wx = atof(arg[iarg+4]);
135       wy = atof(arg[iarg+5]);
136       wz = atof(arg[iarg+6]);
137       if (domain->dimension == 2 && pz != 0.0)
138         error->all(FLERR,"Surf_collide diffuse rotation invalid for 2d");
139       if (domain->dimension == 2 && (wx != 0.0 || wy != 0.0))
140         error->all(FLERR,"Surf_collide diffuse rotation invalid for 2d");
141       iarg += 7;
142     } else error->all(FLERR,"Illegal surf_collide diffuse command");
143   }
144 
145   if (tflag && rflag) error->all(FLERR,"Illegal surf_collide diffuse command");
146   if (tflag || rflag) trflag = 1;
147   else trflag = 0;
148 
149   random = NULL;
150 
151   k_nsingle = DAT::tdual_int_scalar("SurfCollide:nsingle");
152   d_nsingle = k_nsingle.d_view;
153   h_nsingle = k_nsingle.h_view;
154 
155   allowreact = 0;
156 }
157 
158 /* ---------------------------------------------------------------------- */
159 
~SurfCollideDiffuseKokkos()160 SurfCollideDiffuseKokkos::~SurfCollideDiffuseKokkos()
161 {
162   if (copy) return;
163 
164 #ifdef SPARTA_KOKKOS_EXACT
165   rand_pool.destroy();
166 #endif
167 }
168 
169 /* ---------------------------------------------------------------------- */
170 
pre_collide()171 void SurfCollideDiffuseKokkos::pre_collide()
172 {
173   if (modify->n_update_custom)
174     error->all(FLERR,"Cannot yet use surf_collide diffuse/kk"
175                "with fix vibmode or fix ambipolar");
176 
177   if (random == NULL) {
178     // initialize RNG
179 
180     random = new RanKnuth(update->ranmaster->uniform());
181     double seed = update->ranmaster->uniform();
182     random->reset(seed,comm->me,100);
183 
184 #ifdef SPARTA_KOKKOS_EXACT
185     rand_pool.init(random);
186 #endif
187   }
188 
189   ParticleKokkos* particle_kk = (ParticleKokkos*) particle;
190   particle_kk->sync(Device,SPECIES_MASK);
191   d_species = particle_kk->k_species.d_view;
192   boltz = update->boltz;
193 
194   rotstyle = NONE;
195   if (Pointers::collide) rotstyle = Pointers::collide->rotstyle;
196   vibstyle = NONE;
197   if (Pointers::collide) vibstyle = Pointers::collide->vibstyle;
198 }
199