main.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // This code simulates the fluid-structure interaction between an incompressible water
  2. // flow in a microchannel and two micropillars. The micropillars are modeled as elastic
  3. // structures. Small-strain geometric nonlinearity is taken into account.
  4. // A monolithic fluid-structure coupling is used. A smooth mesh deformation is obtained
  5. // by solving a Laplace formulation.
  6. // ALE can be used as an alternative to solve this FSI problem.
  7. //
  8. // A parabolic normal flow velocity is forced at the inlet and
  9. // a zero pressure is imposed at the outlet.
  10. //
  11. //
  12. // The microchannel geometry is as follows (l = 350 um, h = 120 um):
  13. //
  14. // l
  15. // <------------------------------------------------------------------>
  16. // ________________________________ ________________________________
  17. // | |
  18. // /|\ | | OUTLET
  19. // | | |
  20. // | | |
  21. // | __ | |
  22. // | | | PILLARS |__|
  23. // | | |
  24. // | | |
  25. // INLET | | |
  26. // \|/ h | |
  27. // _________________| |_______________________________________________
  28. #include "sparselizardbase.h"
  29. using namespace mathop;
  30. void sparselizard(void)
  31. {
  32. // The domain regions as defined in 'fsimicropillar.geo':
  33. int fluid = 1, solid = 2, inlet = 3, outlet = 4, sides = 5, clamp = 6;
  34. // Load the mesh file (the mesh can be curved):
  35. mesh mymesh("fsimicropillar.msh");
  36. // Define the fluid-structure interface:
  37. int fsinterface = regionintersection({fluid, solid});
  38. // Confirm that the normal at the interface is pointing outwards to the pillars:
  39. normal(fsinterface).write(fsinterface, "normal.pos");
  40. // Field v is the flow velocity. It uses nodal shape functions "h1" with two components in 2D.
  41. // Field p is the relative pressure. Field u is the mechanical deflection. Field umesh stores
  42. // the smoothed mesh deformation while field y is the y coordinate.
  43. field v("h1xy"), p("h1"), u("h1xy"), umesh("h1xy"), y("y");
  44. // Force a no-slip (0 velocity) condition on the non-moving walls:
  45. v.setconstraint(sides);
  46. // Force the fluid flow at the fluid-structure interface to zero (no-slip condition for static simulation, dt(u) = 0):
  47. v.setconstraint(fsinterface);
  48. // Force a y-parabolic inflow velocity in the x direction at the inlet.
  49. // The channel height is h [m].
  50. double h = 120e-6;
  51. v.setconstraint(inlet, array2x1( 0.03 * 4.0/(h*h)*y*(h-y), 0));
  52. // Set a 0 relative pressure [Pa] at the outlet:
  53. p.setconstraint(outlet);
  54. // The pillars are clamped at their bottom side:
  55. u.setconstraint(clamp);
  56. // Use an order 1 interpolation for p and 2 for v on the fluid region (satisfies the BB condition).
  57. // Use order 2 for u on the solid region.
  58. p.setorder(fluid, 1); v.setorder(fluid, 2); u.setorder(solid, 2);
  59. umesh.setorder(fluid, 2); umesh.setorder(solid, 2);
  60. // Mesh deformation field umesh is forced to 0 on the fluid boundary,
  61. // to u on the solid and smoothed with a Laplace formulation in the fluid.
  62. umesh.setconstraint(regionunion({inlet,outlet,sides})); umesh.setconstraint(solid, u);
  63. // Classical Laplace formulation for each component:
  64. formulation laplacian;
  65. laplacian += integral(fluid, grad(dof(compx(umesh)))*grad(tf(compx(umesh))) + grad(dof(compy(umesh)))*grad(tf(compy(umesh))) );
  66. // This is needed to add the degrees of freedom in the solid region to the formulation:
  67. laplacian += integral(solid, dof(umesh)*tf(umesh) );
  68. // Dynamic viscosity of water [Pa.s] and density [kg/m3]:
  69. double mu = 8.9e-4, rhof = 1000;
  70. // Mechanical properties. Young's modulus E [Pa], Poisson's ratio nu [] and the density rho [kg/m3]:
  71. double E = 1e6, nu = 0.3, rhos = 2000;
  72. // Define the weak formulation for the fluid-structure interaction:
  73. formulation fsi;
  74. // Classical elasticity with small-strain geometric nonlinearity (obtained with the extra u argument). Update argument 0.0 to add prestress.
  75. fsi += integral(solid, predefinedelasticity(dof(u), tf(u), u, E, nu, 0.0, "planestrain"));
  76. // Define the weak formulation for time-independent incompressible laminar flow (on the mesh deformed by 'umesh'):
  77. fsi += integral(fluid, umesh, predefinednavierstokes(dof(v), tf(v), v, dof(p), tf(p), mu, rhof, 0, 0, false) );
  78. // Add the hydrodynamic load pI - mu*( grad(v) + transpose(grad(v)) ) normal to the FSI interface (on the mesh deformed by 'umesh').
  79. // The gradient in the viscous force term has to be evaluated on the fluid elements (here with a call to 'on').
  80. fsi += integral(fsinterface, umesh, ( p * -normal(fsinterface) - on(fluid, mu*( grad(v) + transpose(grad(v)) ) ) * -normal(fsinterface) ) * tf(u) );
  81. double uprev = 0, umax = 1;
  82. while (std::abs(umax-uprev)/std::abs(umax) > 1e-6)
  83. {
  84. // Solve the fluid-structure interaction and the Laplace formulation to smooth the mesh.
  85. // The fields are updated in each 'solve' call.
  86. solve(fsi);
  87. solve(laplacian);
  88. // Output the max pillar deflection:
  89. uprev = umax;
  90. umax = norm(u).max(solid, 5)[0];
  91. std::cout << "Max pillar deflection (relative change): " << umax*1e6 << " um (" << std::abs(umax-uprev)/std::abs(umax) << ")" << std::endl;
  92. }
  93. // Write the fields to ParaView .vtk format:
  94. u.write(solid, "u.vtk", 2);
  95. // Write v on the deformed mesh:
  96. v.write(fluid, umesh, "v.vtk", 2);
  97. // Code validation line. Can be removed.
  98. std::cout << (umax < 8.384e-06 && umax > 8.383e-06);
  99. }
  100. int main(void)
  101. {
  102. SlepcInitialize(0,{},0,0);
  103. sparselizard();
  104. SlepcFinalize();
  105. return 0;
  106. }