This example code solves a simple electromagnetic diffusion problem corresponding to the second order definite Maxwell equation

\nabla \times \nabla \times E +E=f

with boundary condition

E \times \textit{\textbf{n}} = \text{given tangential field}

Here, we use a given exact solution $E$ and compute the corresponding r.h.s. f.

We discretize with Nedelec finite elements in 2D or 3D.

The example demonstrates the use of $H$(curl) finite element spaces with the curl-curl and the (vector finite element) mass bilinear form, as well as the computation of discretization error when the exact solution is known. Static condensation is also illustrated.

Pre-defined functions

void E_exact(const Vector &, Vector &);
void f_exact(const Vector &, Vector &);

The lines of code you provided are from the ex3 example of the MFEM library. These lines define two functions, “E_exact” and “f_exact”, that are used to compute the exact solution, E, and the right-hand side of the equation, f, respectively. These functions are used to check the accuracy of the numerical solution obtained using MFEM.

“E_exact” function takes in a Vector of coordinates and returns the exact solution at that point in a Vector. “f_exact” function also takes in a Vector of coordinates and returns the value of the right-hand side of the equation at that point in a Vector.

The implementation of these functions is not shown in the code snippet you provided, but in the ex3 example, the specific form of E and f for the problem being solved is defined in these functions.

The user can then compare the numerical solution obtained using MFEM to the exact solution to check for accuracy.

void E_exact(const Vector &x, Vector &E)
{
   if (dim == 3)
   {
      E(0) = sin(kappa * x(1));
      E(1) = sin(kappa * x(2));
      E(2) = sin(kappa * x(0));
   }
   else
   {
      E(0) = sin(kappa * x(1));
      E(1) = sin(kappa * x(0));
      if (x.Size() == 3) { E(2) = 0.0; }
   }
}

That is the implementation of the function “E_exact” as it appears in the ex3 example of the MFEM library. It takes two arguments as input: “x”, a Vector of coordinates and “E” a Vector to store the exact solution. The function checks the dimension of the problem (2D or 3D) by checking the value of the global variable “dim”. Depending on the dimension, the function computes the exact solution “E” at the given point “x” using the formula sin(kappa * x(i)),

E_i=sin(\kappa x_i) 

where “$\kappa$” is a global variable and “i” is the ith coordinate.

For 2D,

E_x=sin(\kappa y)),  \ \ E_y = sin(\kappa  x) 

For 3D,

E_x=\sin(\kappa x), \ \ E_y = \sin(\kappa x_y),  \ \ E_z=\sin(\kappa z) 

It also checks if $x=\textbf{x}(0), y=\textbf{x}(1)$ in the case of 2D, if so it sets $E_z = 0.0$.

This function computes the exact solution of the differential equation at a given point $\textbf{x}$, it helps the user to check the accuracy of the numerical solution obtained using MFEM.

void f_exact(const Vector &x, Vector &f)
{
   if (dim == 3)
   {
      f(0) = (1. + kappa * kappa) * sin(kappa * x(1));
      f(1) = (1. + kappa * kappa) * sin(kappa * x(2));
      f(2) = (1. + kappa * kappa) * sin(kappa * x(0));
   }
   else
   {
      f(0) = (1. + kappa * kappa) * sin(kappa * x(1));
      f(1) = (1. + kappa * kappa) * sin(kappa * x(0));
      if (x.Size() == 3) { f(2) = 0.0; }
   }
}

That is the implementation of the function “f_exact” as it appears in the ex3 example of the MFEM library. It takes two arguments as input: “x”, a Vector of coordinates and “f” a Vector to store the value of the right-hand side of the equation. The function checks the dimension of the problem (2D or 3D) by checking the value of the global variable “dim”. Depending on the dimension, the function computes the right-hand side of the equation “$f$” at the given point “$x$” using the formula

f_i = (1+\kappa ^2) sin(\kappa x_i)

where “$\kappa$” is a global variable and “$i$” is the ith coordinate.

For 2D,

f_x = (1+\kappa^2) sin (\kappa y)  , \ \ f_y = (1+\kappa^2) sin (\kappa x)

For 3D, f(0) = (1. + kappa * kappa) * sin(kappa * x(1)), f(1) = (1. + kappa * kappa) * sin(kappa * x(2)), f(2) = (1. + kappa * kappa) * sin(kappa * x(0))

It also checks if x has 3 components in the case of 2D, if so it sets f(2) = 0.0.

This function computes the value of the right-hand side of the equation at a given point x, it’s used to define the problem and it’s an important part of the solution process.

Parse command-line options

   const char *mesh_file = "../data/beam-tet.mesh";
   int order = 1;
   bool static_cond = false;
   bool visualization = 1;

   OptionsParser args(argc, argv);
   args.AddOption(&mesh_file, "-m", "--mesh",
                  "Mesh file to use.");
   args.AddOption(&order, "-o", "--order",
                  "Finite element order (polynomial degree).");
   args.AddOption(&freq, "-f", "--frequency", "Set the frequency for the exact"
                  " solution.");
   args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
                  "--no-static-condensation", "Enable static condensation.");
   args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
                  "--no-visualization",
                  "Enable or disable GLVis visualization.");

That is the code from the example of the MFEM library that parses command-line options.

This code first declares and initializes several variables, such as mesh_file, order, static_cond, and visualization, with default values.

It then creates an OptionsParser object “args” by passing it the command-line arguments “argc” and “argv”.

It then adds options for the mesh_file, order, frequency, static_condensation, and visualization using the AddOption method on the OptionsParser object. These options allow the user to specify values for these variables when running the program from the command line.

It then calls the Parse method on the OptionsParser object to parse the command-line options, and check if all options are good.

If the options are not good, it calls the PrintUsage method on the OptionsParser object to print the usage message and then return 1.

It then calls the PrintOptions method on the OptionsParser object to print the options that have been set and finally it calculates kappa by multiplying frequency with pi.

This code allows the user to pass command-line options to the program, it uses the OptionsParser class to parse the options and it allows the user to set various parameters such as the mesh file, order, frequency, static_condensation, and visualization.


Posted

in

, , ,

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *