quadgrid 0.1
simple cartesian quad grid with particles for c++/octave
Loading...
Searching...
No Matches
grid_velocity_field_comsol.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>

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 88 of file grid_velocity_field_comsol.cpp.

88 {
89
90 cdf::timer::timer_t timer;
91
92 // read data from file
93 constexpr auto filename = "velocity_comsol.json";
94
95 nlohmann::json j;
96 std::ifstream inbuf (filename);
97 inbuf >> j;
98
99 // create grid from fields in a json object
100 quadgrid_t<std::vector<double>> qg (j["grid_properties"]);
101
102 // create particles from properties in the json object
103 // and the above created grid
104 particles_t p (j, qg);
105
106 // as we will use the mass matrix we must initialize it manually
107 p.build_mass ();
108
109 // the variables defined on the grid are not class members
110 std::map<std::string, std::vector<double>> vars=
111 j["grid_vars"].get<std::map<std::string, std::vector<double>>> ();
112
113 inbuf.close ();
114
115 // Diffusion is modelled as a Gaussian process
116 std::random_device rd2; // Will be used to obtain a seed for the random number engine
117 std::mt19937 gen2;
118 std::normal_distribution<> normal;
119 std::function<double ()> noise = [&gen2, &rd2, &normal] () { return normal(gen2); };
120
121
122 // Create particle <-> grid connectivity
123 // must be updated explicitely
124 p.init_particle_mesh ();
125
126
127 // Create the callable object to be used for moving the particles
128 // capture references to the particle positions and velocities
129 stepper state (p.x, p.y, p.dprops["VX"], p.dprops["VY"], p.dprops["DIST"],
130 p.dprops["DIST_DX"], p.dprops["DIST_DY"], qg.hx(), qg.hy(),
131 1.e-3, 1.e-1, noise);
132
133 p.g2p (vars, {"vx", "vy", "dist"}, {"VX", "VY", "DIST"});
134
135 constexpr int nsave = 300;
136 constexpr double tmax = 2 * 8.5 / 40.;
137 constexpr double dtsave = tmax / nsave;
138 double t = 0.;
139
140 // Time stepping
141 for (int isave = 0; isave < nsave; ++isave) {
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 timer.tic("save particles");
150 // write particle data to file
151 const std::string ofilename = "particle";
152 const std::string ofileext = ".csv";
153 const std::string numfile = std::string(".") + std::to_string(isave);
154
155 std::ofstream outbuf (ofilename + numfile + ofileext);
156 p.print<particles_t::output_format::csv> (outbuf);
157 outbuf.close ();
158 timer.toc("save particles");
159
160 // write grid data to file
161 timer.tic("save grid");
162 const std::string gfilename = std::string("grid.") + std::to_string(isave) + std::string(".vts");
163 qg.vtk_export (gfilename.c_str(), vars);
164 timer.toc("save grid");
165
166 while (t < dtsave * (isave + 1)) {
167
168 // Clean up grid variables at each step!
169
170 timer.tic("clean particle properties interpolated from grid");
171 std::fill(p.dprops["VX"].begin (), p.dprops["VX"].end (), 0.0);
172 std::fill(p.dprops["VY"].begin (), p.dprops["VY"].end (), 0.0);
173 std::fill(p.dprops["DIST"].begin (), p.dprops["DIST"].end (), 0.0);
174 std::fill(p.dprops["DIST_DX"].begin (), p.dprops["DIST_DX"].end (), 0.0);
175 std::fill(p.dprops["DIST_DY"].begin (), p.dprops["DIST_DY"].end (), 0.0);
176 timer.toc("clean particle properties interpolated from grid");
177
178 timer.tic("clean rho");
179 std::fill(vars["rho"].begin (), vars["rho"].end (), 0.0);
180 timer.toc("clean rho");
181
182 // G2P : interpolate velocity and sgd at particle positions
183 timer.tic("g2p");
184 p.g2p (vars, {"vx", "vy", "dist"}, {"VX", "VY", "DIST"});
185 timer.toc("g2p");
186
187 // Compute dt
188 timer.tic("dt");
189 auto maxvx = std::max_element (p.dprops["VX"].begin (), p.dprops["VX"].end ());
190 state.dt = .5 * qg.hx() / (*maxvx);
191 auto maxvy = std::max_element (p.dprops["VY"].begin (), p.dprops["VY"].end ());
192 state.dt = std::min (state.dt, .5 * qg.hy() / (*maxvy));
193 if (t + state.dt > dtsave * (isave + 1)) state.dt = dtsave * (isave + 1) - t;
194 std::cout << "hx = " << qg.hx() << " hy = " << qg.hy() << " vx = " << (*maxvx) << " vy = " << (*maxvy) << std::endl;
195 std::cout << "t = " << t << " dt = " << state.dt << " t + dt = " << t + state.dt << std::endl;
196 timer.toc("dt");
197
198 // G2PD : compute direction away from boundary
199 timer.tic("g2pd");
200 p.g2pd (vars, {"dist"}, {"DIST_DX"}, {"DIST_DY"});
201 timer.toc("g2pd");
202
203 // Move particles
204 timer.tic("move partcles");
205
206 // You can use a loop
207 // for (int ip = 0; ip < p.num_particles; ++ip) {
208 // state(ip);
209 // }
210
211 // Or use an STL algorithm
212 range rng (0, p.num_particles);
213 std::for_each (rng.begin (), rng.end (), state);
214
215 timer.toc("move partcles");
216
217 // Rebuild particle <-> grid connectivity
218 // must be updated explicitely
219 timer.tic("init_particle_mesh");
220 p.init_particle_mesh ();
221 timer.toc("init_particle_mesh");
222
223 t += state.dt;
224 }
225 }
226
227 // Project particle masses onto the greed and
228 // build a density field, only used for output
229 timer.tic("p2g");
230 p.p2g (vars, {"M"}, {"rho"}, true);
231 timer.toc("p2g");
232
233 timer.tic("save particles");
234 // write particle data to file
235 const std::string ofilename = "particle";
236 const std::string ofileext = ".csv";
237 const std::string numfile = std::string(".") + std::to_string(nsave);
238
239 std::ofstream outbuf (ofilename + numfile + ofileext);
240 p.print<particles_t::output_format::csv> (outbuf);
241 outbuf.close ();
242 timer.toc("save particles");
243
244 // write grid data to file
245 timer.tic("save grid");
246 const std::string gfilename = std::string("grid.") + std::to_string(nsave) + std::string(".vts");
247 qg.vtk_export (gfilename.c_str(), vars);
248 timer.toc("save grid");
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
Definition counter.h:7