main.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // This code creates a structured mesh for a 3D geometry of a mechanical part (a small and a bigger cylinder connected together).
  2. //
  3. // It is structured as follows:
  4. //
  5. // 1. The 2D projected surface of the geometry is created
  6. // 2. The projection is extruded
  7. // 3. A deformation function is applied to the big cylinder to get the final geometry.
  8. // 4. A mechanical simulation is performed on the geometry
  9. //
  10. // In order to identify the regions needed in the simulation the following physical region numbers are used:
  11. //
  12. // --> 1 for the whole volume
  13. // --> 2 for the bottom surface of the small cylinder (mechanical clamp)
  14. // --> 3 for the surface inside the big cylinder
  15. //
  16. // Region number -1 is used for all construction geometries (not used in the simulation).
  17. #include "sparselizardbase.h"
  18. using namespace mathop;
  19. void sparselizard(void)
  20. {
  21. // The physical region numbers as detailed above:
  22. int vol = 1, clamp = 2, faceincylinder = 3;
  23. // Define the x, y and z coordinate fields:
  24. field x("x"), y("y"), z("z");
  25. // Define pi:
  26. double pi = getpi();
  27. ///// CONSTRUCTION OF THE SMALL CYLINDER with inner and outer radius 7mm and 15mm:
  28. double smallinnerradius = 0.007, smallouterradius = 0.015;
  29. // Define the points to construct the cylinder.
  30. // Inputs are the x, y and z point coordinates.
  31. shape p1("point", -1, {0,0,0});
  32. shape p2("point", -1, {smallinnerradius*cos(45*2*pi/360), smallinnerradius*sin(45*2*pi/360), 0});
  33. shape p3("point", -1, {smallinnerradius*cos(-45*2*pi/360),smallinnerradius*sin(-45*2*pi/360),0});
  34. shape p4("point", -1, {smallouterradius*cos(45*2*pi/360), smallouterradius*sin(45*2*pi/360), 0});
  35. shape p5("point", -1, {smallouterradius*cos(-45*2*pi/360),smallouterradius*sin(-45*2*pi/360),0});
  36. // Define the arcs and the lines to construct the small cylinder.
  37. // Inputs are the first point, last point and arc center point
  38. // as well as the number of mesh nodes in the arc.
  39. shape a1("arc", -1, {p2,p3,p1}, 16);
  40. shape a2("arc", -1, {p4,p5,p1}, 16);
  41. shape a3("arc", -1, {p3,p2,p1}, 8);
  42. shape a4("arc", -1, {p5,p4,p1}, 8);
  43. shape l1("line", -1, {p2,p4}, 3);
  44. shape l2("line", -1, {p3,p5}, 3);
  45. // Define the 2 quadrangle surfaces for the small cylinder.
  46. // Inputs are the contour lines (following the contour clockwise or counter-clockwise).
  47. shape q1("quadrangle", -1, {a1,l1,a2,l2});
  48. shape q2("quadrangle", -1, {a3,l2,a4,l1});
  49. ///// CONSTRUCTION OF THE BIG CYLINDER with inner and outer radius 10mm and 30mm
  50. // around center point on x axis at x equal 100mm.
  51. double biginnerradius = 0.01, bigouterradius = 0.03;
  52. // Define the points to construct the cylinder.
  53. shape p6("point", -1, {0.1,0,0});
  54. shape p7("point", -1, {0.1-biginnerradius*cos(45*2*pi/360), biginnerradius*sin(45*2*pi/360), 0});
  55. shape p8("point", -1, {0.1-biginnerradius*cos(-45*2*pi/360),biginnerradius*sin(-45*2*pi/360),0});
  56. shape p9("point", -1, {0.1-bigouterradius*cos(45*2*pi/360), bigouterradius*sin(45*2*pi/360), 0});
  57. shape p10("point", -1, {0.1-bigouterradius*cos(-45*2*pi/360),bigouterradius*sin(-45*2*pi/360),0});
  58. // Define the arcs and the lines to construct the big cylinder.
  59. shape a5("arc", -1, {p7,p8,p6}, 8);
  60. shape a6("arc", -1, {p9,p10,p6}, 8);
  61. shape a7("arc", -1, {p8,p7,p6}, 16);
  62. shape a8("arc", -1, {p10,p9,p6}, 16);
  63. shape l3("line", -1, {p7,p9}, 5);
  64. shape l4("line", -1, {p8,p10}, 5);
  65. // Define the 2 quadrangle surfaces for the big cylinder.
  66. shape q3("quadrangle", -1, {a5,l3,a6,l4});
  67. shape q4("quadrangle", -1, {a7,l4,a8,l3});
  68. ///// CONSTRUCTION OF THE SURFACE BETWEEN THE TWO CYLINDERS
  69. // Define the lines linking the 2 cylinders:
  70. shape l5("line", -1, {p4,p9}, 12);
  71. shape l6("line", -1, {p5,p10}, 12);
  72. // Define the surface between the cylinders:
  73. shape q5("quadrangle", -1, {a4,l6,a6,l5});
  74. ///// EXTRUDE THE TOP AND BOTTOM CYLINDERS AROUND THE CENTRAL PART OF THE SMALL CYLINDER:
  75. // Extrude arguments are the physical region of the extruded volume,
  76. // the extrusion height and the numbers of node layers in the extrusion.
  77. // The central part in the small cylinder is 10mm thick and the two above and below 5mm.
  78. double centralthickness = 0.01, thicknessaboveandbelow = 0.005;
  79. // Create the bottom volume part:
  80. shape v1 = q1.extrude(vol, -thicknessaboveandbelow, 3);
  81. shape v2 = q2.extrude(vol, -thicknessaboveandbelow, 3);
  82. // Create the central part:
  83. shape v3 = q1.extrude(vol, centralthickness, 6);
  84. shape v4 = q2.extrude(vol, centralthickness, 6);
  85. // Create the top volume part.
  86. // Extrude it from the top face of v3 and v4.
  87. shape v3topface = v3.getsons()[5];
  88. shape v4topface = v4.getsons()[5];
  89. shape v5 = v3topface.extrude(vol, thicknessaboveandbelow, 3);
  90. shape v6 = v4topface.extrude(vol, thicknessaboveandbelow, 3);
  91. ///// EXTRUDE THE BIG CYLINDER:
  92. shape v7 = q3.extrude(vol, centralthickness, 6);
  93. shape v8 = q4.extrude(vol, centralthickness, 6);
  94. ///// EXTRUDE THE SURFACE BETWEEN THE 2 CYLINDERS:
  95. shape v9 = q5.extrude(vol, centralthickness, 6);
  96. ///// DEFORM THE BIG CYLINDER ABOVE AND BELOW:
  97. v7.deform(0,0, 100*(bigouterradius-sqrt((x-0.1)*(x-0.1)+y*y))*(z-centralthickness/2));
  98. v8.deform(0,0, 100*(bigouterradius-sqrt((x-0.1)*(x-0.1)+y*y))*(z-centralthickness/2));
  99. ///// GET THE BOTTOM SURFACE OF THE SMALL CYLINDER AND ASSIGN PHYSICAL REGION NUMBER 2
  100. ///// GET THE SURFACE INSIDE THE BIG CYLINDER AND ASSIGN PHYSICAL REGION NUMBER 3
  101. // You can .write the mesh at any time during the geometry construction
  102. // phase (see below) to easily know which son you are looking for.
  103. shape clampface1 = v1.getsons()[5];
  104. shape clampface2 = v2.getsons()[5];
  105. clampface1.setphysicalregion(clamp);
  106. clampface2.setphysicalregion(clamp);
  107. shape faceincylinder1 = v7.getsons()[1];
  108. shape faceincylinder2 = v8.getsons()[1];
  109. faceincylinder1.setphysicalregion(faceincylinder);
  110. faceincylinder2.setphysicalregion(faceincylinder);
  111. ///// LOAD THE MESH
  112. // Add here all regions needed in the finite element simulation.
  113. mesh mymesh({v1,v2,v3,v4,v5,v6,v7,v8,v9, clampface1,clampface2, faceincylinder1,faceincylinder2});
  114. // You can write the mesh at any time during the geometry
  115. // construction to easily debug and validate every line of code.
  116. mymesh.write("mymesh.msh");
  117. ///// START THE MECHANICAL SIMULATION
  118. // Nodal shape functions 'h1' with 3 components.
  119. // Field u is the mechanical displacement.
  120. field u("h1xyz");
  121. // Use interpolation order 2 on 'vol', the whole domain:
  122. u.setorder(vol, 2);
  123. // Clamp on surface 'clamp' (i.e. 0 valued-Dirichlet conditions):
  124. u.setconstraint(clamp);
  125. // E is Young's modulus. nu is Poisson's ratio.
  126. double E = 200e9, nu = 0.3;
  127. formulation elasticity;
  128. // The linear elasticity formulation is classical and thus predefined:
  129. elasticity += integral(vol, predefinedelasticity(dof(u), tf(u), E, nu));
  130. // Add a surface force (to the inside of the big cylinder) to tilt the structure around the x axis:
  131. elasticity += integral(faceincylinder, array1x3(0,10*(z-centralthickness/2),0)*tf(u));
  132. elasticity.generate();
  133. vec solu = solve(elasticity.A(), elasticity.b());
  134. // Transfer the data from the solution vector to the u field:
  135. u.setdata(vol, solu);
  136. // Write the deflection with an order 2 interpolation. Exaggerate the deflection by a large factor.
  137. (0.3e10*u).write(vol, "u.pos", 2);
  138. // Code validation line. Can be removed.
  139. std::cout << (abs(compz(u)).max(vol, 2)[0] < 4.24272e-12 && abs(compz(u)).max(vol, 2)[0] > 4.2427e-12);
  140. }
  141. int main(void)
  142. {
  143. SlepcInitialize(0,{},0,0);
  144. sparselizard();
  145. SlepcFinalize();
  146. return 0;
  147. }