main.cpp 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // This code simulates the magnetic field created by an imposed current density
  2. // in an aluminium wire when a magnetic shield (a steel cylinder) is placed nearby.
  3. //
  4. // This example illustrates the resolution of a general magnetostatic problem with
  5. // current density sources on a 3D geometry. It uses the magnetic vector potential
  6. // based on edge shape functions 'hcurl' and combined with a gauge. The gauge is
  7. // needed because the algebraic system to solve is singular. The effect of the gauge
  8. // is to remove all degrees of freedom associated to higher order gradient type shape
  9. // functions from the algebraic system. Additionally all degrees of freedom associated
  10. // to lowest order (order 0) edge shape functions are removed for all edges in a
  11. // spanning tree. After having removed these two types of degrees of freedom the
  12. // matrix becomes non-singular and can be solved with a usual direct solver.
  13. //
  14. // It is worth noting that the spanning tree growth HAS TO START on the regions
  15. // where the magnetic vector potential field 'a' is constrained. This is to avoid
  16. // issues of forcing the value of the magnetic flux through faces where we do not
  17. // want it to be constrained.
  18. #include "sparselizardbase.h"
  19. using namespace mathop;
  20. void sparselizard(void)
  21. {
  22. // Give names to the region numbers defined in the mesh file:
  23. int conductor = 1, shield = 2, air = 3, contour = 4;
  24. // Load the mesh:
  25. mesh mymesh("magmesh.msh");
  26. // Define the whole volume region for convenience:
  27. int wholedomain = regionunion({conductor,shield,air});
  28. // Define the magnetic permeability mu [H/m] in the air, conductor (aluminium) and magnetic shield (steel):
  29. double mu0 = 4*getpi()*1e-7;
  30. parameter mu;
  31. mu|air = mu0;
  32. mu|conductor = mu0;
  33. mu|shield = 1000*mu0;
  34. // Define a spanning tree to gauge the magnetic vector potential (otherwise the matrix is singular).
  35. // Start growing the tree from the regions with constrained potential vector (here the contour):
  36. spanningtree spantree({contour});
  37. // Write it for illustration:
  38. spantree.write("spantree.pos");
  39. // Define the magnetic vector potential 'a' and provide the tree. Use edge shape functions 'hcurl'.
  40. field a("hcurl", spantree);
  41. // Gauge the vector potential field on the whole volume:
  42. a.setgauge(wholedomain);
  43. // Use higher interpolation orders where needed. Use order 1 (default) everywhere else:
  44. a.setorder(shield, 2);
  45. // Put a magnetic wall (i.e. set field 'a' to 0) all around the domain (no magnetic flux can cross it):
  46. a.setconstraint(contour);
  47. // Define the magnetostatic formulation:
  48. formulation magnetostatics;
  49. // The strong form of the magnetostatic formulation is curl( 1/mu * curl(a) ) = j, with b = curl(a):
  50. magnetostatics += integral(wholedomain, 1/mu* curl(dof(a)) * curl(tf(a)) );
  51. // A current density of 1A/m^2 flows in the z direction in the conductor region:
  52. magnetostatics += integral(conductor, -array3x1(0,0,1)*tf(a));
  53. // Generate the algebraic matrices A and vector b of the Ax = b problem:
  54. magnetostatics.generate();
  55. // Get the x solution vector:
  56. vec sol = solve(magnetostatics.A(), magnetostatics.b());
  57. // Update field 'a' with the solution that has just been computed:
  58. a.setdata(wholedomain, sol);
  59. // Write the magnetic induction field b = curl(a) [T]:
  60. curl(a).write(wholedomain, "b.pos");
  61. // Code validation line. Can be removed:
  62. std::cout << (norm(a).max(wholedomain,4)[0] < 1.96437e-08 && norm(a).max(wholedomain,4)[0] > 1.96435e-08);
  63. }
  64. int main(void)
  65. {
  66. SlepcInitialize(0,{},0,0);
  67. sparselizard();
  68. SlepcFinalize();
  69. return 0;
  70. }