// This code simulates in time the laminar, incompressible air flow around a cylinder. // The forced input air velocity is linearly increased over time from 0 m/s to 0.15 m/s. // Once the air velocity reaches a threshold value a von Karman vortex street appears. // The cylinder has a diameter of 14 cm and the truncated air domain is 2 m x 0.8 m. // // The Reynolds number (rho*v*D/mu) is 1400 for the max 0.15 m/s velocity. // // - rho is the density of air [kg/m3] // - v is the flow velocity far from the cylinder [m/s] // - D is the cylinder diameter [m] // - mu is the dynamic viscosity of air [Pa.s] #include "sparselizardbase.h" using namespace mathop; void sparselizard(void) { // Region numbers used in this simulation as defined in the .msh file: int fluid = 1, cylinder = 2, inlet = 3, outlet = 4; // Load the mesh (GMSH format): mesh mymesh("channel.msh"); // Define the cylinder skin region: int cylskin = regionintersection({fluid,cylinder}); // Field v is the flow velocity. It uses nodal shape functions "h1" with two components in 2D. // Field p is the relative pressure. field v("h1xy"), p("h1"); // Force the flow velocity to 0 on the cylinder skin: v.setconstraint(cylskin); // Force a x-direction flow velocity increasing linearly over time at the inlet: v.setconstraint(inlet, array2x1(0.01/6.0*t(),0)); // Set a 0 relative pressure at the outlet: p.setconstraint(outlet); // Use an order 1 interpolation for p and 2 for v on the fluid region (satisfies the BB condition): p.setorder(fluid, 1); v.setorder(fluid, 2); // Dynamic viscosity of air [Pa.s] and density [kg/m3] at room temperature and atmospheric pressure: double mu = 18e-6, rho = 1.2; // Define the weak formulation for time-dependent incompressible laminar flow: formulation laminarflow; laminarflow += integral(fluid, predefinednavierstokes(dof(v), tf(v), v, dof(p), tf(p), mu, rho, 0, 0, true) ); // Define the object for an implicit Euler time resolution. // An all zero initial guess for the fields and their time derivative is set with 'vec(laminarflow)'. impliciteuler eul(laminarflow, vec(laminarflow), vec(laminarflow)); // Set the relative tolerance on the inner nonlinear iteration: eul.settolerance(1e-4); // Run from 0sec to 90sec by steps of 0.2sec: std::vector sols = eul.runnonlinear(0, 0.2, 90)[0]; for (int i = 0; i < sols.size(); i++) { // Transfer the solution at the ith timestep to field v: v.setdata(fluid, sols[i]); // Write field v with an order 2 interpolation to ParaView .vtk format: v.write(fluid, "v" + std::to_string(1000 + i) + ".vtk", 2); } } int main(void) { SlepcInitialize(0,{},0,0); sparselizard(); SlepcFinalize(); return 0; }