35using namespace navier;
48 int paraview_freq = 500;
51 int add_particles_freq = 300;
52 int num_add_particles = 100;
57 int print_csv_freq = 500;
60 bool visualization =
true;
66 int traj_len_update_freq = 0;
83int main(
int argc,
char *argv[])
92 args.
AddOption(&
ctx.dt,
"-dt",
"--time-step",
"Time step.");
93 args.
AddOption(&
ctx.nt,
"-nt",
"--num-timesteps",
"Number of time steps.");
95 "Number of times to refine the mesh in serial.");
97 "Order (degree) of the finite elements.");
98 args.
AddOption(&
ctx.Re,
"-Re",
"--reynolds-number",
"Reynolds number.");
99 args.
AddOption(&
ctx.paraview_freq,
"-pv",
"--paraview-freq",
100 "ParaView data collection write frequency. 0 to disable.");
101 args.
AddOption(&
ctx.visualization,
"-vis",
"--visualization",
"-no-vis",
102 "--no-visualization",
103 "Enable or disable GLVis visualization.");
104 args.
AddOption(&
ctx.add_particles_freq,
"-ipf",
"--inject-particles-freq",
105 "Frequency of particle injection at domain inlet.");
106 args.
AddOption(&
ctx.num_add_particles,
"-npt",
"--num-particles-inject",
107 "Number of particles to add each injection.");
109 "Kappa constant minimum.");
111 "Kappa constant maximum.");
112 args.
AddOption(&
ctx.gamma,
"-g",
"--gamma",
"Gamma constant.");
113 args.
AddOption(&
ctx.zeta,
"-z",
"--zeta",
"Zeta constant.");
114 args.
AddOption(&
ctx.print_csv_freq,
"-csv",
"--csv-freq",
115 "Frequency of particle CSV outputting. 0 to disable.");
116 args.
AddOption(&
ctx.traj_len_update_freq,
"-traj",
"--traj-freq",
117 "Frequency of particle trajectory update. 0 to disable.");
130 Mesh mesh(
"../../data/channel-bifurcation-2d.mesh");
131 for (
int lev = 0; lev <
ctx.rs_levels; lev++)
137 ParMesh pmesh(MPI_COMM_WORLD, mesh);
165 int nparticles = (
ctx.nt/
ctx.add_particles_freq) *
187 int Ww = 500,
Wh = 500;
189 char keys[] =
"mAcRjlmm]]]]]]]]]";
190 std::unique_ptr<ParticleTrajectories> traj_vis;
194 for (
int i = 0; i < nattr; i++)
196 subdomain_attributes[i] = i+1;
198 auto psubmesh = std::unique_ptr<ParMesh>(
new ParMesh(
201 if (
ctx.visualization)
206 if (
ctx.traj_len_update_freq > 0)
209 traj_vis = std::make_unique<ParticleTrajectories>(
212 "Particle Trajectories",
214 traj_vis->AddMeshForVisualization(psubmesh.get());
215 traj_vis->Visualize();
221 std::unique_ptr<ParaViewDataCollection> pvdc;
222 if (
ctx.paraview_freq > 0)
224 pvdc = std::make_unique<ParaViewDataCollection>(
"Bifurcation", &pmesh);
225 pvdc->SetPrefixPath(
"ParaView");
226 pvdc->SetLevelsOfDetail(
ctx.order);
227 pvdc->SetDataFormat(VTKFormat::BINARY);
228 pvdc->SetHighOrderOutput(
true);
237 std::string csv_prefix =
"Navier_Bifurcation_";
244 if (
ctx.print_csv_freq > 0)
246 std::string file_name = csv_prefix +
262 for (
int step = 1; step <=
ctx.nt; step++)
264 flow_solver.
Step(time,
ctx.dt, step-1);
268 if (step %
ctx.add_particles_freq == 0)
271 int rank_num_particles =
ctx.num_add_particles/size +
272 (rank < (
ctx.num_add_particles % size) ?
279 ctx.kappa_min,
ctx.kappa_max,
280 (rank+1)*step,
ctx.zeta,
ctx.gamma, step);
283 particle_solver.
Step(
ctx.dt, u_gf, w_gf);
286 if (
ctx.print_csv_freq > 0 && step %
ctx.print_csv_freq == 0)
289 std::string file_name = csv_prefix +
298 if (
ctx.paraview_freq > 0 && step %
ctx.paraview_freq == 0)
300 pvdc->SetTime(vis_count);
301 pvdc->SetCycle(step);
306 if (
ctx.visualization)
311 if (
ctx.traj_len_update_freq > 0 &&
312 step %
ctx.traj_len_update_freq == 0)
314 traj_vis->Visualize();
322 auto inactive_global_np =
327 printf(
"\n%-11s %-11s %-11s %-11s\n",
"Step",
"Time",
"dt",
"CFL");
328 printf(
"%-11i %-11.5E %-11.5E %-11.5E\n", step, time,
ctx.dt, cfl);
330 printf(
"\n%16s: %-9llu\n",
"Active Particles", global_np);
331 printf(
"%16s: %-9llu\n",
"Lost Particles", inactive_global_np);
333 printf(
"-----------------------------------------------\n");
346 real_t kappa_max,
int kappa_seed,
352 MPI_Comm_rank(comm, &my_rank);
354 rand_init_yloc.
Randomize(my_rank + step);
355 for (
int i = 0; i < p_idxs.
Size(); i++)
359 for (
int j = 0; j < 4; j++)
364 real_t yval = rand_init_yloc(i);
379 std::mt19937 gen(kappa_seed);
380 std::uniform_real_distribution<> real_dist(0.0,1.0);
381 particle_solver.
Kappa()[idx] = kappa_min + real_dist(gen)*
382 (kappa_max - kappa_min);
383 particle_solver.
Zeta()[idx] = zeta;
384 particle_solver.
Gamma()[idx] = gamma;
388 particle_solver.
Order()[idx] = 0;
400 if (std::fabs(yi)<1.0) {
u(0) = 6.0*yi*(height-yi)/(height*height); }
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
int Size() const
Return the logical size of the array.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void EnsureNodes()
Make sure that the mesh has valid nodes, i.e. its geometry is described by a vector finite element gr...
void Clear()
Clear the contents of the Mesh.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
static int WorldRank()
Return the MPI rank in MPI_COMM_WORLD.
static int WorldSize()
Return the size of MPI_COMM_WORLD.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
bool Good() const
Return true if the command line options were parsed successfully.
Class for parallel grid function.
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Class for parallel meshes.
static ParSubMesh CreateFromBoundary(const ParMesh &parent, const Array< int > &boundary_attributes)
Create a surface ParSubMesh from its parent.
MPI_Comm GetComm() const
Get the MPI communicator for this ParticleSet.
IDType GetGlobalNParticles() const
Get the global number of active particles across all ranks.
void PrintCSV(const char *fname, int precision=16)
Print all particle data to a comma-delimited CSV file.
void Reserve(int res)
Reserve memory for res particles.
void AddParticles(const Array< IDType > &new_ids, Array< int > *new_indices=nullptr)
Add particles with global identifiers new_ids and optionally get the local indices of new particles i...
void SetValues(int i, const Vector &nvals)
Set particle i 's data to nvals .
virtual void SetTime(real_t t)
Set the time for time dependent coefficients.
A general vector function coefficient.
void Randomize(int seed=0)
Set random values in the vector.
Transient Navier-Stokes fluid-particles solver.
ParticleVector & V(int nm=0)
Get reference to the particle velocity ParticleVector at time n - nm .
ParticleVector & W(int nm=0)
Get reference to the fluid vorticity-interpolated ParticleVector at time n - nm .
Array< int > & Order()
Get reference to the order Array<int>.
ParticleVector & U(int nm=0)
Get reference to the fluid velocity-interpolated ParticleVector at time n - nm .
ParticleSet & GetInactiveParticles()
Get reference to the inactive ParticleSet.
ParticleSet & GetParticles()
Get reference to the active ParticleSet.
ParticleVector & X(int nm=0)
Get reference to the position ParticleVector at time n - nm .
void Setup(const real_t dt)
Set initial timestep in time history array.
void Add2DReflectionBC(const Vector &line_start, const Vector &line_end, real_t e, bool invert_normal)
Add a 2D wall reflective boundary condition.
ParticleVector & Gamma()
Get reference to the γ ParticleVector.
void Step(const real_t dt, const ParGridFunction &u_gf, const ParGridFunction &w_gf)
Step the particles in time.
ParticleVector & Kappa()
Get reference to the κ ParticleVector.
ParticleVector & Zeta()
Get reference to the ζ ParticleVector.
Transient incompressible Navier Stokes solver in a split scheme formulation.
void Setup(real_t dt)
Initialize forms, solvers and preconditioners.
real_t ComputeCFL(ParGridFunction &u, real_t dt)
Compute CFL.
void AddVelDirichletBC(VectorCoefficient *coeff, Array< int > &attr)
Add a Dirichlet boundary condition to the velocity field.
ParGridFunction * GetCurrentVorticity()
Return a pointer to the current vorticity ParGridFunction.
void PrintTimingData()
Print timing summary of the solving routine.
void EnablePA(bool pa)
Enable partial assembly for every operator.
ParGridFunction * GetCurrentVelocity()
Return a pointer to the current velocity ParGridFunction.
void Step(real_t &time, real_t dt, int cur_step, bool provisional=false)
Compute solution at the next time step t+dt.
void VisualizeField(socketstream &sock, const char *vishost, int visport, GridFunction &gf, const char *title, int x, int y, int w, int h, const char *keys, bool vec)
real_t u(const Vector &xvec)
std::string to_padded_string(int i, int digits)
Convert an integer to a 0-padded string with the given number of digits.
void SetInjectedParticles(NavierParticles &particle_solver, const Array< int > &p_idxs, real_t kappa_min, real_t kappa_max, int kappa_seed, real_t zeta, real_t gamma, int step)
void vel_dbc(const Vector &x, real_t t, Vector &u)
Fluid data.