quadgrid 0.1
simple cartesian quad grid with particles for c++/octave
Loading...
Searching...
No Matches
grid_velocity_field_thrust.cpp File Reference
#include <json.hpp>
#include <particles.h>
#include <fstream>
#include <iostream>
#include <map>
#include <random>
#include <vector>
#include "counter.h"
#include <timer.h>
#include <quadgrid_config.h>

Go to the source code of this file.

Classes

class  stepper< PVAR_t >
 Functor class for moving particles. More...

Functions

int main ()
 main implementing the time loop.

Function Documentation

◆ main()

int main ( )

main implementing the time loop.

Definition at line 69 of file grid_velocity_field_thrust.cpp.

69 {
70
71 cdf::timer::timer_t timer;
72
73 // read data from file
74 constexpr auto filename = "velocity.json";
75
76 nlohmann::json j;
77 std::ifstream inbuf (filename);
78
79// Declaration of host and device variables (only if thrust is used)
80 #ifdef USE_THRUST
81 inbuf >> j;
83 std::unique_ptr<quadgrid_t<vector_t<real_t>>> qg;
84 std::unique_ptr<particles_t> p;
85 qg = std::make_unique<quadgrid_t<vector_t<real_t>>> (j["grid_properties"]);
86 p = std::make_unique<particles_t> (j, *qg);
87
88 p->build_mass();
89 p->init_particle_mesh();
90
91 std::map<std::string, vector_t<real_t>> vars=
92 j["grid_vars"].get<std::map<std::string, vector_t<real_t>>> ();
93
94 //Copy from host to device
95 p->memcpy_host_to_device();
96
97 for (const auto & g : vars)
98 p->device_grid_vars[g.first] = g.second;
99
100 inbuf.close ();
101
102 // Create the callable object to be used for moving the particles
103 // capture references to the particle positions and velocities
104 stepper state (thrust::raw_pointer_cast(p->device_x.data()), thrust::raw_pointer_cast(p->device_y.data()), thrust::raw_pointer_cast(p->device_dprops["VX"].data()), thrust::raw_pointer_cast(p->device_dprops["VY"].data()), 1., 1.e-5);
105
106// Create iterator for thrust::for_each
107 thrust::counting_iterator<idx_t> first_p(0), last_p(p -> num_particles);
108
109 #else
110 inbuf >> j;
111
112 // create grid from fields in a json object
113 quadgrid_t<vector_t<real_t>> qg (j["grid_properties"]);
114
115 // create particles from properties in the json object
116 // and the above created grid
117 particles_t p (j, qg);
118
119 // as we will use the mass matrix we must initialize it manually
120 p.build_mass ();
121
122 // the variables defined on the grid are not class members
123 std::map<std::string, vector_t<real_t>> vars=
124 j["grid_vars"].get<std::map<std::string, vector_t<real_t>>> ();
125
126 inbuf.close ();
127
128 // Diffusion is modelled as a Gaussian process
129 /*std::random_device rd2; // Will be used to obtain a seed for the random number engine
130 std::mt19937 gen2;
131 std::normal_distribution<> normal;
132 std::function<real_t ()> noise = [&gen2, &rd2, &normal] () { return normal(gen2); };*/
133
134 // Create the callable object to be used for moving the particles
135 // capture references to the particle positions and velocities
136 stepper state (p.x.data(), p.y.data(), p.dprops["VX"].data(), p.dprops["VY"].data(), 1., 1.e-5);
137
138 // Create particle <-> grid connectivity
139 // must be updated explicitely
140 p.init_particle_mesh ();
141
142 #endif
143
144
145 // Time stepping
146 for (int it = 0; it < 1000; ++it) {
147
148 #ifdef USE_THRUST
149 thrust::fill(p->device_dprops["VX"].begin (), p->device_dprops["VX"].end (), 0.0);
150 thrust::fill(p->device_dprops["VX"].begin (), p->device_dprops["VY"].end (), 0.0);
151 thrust::fill(p->device_grid_vars["rho"].begin (), p->device_grid_vars["rho"].end (), 0.0);
152 #else
153 // Clean up grid variables at each step!
154 std::fill(p.dprops["VX"].begin (), p.dprops["VX"].end (), 0.0);
155 std::fill(p.dprops["VY"].begin (), p.dprops["VY"].end (), 0.0);
156 std::fill(vars["rho"].begin (), vars["rho"].end (), 0.0);
157 #endif
158
159 // G2P : interpolate velocity at particle positions
160 timer.tic("g2p");
161 #ifdef USE_THRUST
162 p->g2p(p->device_grid_vars, {"vx", "vy"}, {"VX", "VY"});
163 #else
164 p.g2p (vars, {"vx", "vy"}, {"VX", "VY"});
165 #endif
166
167 timer.toc("g2p");
168
169 // Move particles
170 timer.tic("move partcles");
171
172 // You can use a loop
173 // for (int ip = 0; ip < p.num_particles; ++ip) {
174 // state(ip);
175 // }
176
177 // Or use an STL algorithm
178 #ifdef USE_THRUST
179 thrust::for_each(thrust::device, first_p, last_p, state);
180 #else
181 // Or use an STL algorithm
182 range rng (0, p.num_particles);
183 std::for_each (rng.begin (), rng.end (), state);
184 #endif
185
186
187 timer.toc("move partcles");
188
189 // Rebuild particle <-> grid connectivity
190 // must be updated explicitely
191 timer.tic("init_particle_mesh");
192 #ifdef USE_THRUST
193 p->update_ptcl_to_grd<particles_t::update_ptcl_to_grd_device>();
194 #else
195 p.update_ptcl_to_grd<particles_t::update_ptcl_to_grd_host>();
196 #endif
197
198 timer.toc("init_particle_mesh");
199
200 // Project particle masses onto the greed and
201 // build a density field, only used for output
202 timer.tic("p2g");
203 #ifdef USE_THRUST
204 p->p2g (p->device_grid_vars, {"M"}, {"rho"}, true);
205 #else
206 p.p2g (vars, {"M"}, {"rho"}, true);
207 #endif
208
209 timer.toc("p2g");
210
211 // Don't save at every timestep
212 if (it % 50 == 0) {
213 #ifdef USE_THRUST
214 p->memcpy_device_to_host();
215 //The following copy cannot be included in the memcpy function since vars is not defined in particles.h
216 thrust::copy (p->device_grid_vars["rho"].cbegin(), p->device_grid_vars["rho"].cend(), vars.at("rho").begin());
217
218 // write particle data to file
219 const std::string ofilename = "particle";
220 const std::string ofileext = ".csv";
221 const std::string numfile = std::string(".") + std::to_string(it);
222
223 std::ofstream outbuf (ofilename + numfile + ofileext);
224 p->print<particles_t::output_format::csv> (outbuf);
225
226 outbuf.close ();
227
228 // write grid data to file
229 const std::string gfilename = std::string("grid.") + std::to_string(it) + std::string(".vts");
230 qg->vtk_export (gfilename.c_str(), vars);
231 #else
232 // write particle data to file
233 const std::string ofilename = "particle";
234 const std::string ofileext = ".csv";
235 const std::string numfile = std::string(".") + std::to_string(it);
236
237 std::ofstream outbuf (ofilename + numfile + ofileext);
238 p.print<particles_t::output_format::csv> (outbuf);
239
240 outbuf.close ();
241
242 // write grid data to file
243 const std::string gfilename = std::string("grid.") + std::to_string(it) + std::string(".vts");
244 qg.vtk_export (gfilename.c_str(), vars);
245 #endif
246
247 }
248 }
249
250 // print timing information
251 timer.print_report();
252 return 0;
253}
Functor class for moving particles.
Class to represent particles embedded in a grid.
Definition particles.h:29
quadgrid_t< vector_t< real_t > >::idx_t idx_t
datatype for indexing into vectors of properties
Definition particles.h:32
Definition counter.h:7