main.cpp 2.8 KB

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