61static real_t epsilon_ = 1.0;
62static real_t sigma_ = 20.0;
63static real_t omega_ = 10.0;
76int main(
int argc,
char *argv[])
79 const char *mesh_file =
"../data/inline-quad.mesh";
85 bool visualization = 1;
86 bool herm_conv =
true;
87 bool exact_sol =
true;
89 const char *device_config =
"cpu";
92 args.
AddOption(&mesh_file,
"-m",
"--mesh",
94 args.
AddOption(&ref_levels,
"-r",
"--refine",
95 "Number of times to refine the mesh uniformly.");
97 "Finite element order (polynomial degree).");
99 "Choose between 0: H_1, 1: H(Curl), or 2: H(Div) "
100 "damped harmonic oscillator.");
101 args.
AddOption(&a_coef,
"-a",
"--stiffness-coef",
102 "Stiffness coefficient (spring constant or 1/mu).");
103 args.
AddOption(&epsilon_,
"-b",
"--mass-coef",
104 "Mass coefficient (or epsilon).");
105 args.
AddOption(&sigma_,
"-c",
"--damping-coef",
106 "Damping coefficient (or sigma).");
107 args.
AddOption(&mu_,
"-mu",
"--permeability",
108 "Permeability of free space (or 1/(spring constant)).");
109 args.
AddOption(&epsilon_,
"-eps",
"--permittivity",
110 "Permittivity of free space (or mass constant).");
111 args.
AddOption(&sigma_,
"-sigma",
"--conductivity",
112 "Conductivity (or damping constant).");
114 "Frequency (in Hz).");
115 args.
AddOption(&herm_conv,
"-herm",
"--hermitian",
"-no-herm",
116 "--no-hermitian",
"Use convention for Hermitian operators.");
117 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
118 "--no-visualization",
119 "Enable or disable GLVis visualization.");
120 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
121 "--no-partial-assembly",
"Enable Partial Assembly.");
122 args.
AddOption(&device_config,
"-d",
"--device",
123 "Device configuration string, see Device::Configure().");
133 "Unrecognized problem type: " <<
prob);
141 omega_ = 2.0 * M_PI *
freq;
147 cout <<
"Identified a mesh with known exact solution" << endl;
155 Device device(device_config);
161 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
167 for (
int l = 0; l < ref_levels; l++)
177 cout <<
"Switching to problem type 0, H1 basis functions, "
178 <<
"for 1 dimensional mesh." << endl;
191 cout <<
"Number of finite element unknowns: " << fespace->
GetTrueVSize()
209 b.Vector::operator=(0.0);
238 u.ProjectBdrCoefficient(u0_r, u0_i, ess_bdr);
239 u_exact->ProjectCoefficient(u0_r, u0_i);
243 u.ProjectBdrCoefficient(oneCoef, zeroCoef, ess_bdr);
249 u.ProjectBdrCoefficientTangent(u1_r, u1_i, ess_bdr);
250 u_exact->ProjectCoefficient(u1_r, u1_i);
254 u.ProjectBdrCoefficientTangent(oneVecCoef, zeroVecCoef, ess_bdr);
260 u.ProjectBdrCoefficientNormal(u2_r, u2_i, ess_bdr);
261 u_exact->ProjectCoefficient(u2_r, u2_i);
265 u.ProjectBdrCoefficientNormal(oneVecCoef, zeroVecCoef, ess_bdr);
271 if (visualization && exact_sol)
277 sol_sock_r.precision(8);
278 sol_sock_i.precision(8);
279 sol_sock_r <<
"solution\n" << *mesh <<
u_exact->real()
280 <<
"window_title 'Exact: Real Part'" << flush;
281 sol_sock_i <<
"solution\n" << *mesh <<
u_exact->imag()
282 <<
"window_title 'Exact: Imaginary Part'" << flush;
304 if (pa) {
a->SetAssemblyLevel(AssemblyLevel::PARTIAL); }
372 a->FormLinearSystem(ess_tdof_list,
u,
b, A, U, B);
374 cout <<
"Size of linear system: " << A->
Width() << endl << endl;
382 blockOffsets[1] = A->
Height() / 2;
383 blockOffsets[2] = A->
Height() / 2;
435 a->RecoverFEMSolution(U,
b,
u);
445 err_r =
u.real().ComputeL2Error(u0_r);
446 err_i =
u.imag().ComputeL2Error(u0_i);
449 err_r =
u.real().ComputeL2Error(u1_r);
450 err_i =
u.imag().ComputeL2Error(u1_i);
453 err_r =
u.real().ComputeL2Error(u2_r);
454 err_i =
u.imag().ComputeL2Error(u2_i);
460 cout <<
"|| Re (u_h - u) ||_{L^2} = " << err_r << endl;
461 cout <<
"|| Im (u_h - u) ||_{L^2} = " << err_i << endl;
468 ofstream mesh_ofs(
"refined.mesh");
469 mesh_ofs.precision(8);
470 mesh->
Print(mesh_ofs);
472 ofstream sol_r_ofs(
"sol_r.gf");
473 ofstream sol_i_ofs(
"sol_i.gf");
474 sol_r_ofs.precision(8);
475 sol_i_ofs.precision(8);
476 u.real().Save(sol_r_ofs);
477 u.imag().Save(sol_i_ofs);
487 sol_sock_r.precision(8);
488 sol_sock_i.precision(8);
489 sol_sock_r <<
"solution\n" << *mesh <<
u.real()
490 <<
"window_title 'Solution: Real Part'" << flush;
491 sol_sock_i <<
"solution\n" << *mesh <<
u.imag()
492 <<
"window_title 'Solution: Imaginary Part'" << flush;
494 if (visualization && exact_sol)
502 sol_sock_r.precision(8);
503 sol_sock_i.precision(8);
504 sol_sock_r <<
"solution\n" << *mesh <<
u_exact->real()
505 <<
"window_title 'Error: Real Part'" << flush;
506 sol_sock_i <<
"solution\n" << *mesh <<
u_exact->imag()
507 <<
"window_title 'Error: Imaginary Part'" << flush;
516 sol_sock.precision(8);
517 sol_sock <<
"solution\n" << *mesh << u_t
518 <<
"window_title 'Harmonic Solution (t = 0.0 T)'"
519 <<
"pause\n" << flush;
521 cout <<
"GLVis visualization paused."
522 <<
" Press space (in the GLVis window) to resume it.\n";
529 oss <<
"Harmonic Solution (t = " <<
t <<
" T)";
531 add(cos( 2.0 * M_PI *
t),
u.real(),
532 sin(-2.0 * M_PI *
t),
u.imag(), u_t);
533 sol_sock <<
"solution\n" << *mesh << u_t
534 <<
"window_title '" << oss.str() <<
"'" << flush;
552 string file(mesh_file);
553 size_t p0 = file.find_last_of(
"/");
554 string s0 = file.substr((p0==string::npos)?0:(p0+1),7);
555 return s0 ==
"inline-";
561 complex<real_t> i(0.0, 1.0);
562 complex<real_t>
alpha = (epsilon_ * omega_ - i * sigma_);
563 complex<real_t>
kappa = std::sqrt(mu_ * omega_*
alpha);
564 return std::exp(-i *
kappa * x[
dim - 1]);
void u_exact(const Vector &x, Vector &u)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
A class to handle Block diagonal preconditioners in a matrix-free implementation.
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).
@ HERMITIAN
Native convention for Hermitian operators.
@ BLOCK_SYMMETRIC
Alternate convention for damping operators.
A coefficient that is constant across space and time.
Integrator for for Nedelec elements.
Data type for scaled Jacobi-type smoother of sparse matrix.
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
void Print(std::ostream &out=mfem::out)
Print the configuration of the MFEM virtual device object.
for Raviart-Thomas elements
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const
Get a list of essential true dofs, ess_tdof_list, corresponding to the boundary attributes marked in ...
A general function coefficient.
virtual void Mult(const Vector &b, Vector &x) const
Iterative solution of the linear system using the GMRES method.
Data type for Gauss-Seidel smoother of sparse matrix.
Class for grid function - Vector with associated FE space.
Arbitrary order H1-conforming (continuous) finite elements.
virtual void SetOperator(const Operator &op) override
Also calls SetOperator for the preconditioner if there is one.
void SetRelTol(real_t rtol)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void SetMaxIter(int max_it)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
int Dimension() const
Dimension of the reference space used within the elements.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Arbitrary order H(curl)-conforming Nedelec finite elements.
Pointer to an Operator of a specified type.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
Operator * Ptr() const
Access the underlying Operator pointer.
Jacobi smoothing for a given bilinear form (no matrix necessary).
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
@ DIAG_ONE
Set the diagonal value to one.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
bool Good() const
Return true if the command line options were parsed successfully.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Scaled Operator B: x -> a A(x).
Vector coefficient that is constant in space and time.
A general vector function coefficient.
int Size() const
Returns the size of the vector.
void SetSize(int s)
Resize the vector to size s.
void u2_real_exact(const Vector &, Vector &)
bool check_for_inline_mesh(const char *mesh_file)
void u1_imag_exact(const Vector &, Vector &)
real_t u0_real_exact(const Vector &)
void u1_real_exact(const Vector &, Vector &)
real_t u0_imag_exact(const Vector &)
void u2_imag_exact(const Vector &, Vector &)
complex< real_t > u0_exact(const Vector &x)
real_t u(const Vector &xvec)
void add(const Vector &v1, const Vector &v2, Vector &v)