main.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // This code projects an expression on a finite element basis, i.e. it computes
  2. // the best approximation of the expression for the requested interpolation order.
  3. // The relative L2 norm of the error is output so that one can investigate
  4. // the impact of the interpolation order and the mesh size on the error.
  5. //
  6. // The theory of finite elements states that for a fine enough mesh
  7. // (i.e. a large enough 'n' in the quad.geo file) the error should decrease
  8. // at a rate n^(p+1) where p is the interpolation order.
  9. // All standard shape functions in sparselizard follow this asymptotic decrease rate.
  10. #include "sparselizardbase.h"
  11. using namespace mathop;
  12. void sparselizard(void)
  13. {
  14. // CHANGE THE INTERPOLATION ORDER HERE TO SEE THE IMPACT ON THE ERROR
  15. // Recommended order range is 1 to 6 here. Note that when
  16. // you reach machine precision the error stops decreasing.
  17. int interpolationorder = 5;
  18. // The domain region as defined in 'quad.geo':
  19. int face = 1;
  20. mesh mymesh("quad.msh");
  21. // Nodal shape functions 'h1' for field v.
  22. // Fields x and y are the x and y coordinate fields:
  23. field v("h1"), x("x"), y("y");
  24. // Use the requested interpolation order on the whole domain:
  25. v.setorder(face, interpolationorder);
  26. // A finite element approximation of this expression is computed:
  27. expression toproject = sin(10*x)*sin(13*y);
  28. // This formulation computes integral( v*v' ) = integral( toproject*v' ) :
  29. formulation projection;
  30. // A last int argument is added. The 20 means the term below will be
  31. // assembled using an integration order +20 compared to the default
  32. // order (which is order of the dof + order of the tf + 2).
  33. projection += integral(face, dof(v)*tf(v) - toproject*tf(v), +20 );
  34. projection.generate();
  35. vec solv = solve(projection.A(), projection.b());
  36. // Transfer the data from the solution vector to the v field:
  37. v.setdata(face, solv);
  38. // Compute the relative L2 norm of the error, i.e. the square root of
  39. // the integral of the error squared divided by the expression squared.
  40. // The integration is exact for up to order 20 polynomials.
  41. double relativel2normoferror = sqrt( pow( v - toproject , 2).integrate(face, 20) / pow( toproject , 2).integrate(face, 20) );
  42. std::cout << std::endl << "Relative L2 norm of the error is " << relativel2normoferror << std::endl << std::endl;
  43. // Write with an order 4 interpolation:
  44. v.write(face, "v.pos", 4);
  45. // Code validation line. Can be removed.
  46. std::cout << (relativel2normoferror < 1e-5);
  47. }
  48. int main(void)
  49. {
  50. SlepcInitialize(0,{},0,0);
  51. sparselizard();
  52. SlepcFinalize();
  53. return 0;
  54. }