60 static double mu_ = 1.0;
61 static double epsilon_ = 1.0;
62 static double sigma_ = 20.0;
63 static double omega_ = 10.0;
76 int 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;
151 herm_conv ? ComplexOperator::HERMITIAN : ComplexOperator::BLOCK_SYMMETRIC;
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;
415 double s = (
prob != 1) ? 1.0 : -1.0;
417 (conv == ComplexOperator::HERMITIAN) ?
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";
527 double t = (double)(i % num_frames) / num_frames;
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<double> i(0.0, 1.0);
562 complex<double>
alpha = (epsilon_ * omega_ - i * sigma_);
563 complex<double>
kappa = std::sqrt(mu_ * omega_*
alpha);
564 return std::exp(-i *
kappa * x[
dim - 1]);
Class for grid function - Vector with associated FE space.
Data type for scaled Jacobi-type smoother of sparse matrix.
A coefficient that is constant across space and time.
void PrintOptions(std::ostream &out) const
Print the options.
int Dimension() const
Dimension of the reference space used within the elements.
void u2_imag_exact(const Vector &, Vector &)
void SetSize(int s)
Resize the vector to size s.
void PrintUsage(std::ostream &out) const
Print the usage message.
Integrator for (curl u, curl v) for Nedelec elements.
Vector coefficient that is constant in space and time.
Pointer to an Operator of a specified type.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
int Size() const
Returns the size of the vector.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
Get a list of essential true dofs, ess_tdof_list, corresponding to the boundary attributes marked in ...
void Print(std::ostream &out=mfem::out)
Print the configuration of the MFEM virtual device object.
bool Good() const
Return true if the command line options were parsed successfully.
complex< double > u0_exact(const Vector &x)
(Q div u, div v) for RT elements
void u1_imag_exact(const Vector &, Vector &)
void add(const Vector &v1, const Vector &v2, Vector &v)
Data type for Gauss-Seidel smoother of sparse matrix.
virtual void SetOperator(const Operator &op) override
Also calls SetOperator for the preconditioner if there is one.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
A class to handle Block diagonal preconditioners in a matrix-free implementation. ...
int main(int argc, char *argv[])
Jacobi smoothing for a given bilinear form (no matrix necessary).
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
double u0_imag_exact(const Vector &)
void SetMaxIter(int max_it)
Set the diagonal value to one.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
A general vector function coefficient.
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void u_exact(const Vector &x, Vector &u)
void SetRelTol(double rtol)
Scaled Operator B: x -> a A(x).
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
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...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
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.
int Size() const
Return the logical size of the array.
A general function coefficient.
Arbitrary order H(curl)-conforming Nedelec finite elements.
virtual void Print(std::ostream &os=mfem::out) const
void u1_real_exact(const Vector &, Vector &)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Arbitrary order H1-conforming (continuous) finite elements.
double u(const Vector &xvec)
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
bool check_for_inline_mesh(const char *mesh_file)
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).
void u2_real_exact(const Vector &, Vector &)
double u0_real_exact(const Vector &)