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 #ifdef FIX_CLASS
16 
17 FixStyle(vibmode/kk,FixVibmodeKokkos)
18 
19 #else
20 
21 #ifndef SPARTA_FIX_VIBMODE_KOKKOS_H
22 #define SPARTA_FIX_VIBMODE_KOKKOS_H
23 
24 #include "fix_vibmode.h"
25 #include "kokkos_type.h"
26 #include "particle_kokkos.h"
27 #include "Kokkos_Random.hpp"
28 #include "rand_pool_wrap.h"
29 
30 namespace SPARTA_NS {
31 
32 class FixVibmodeKokkos : public FixVibmode {
33  public:
34   FixVibmodeKokkos(class SPARTA *, int, char **);
35   ~FixVibmodeKokkos();
36   //void init();
37   void update_custom(int, double, double, double, double *);
38 
39   KOKKOS_INLINE_FUNCTION
40   void update_custom_kokkos(int, double, double, double, double *);
41 
42  private:
43   int boltz;
44 
45 #ifndef SPARTA_KOKKOS_EXACT
46   Kokkos::Random_XorShift64_Pool<DeviceType> rand_pool;
47   typedef typename Kokkos::Random_XorShift64_Pool<DeviceType>::generator_type rand_type;
48 
49   //Kokkos::Random_XorShift1024_Pool<DeviceType> rand_pool;
50   //typedef typename Kokkos::Random_XorShift1024_Pool<DeviceType>::generator_type rand_type;
51 #else
52   RandPoolWrap rand_pool;
53   typedef RandWrap rand_type;
54 #endif
55 
56   t_particle_1d d_particles;
57   t_particle_1d d_sorted;
58   t_species_1d d_species;
59 
60   DAT::t_int_1d d_ewhich;
61   ParticleKokkos::tdual_struct_tdual_int_2d_1d k_eiarray;
62 };
63 
64 /* ----------------------------------------------------------------------
65    called when a particle with index is created
66     or when temperature dependent properties need to be updated
67    populate all vibrational modes and set evib = sum of mode energies
68 ------------------------------------------------------------------------- */
69 
70 KOKKOS_INLINE_FUNCTION
71 void FixVibmodeKokkos::update_custom_kokkos(int index, double temp_thermal,
72                                             double temp_rot, double temp_vib,
73                                             double *)
74 {
75   auto &d_vibmode = k_eiarray.d_view[d_ewhich[vibmodeindex]].k_view.d_view;
76 
77   int isp = d_particles[index].ispecies;
78   int nmode = d_species[isp].nvibmode;
79 
80   // no modes, just return
81 
82   if (nmode == 0) return;
83 
84   // single mode, evib already set by Particle::evib()
85   // just convert evib back to mode level
86 
87   if (nmode == 1) {
88     d_vibmode(index,0) = static_cast<int>
89       (d_particles[index].evib / boltz /
90        d_species[isp].vibtemp[0]);
91     return;
92   }
93 
94   // loop over modes and populate each
95   // accumlate new total evib
96 
97   int ivib;
98   double evib = 0.0;
99 
100   rand_type rand_gen = rand_pool.get_state();
101 
102   for (int imode = 0; imode < nmode; imode++) {
103     const int ivib = static_cast<int> (-log(rand_gen.drand()) * temp_vib /
104                                        d_species[isp].vibtemp[imode]);
105     d_vibmode(index,imode) = ivib;
106     evib += ivib * boltz * d_species[isp].vibtemp[imode];
107   }
108 
109     rand_pool.free_state(rand_gen);
110 
111   d_particles[index].evib = evib;
112 }
113 
114 }
115 
116 #endif
117 #endif
118