quadgrid 0.1
simple cartesian quad grid with particles for c++/octave
Loading...
Searching...
No Matches
grid_velocity_field.cpp
Go to the documentation of this file.
1
2
3#include <json.hpp>
4#include <particles.h>
5
6#include <fstream>
7#include <iostream>
8#include <map>
9#include <random>
10#include <vector>
11
12#include "counter.h"
13#include <timer.h>
14
16
21class
22stepper {
23private :
24 std::vector<double> &x;
25 std::vector<double> &y;
26 std::vector<double> &vx;
27 std::vector<double> &vy;
28
29 double dt, D;
30 std::function<double (void)> normal;
31
32public :
33
34 stepper (std::vector<double> &x_, std::vector<double> &y_,
35 std::vector<double> &vx_, std::vector<double> &vy_,
36 double dt_, double D_, std::function<double (void)> &noise_)
37 : x(x_), y(y_), vx(vx_), vy(vy_), dt{dt_}, D{D_}, normal(noise_) { }
38
40
46 void operator() (int n) {
47 double dxb, dyb;
48
49 //Brownian motion displacements
50 dxb=std::sqrt (2*D*dt) * normal();
51 dyb=std::sqrt (2*D*dt) * normal();
52
53 //update particles positions
54 x[n] += vx[n] * dt + dxb;
55 y[n] += vy[n] * dt + dyb;
56
57 // Apply boundary conditions (unelastic walls)
58 y[n] = std::min (1.999, std::max (0.001, y[n]));
59 x[n] = std::min (1.999, std::max (0.001, x[n]));
60 }
61
62};
63
64
66
67int
68main () {
69
70 cdf::timer::timer_t timer;
71
72 // read data from file
73 constexpr auto filename = "velocity.json";
74
75 nlohmann::json j;
76 std::ifstream inbuf (filename);
77 inbuf >> j;
78
79 // create grid from fields in a json object
80 quadgrid_t<std::vector<double>> qg (j["grid_properties"]);
81
82 // create particles from properties in the json object
83 // and the above created grid
84 particles_t p (j, qg);
85
86 // as we will use the mass matrix we must initialize it manually
87 p.build_mass ();
88
89 // the variables defined on the grid are not class members
90 std::map<std::string, std::vector<double>> vars=
91 j["grid_vars"].get<std::map<std::string, std::vector<double>>> ();
92
93 inbuf.close ();
94
95 // Diffusion is modelled as a Gaussian process
96 std::random_device rd2; // Will be used to obtain a seed for the random number engine
97 std::mt19937 gen2;
98 std::normal_distribution<> normal;
99 std::function<double ()> noise = [&gen2, &rd2, &normal] () { return normal(gen2); };
100
101 // Create the callable object to be used for moving the particles
102 // capture references to the particle positions and velocities
103 stepper state (p.x, p.y, p.dprops["VX"], p.dprops["VY"], 1., 1.e-5, noise);
104
105 // Create particle <-> grid connectivity
106 // must be updated explicitely
108
109
110 // Time stepping
111 for (int it = 0; it < 1000; ++it) {
112
113 // Clean up grid variables at each step!
114 std::fill(p.dprops["VX"].begin (), p.dprops["VX"].end (), 0.0);
115 std::fill(p.dprops["VY"].begin (), p.dprops["VY"].end (), 0.0);
116 std::fill(vars["rho"].begin (), vars["rho"].end (), 0.0);
117
118 // G2P : interpolate velocity at particle positions
119 timer.tic("g2p");
120 p.g2p (vars, {"vx", "vy"}, {"VX", "VY"});
121 timer.toc("g2p");
122
123 // Move particles
124 timer.tic("move partcles");
125
126 // You can use a loop
127 // for (int ip = 0; ip < p.num_particles; ++ip) {
128 // state(ip);
129 // }
130
131 // Or use an STL algorithm
132 range rng (0, p.num_particles);
133 std::for_each (rng.begin (), rng.end (), state);
134
135 timer.toc("move partcles");
136
137 // Rebuild particle <-> grid connectivity
138 // must be updated explicitely
139 timer.tic("init_particle_mesh");
141 timer.toc("init_particle_mesh");
142
143 // Project particle masses onto the greed and
144 // build a density field, only used for output
145 timer.tic("p2g");
146 p.p2g (vars, {"M"}, {"rho"}, true);
147 timer.toc("p2g");
148
149 // Don't save at every timestep
150 if (it % 50 == 0) {
151
152 // write particle data to file
153 const std::string ofilename = "particle";
154 const std::string ofileext = ".csv";
155 const std::string numfile = std::string(".") + std::to_string(it);
156
157 std::ofstream outbuf (ofilename + numfile + ofileext);
159
160 outbuf.close ();
161
162 // write grid data to file
163 const std::string gfilename = std::string("grid.") + std::to_string(it) + std::string(".vts");
164 qg.vtk_export (gfilename.c_str(), vars);
165
166 }
167 }
168
169 // print timing information
170 timer.print_report();
171 return 0;
172}
void vtk_export(const char *filename, const std::map< std::string, distributed_vector > &f) const
Functor class for moving particles.
std::vector< double > & vx
stepper(std::vector< double > &x_, std::vector< double > &y_, std::vector< double > &vx_, std::vector< double > &vy_, double dt_, double D_, std::function< double(void)> &noise_)
std::vector< double > & y
std::function< double(void)> normal
std::vector< double > & x
std::vector< double > & vy
int main()
main implementing the time loop.
Class to represent particles embedded in a grid.
Definition particles.h:29
void p2g(std::map< std::string, device_vector_t< real_t > > &vars, bool apply_mass=false)
Map particle variables to the grid.
Definition particles.h:331
void g2p(const std::map< std::string, device_vector_t< real_t > > &vars, bool apply_mass=false)
Definition particles.h:401
idx_t num_particles
number of particles.
Definition particles.h:34
void init_particle_mesh()
Build grid/particles connectivity.
void print(std::ostream &os) const
Template for export function.
Definition particles.h:109
vector_t< real_t > x
x coordinate of particle positions.
Definition particles.h:35
std::map< std::string, vector_t< real_t > > dprops
double type quantities associated with the particles.
Definition particles.h:42
vector_t< real_t > y
y coordinate of particle positions.
Definition particles.h:36
void build_mass()
Construct a mass matrix.
Definition counter.h:7
iterator begin() const
Definition counter.h:33
iterator end() const
Definition counter.h:34