main.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // This is a sandbox example to get a feeling with the stabilization methods
  2. // proposed in sparselizard for advection-dominated advection-diffusion problems.
  3. //
  4. // The geometry is a square of side 'a' with 'n' mesh points in the x and y direction.
  5. #include "sparselizardbase.h"
  6. using namespace mathop;
  7. mesh createmesh(double a, int n);
  8. void sparselizard()
  9. {
  10. // Square surface and its four sides:
  11. int sur = 1, left = 2, right = 3, up = 4, down = 5;
  12. mesh mymesh = createmesh(1.0, 101);
  13. // Field c can be a chemical concentration:
  14. field c("h1"), x("x"), y("y");
  15. // Use interpolation order 2:
  16. c.setorder(sur, 2);
  17. // Steady supply of chemical concentration from the left side:
  18. c.setconstraint(left, 1);
  19. // A 0.1 m/s fluid flow in the x direction is considered:
  20. expression v = array2x1(0.1,0);
  21. // Initial all zero concentration except in the square
  22. // delimited by [0,0.25] for x and [0.4,0.6] for y:
  23. expression cinit = ifpositive(x-0.25, 0.0, ifpositive(abs(y-0.5)-0.1, 0.0, 1.0) );
  24. c.setvalue(sur, cinit);
  25. c.write(sur, "cinit.vtu", 2);
  26. // Tuning factor for the stabilization:
  27. double delta = 0.1;
  28. // Timestep and end time for the simulation:
  29. double ts = 0.1, tend = 5.0;
  30. // This will hold the solution vectors for every timestep:
  31. std::vector<vec> sol;
  32. std::cout << std::endl << "No stabilization:" << std::endl;
  33. formulation adnostab;
  34. adnostab += integral(sur, predefinedadvectiondiffusion(dof(c), tf(c), v, 1e-6, 1.0, 1.0, true));
  35. c.setvalue(sur, cinit);
  36. vec init(adnostab);
  37. init.setdata(sur, c);
  38. genalpha genanostab(adnostab, init, vec(adnostab), vec(adnostab), {true,true,true,true});
  39. genanostab.setparameter(0.75);
  40. sol = genanostab.runlinear(0, ts, tend, 2)[0];
  41. c.setdata(sur, sol[sol.size()-1]);
  42. c.write(sur, "cnostab.vtu", 2);
  43. std::cout << std::endl << "Isotropic:" << std::endl;
  44. formulation adiso;
  45. adiso += integral(sur, predefinedadvectiondiffusion(dof(c), tf(c), v, 1e-6, 1.0, 1.0, true));
  46. adiso += integral(sur, predefinedstabilization("iso", delta, c, v, 0.0, 0.0));
  47. c.setvalue(sur, cinit);
  48. vec initiso(adiso);
  49. initiso.setdata(sur, c);
  50. genalpha genaiso(adiso, initiso, vec(adiso), vec(adiso), {true,true,true,true});
  51. genaiso.setparameter(0.75);
  52. sol = genaiso.runlinear(0, ts, tend, 2)[0];
  53. c.setdata(sur, sol[sol.size()-1]);
  54. c.write(sur, "ciso.vtu", 2);
  55. std::cout << std::endl << "Streamline anisotropic:" << std::endl;
  56. formulation adaniso;
  57. adaniso += integral(sur, predefinedadvectiondiffusion(dof(c), tf(c), v, 1e-6, 1.0, 1.0, true));
  58. adaniso += integral(sur, predefinedstabilization("aniso", delta, c, v, 0.0, 0.0));
  59. c.setvalue(sur, cinit);
  60. vec initaniso(adaniso);
  61. initaniso.setdata(sur, c);
  62. genalpha genaaniso(adaniso, initaniso, vec(adaniso), vec(adaniso), {true,true,true,true});
  63. genaaniso.setparameter(0.75);
  64. sol = genaaniso.runlinear(0, ts, tend, 2)[0];
  65. c.setdata(sur, sol[sol.size()-1]);
  66. c.write(sur, "caniso.vtu", 2);
  67. // Define the strong form residual to be used by the stabilization methods below:
  68. expression dofres = v*grad(dof(c));
  69. expression res = v*grad(c);
  70. // Tuning parameter for streamline and for crosswind:
  71. double deltas = 0.1, deltac = 0.001;
  72. std::cout << std::endl << "Streamline and crosswind combined:" << std::endl;
  73. formulation adcomb;
  74. adcomb += integral(sur, predefinedadvectiondiffusion(dof(c), tf(c), v, 1e-6, 1.0, 1.0, true));
  75. adcomb += integral(sur, predefinedstabilization("supg", deltas, c, v, 1e-6, dofres));
  76. adcomb += integral(sur, predefinedstabilization("cws", deltac, c, v, 1e-6, res));
  77. c.setvalue(sur, cinit);
  78. vec initcomb(adcomb);
  79. initcomb.setdata(sur, c);
  80. genalpha genacomb(adcomb, initcomb, vec(adcomb), vec(adcomb), {true,true,true,true});
  81. genacomb.setparameter(0.75);
  82. sol = genacomb.runlinear(0, ts, tend, 2)[0];
  83. c.setdata(sur, sol[sol.size()-1]);
  84. c.write(sur, "ccombined.vtu", 2);
  85. // Code validation line. Can be removed.
  86. double cinterpolated = c.interpolate(sur, {0.76,0.399,0.0})[0];
  87. std::cout << (cinterpolated < 0.128046 && cinterpolated > 0.128043);
  88. }
  89. mesh createmesh(double a, int n)
  90. {
  91. // Give names to the physical region numbers:
  92. int sur = 1, left = 2, right = 3, up = 4, down = 5;
  93. shape square("quadrangle", sur , {0,0,0, a,0,0, a,a,0, 0,a,0}, {n,n,n,n});
  94. shape line1 = square.getsons()[0];
  95. line1.setphysicalregion(down);
  96. shape line2 = square.getsons()[1];
  97. line2.setphysicalregion(right);
  98. shape line3 = square.getsons()[2];
  99. line3.setphysicalregion(up);
  100. shape line4 = square.getsons()[3];
  101. line4.setphysicalregion(left);
  102. // Provide to the mesh all shapes of interest:
  103. mesh mymesh({square,line1,line2,line3,line4});
  104. return mymesh;
  105. }
  106. int main(void)
  107. {
  108. SlepcInitialize(0,{},0,0);
  109. sparselizard();
  110. SlepcFinalize();
  111. return 0;
  112. }