// This code simulates the Stokes flow of a viscous fluid (water) in a microvalve. // Reynold's number rho*v*L/mu is very low so that the inertia terms can be neglected. // The fluid is considered incompressible. // // This code can be validated with analytical solutions of a flow between two // infinite parallel plates with a thin gap. Only the geometry has to be adapted. #include "sparselizardbase.h" using namespace mathop; mesh createmesh(void); void sparselizard(void) { // Define the physical regions that will be used: int support = 1, fluid = 2, pillar = 3, membrane = 4, inlet = 7, outlet = 8; // Create the geometry and the mesh: mesh mymesh = createmesh(); // Write the mesh for display: mymesh.write("microvalve.msh"); // Define the fluid boundary as the intersection between the solid and the fluid regions: int solid = regionunion({pillar,support,membrane}); int fluidboundary = regionintersection({fluid,solid}); // Dynamic viscosity of water [Pa.s] and density [kg/m3]: double mu = 8.9e-4, rho = 1000; // Field v is the flow velocity. It uses nodal shape functions "h1" with two components. // Field p is the relative pressure. field v("h1xy"), p("h1"); // Force the flow velocity to 0 at the solid interface: v.setconstraint(fluidboundary); // Set a relative pressure of 100 Pa at the valve inlet and 0 at the outlet: p.setconstraint(inlet, 100); p.setconstraint(outlet); // Use an order 1 interpolation for p and 2 for v on the fluid region: p.setorder(fluid, 1); v.setorder(fluid, 2); // Define the weak formulation of the Stokes flow problem. // The strong form can be found at https://en.wikipedia.org/wiki/Stokes_flow formulation viscousflow; viscousflow += integral(fluid, predefinedstokes(dof(v), tf(v), dof(p), tf(p), mu, rho, 0, 0) ); // Generate, solve and save: solve(viscousflow); // Write the p and v fields to file. Write v with an order 2 interpolation. p.write(fluid, "p.vtk"); v.write(fluid, "v.vtk", 2); // Output the flowrate for a unit width: double flowrate = (normal(inlet)*v).integrate(inlet, 4); std::cout << std::endl << "Flowrate for a unit width: " << flowrate << " m^3/s" << std::endl; // Code validation line. Can be removed. std::cout << (flowrate < 1.4845e-7 && flowrate > 1.4844e-7); } mesh createmesh(void) { // Give names to the physical region numbers: int support = 1, fluid = 2, pillar = 3, membrane = 4, inlet = 7, outlet = 8; // Define the x and y geometrical dimensions: double y1 = 15e-6, y2 = 25e-6, y3 = 30e-6; double x1 = -100e-6, x2 = -50e-6, x3 = -25e-6, x4 = 25e-6, x5 = 50e-6, x6 = 100e-6; // Define the mesh finesse: int n = 10; shape q1("quadrangle", support, {x1,0,0, x2,0,0, x2,y1,0, x1,y1,0}, {n,n,n,n}); shape q2("quadrangle", support, {x5,0,0, x6,0,0, x6,y1,0, x5,y1,0}, {n,n,n,n}); shape q3("quadrangle", fluid, {x2,0,0, x3,0,0, x3,y1,0, x2,y1,0}, {n,n,n,n}); shape q4("quadrangle", fluid, {x4,0,0, x5,0,0, x5,y1,0, x4,y1,0}, {n,n,n,n}); shape q5("quadrangle", pillar, {x3,0,0, x4,0,0, x4,y1,0, x3,y1,0}, {n,n,n,n}); shape q6("quadrangle", support, {x1,y1,0, x2,y1,0, x2,y2,0, x1,y2,0}, {n,n,n,n}); shape q7("quadrangle", support, {x5,y1,0, x6,y1,0, x6,y2,0, x5,y2,0}, {n,n,n,n}); shape q8("quadrangle", fluid, {x2,y1,0, x3,y1,0, x3,y2,0, x2,y2,0}, {n,n,n,n}); shape q9("quadrangle", fluid, {x4,y1,0, x5,y1,0, x5,y2,0, x4,y2,0}, {n,n,n,n}); shape q10("quadrangle", fluid, {x3,y1,0, x4,y1,0, x4,y2,0, x3,y2,0}, {n,n,n,n}); shape q11("quadrangle", membrane, {x1,y2,0, x2,y2,0, x2,y3,0, x1,y3,0}, {n,n,n,n}); shape q12("quadrangle", membrane, {x5,y2,0, x6,y2,0, x6,y3,0, x5,y3,0}, {n,n,n,n}); shape q13("quadrangle", membrane, {x2,y2,0, x3,y2,0, x3,y3,0, x2,y3,0}, {n,n,n,n}); shape q14("quadrangle", membrane, {x4,y2,0, x5,y2,0, x5,y3,0, x4,y3,0}, {n,n,n,n}); shape q15("quadrangle", membrane, {x3,y2,0, x4,y2,0, x4,y3,0, x3,y3,0}, {n,n,n,n}); // Get the inlet and outlet lines: shape l1 = q3.getsons()[0]; shape l2 = q4.getsons()[0]; l1.setphysicalregion(inlet); l2.setphysicalregion(outlet); // Provide to the mesh all shapes of interest: mesh mymesh({q1,q2,q3,q4,q5,q6,q7,q8,q9,q10,q11,q12,q13,q14,q15,l1,l2}); return mymesh; } int main(void) { SlepcInitialize(0,{},0,0); sparselizard(); SlepcFinalize(); return 0; }