61static real_t epsilon_ = 1.0;
62static real_t sigma_ = 20.0;
63static real_t omega_ = 10.0;
76int main(
int argc,
char *argv[])
85 const char *mesh_file =
"../data/inline-quad.mesh";
86 int ser_ref_levels = 1;
87 int par_ref_levels = 1;
92 bool visualization = 1;
93 bool herm_conv =
true;
94 bool exact_sol =
true;
96 const char *device_config =
"cpu";
99 args.
AddOption(&mesh_file,
"-m",
"--mesh",
100 "Mesh file to use.");
101 args.
AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
102 "Number of times to refine the mesh uniformly in serial.");
103 args.
AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
104 "Number of times to refine the mesh uniformly in parallel.");
106 "Finite element order (polynomial degree).");
108 "Choose between 0: H_1, 1: H(Curl), or 2: H(Div) "
109 "damped harmonic oscillator.");
110 args.
AddOption(&a_coef,
"-a",
"--stiffness-coef",
111 "Stiffness coefficient (spring constant or 1/mu).");
112 args.
AddOption(&epsilon_,
"-b",
"--mass-coef",
113 "Mass coefficient (or epsilon).");
114 args.
AddOption(&sigma_,
"-c",
"--damping-coef",
115 "Damping coefficient (or sigma).");
116 args.
AddOption(&mu_,
"-mu",
"--permeability",
117 "Permeability of free space (or 1/(spring constant)).");
118 args.
AddOption(&epsilon_,
"-eps",
"--permittivity",
119 "Permittivity of free space (or mass constant).");
120 args.
AddOption(&sigma_,
"-sigma",
"--conductivity",
121 "Conductivity (or damping constant).");
123 "Frequency (in Hz).");
124 args.
AddOption(&herm_conv,
"-herm",
"--hermitian",
"-no-herm",
125 "--no-hermitian",
"Use convention for Hermitian operators.");
126 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
127 "--no-visualization",
128 "Enable or disable GLVis visualization.");
129 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
130 "--no-partial-assembly",
"Enable Partial Assembly.");
131 args.
AddOption(&device_config,
"-d",
"--device",
132 "Device configuration string, see Device::Configure().");
148 "Unrecognized problem type: " <<
prob);
156 omega_ = 2.0 * M_PI *
freq;
160 if (myid == 0 && exact_sol)
162 cout <<
"Identified a mesh with known exact solution" << endl;
170 Device device(device_config);
171 if (myid == 0) { device.
Print(); }
176 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
180 for (
int l = 0; l < ser_ref_levels; l++)
190 for (
int l = 0; l < par_ref_levels; l++)
202 cout <<
"Switching to problem type 0, H1 basis functions, "
203 <<
"for 1 dimensional mesh." << endl;
220 cout <<
"Number of finite element unknowns: " << size << endl;
267 u.ProjectBdrCoefficient(u0_r, u0_i, ess_bdr);
268 u_exact->ProjectCoefficient(u0_r, u0_i);
272 u.ProjectBdrCoefficient(oneCoef, zeroCoef, ess_bdr);
278 u.ProjectBdrCoefficientTangent(u1_r, u1_i, ess_bdr);
279 u_exact->ProjectCoefficient(u1_r, u1_i);
283 u.ProjectBdrCoefficientTangent(oneVecCoef, zeroVecCoef, ess_bdr);
289 u.ProjectBdrCoefficientNormal(u2_r, u2_i, ess_bdr);
290 u_exact->ProjectCoefficient(u2_r, u2_i);
294 u.ProjectBdrCoefficientNormal(oneVecCoef, zeroVecCoef, ess_bdr);
300 if (visualization && exact_sol)
305 sol_sock_r <<
"parallel " << num_procs <<
" " << myid <<
"\n";
306 sol_sock_r.precision(8);
307 sol_sock_r <<
"solution\n" << *pmesh <<
u_exact->real()
308 <<
"window_title 'Exact: Real Part'" << flush;
313 sol_sock_i <<
"parallel " << num_procs <<
" " << myid <<
"\n";
314 sol_sock_i.precision(8);
315 sol_sock_i <<
"solution\n" << *pmesh <<
u_exact->imag()
316 <<
"window_title 'Exact: Imaginary Part'" << flush;
341 if (pa) {
a->SetAssemblyLevel(AssemblyLevel::PARTIAL); }
413 cout <<
"Size of linear system: "
423 blockTrueOffsets[0] = 0;
424 blockTrueOffsets[1] = A->
Height() / 2;
425 blockTrueOffsets[2] = A->
Height() / 2;
480 a->RecoverFEMSolution(U,
b,
u);
490 err_r =
u.real().ComputeL2Error(u0_r);
491 err_i =
u.imag().ComputeL2Error(u0_i);
494 err_r =
u.real().ComputeL2Error(u1_r);
495 err_i =
u.imag().ComputeL2Error(u1_i);
498 err_r =
u.real().ComputeL2Error(u2_r);
499 err_i =
u.imag().ComputeL2Error(u2_i);
507 cout <<
"|| Re (u_h - u) ||_{L^2} = " << err_r << endl;
508 cout <<
"|| Im (u_h - u) ||_{L^2} = " << err_i << endl;
516 ostringstream mesh_name, sol_r_name, sol_i_name, sol_z_name;
517 mesh_name <<
"mesh." << setfill(
'0') << setw(6) << myid;
518 sol_r_name <<
"sol_r." << setfill(
'0') << setw(6) << myid;
519 sol_i_name <<
"sol_i." << setfill(
'0') << setw(6) << myid;
520 sol_z_name <<
"sol_z." << setfill(
'0') << setw(6) << myid;
522 ofstream mesh_ofs(mesh_name.str().c_str());
523 mesh_ofs.precision(8);
524 pmesh->
Print(mesh_ofs);
526 ofstream sol_r_ofs(sol_r_name.str().c_str());
527 ofstream sol_i_ofs(sol_i_name.str().c_str());
528 ofstream sol_z_ofs(sol_z_name.str().c_str());
529 sol_r_ofs.precision(8);
530 sol_i_ofs.precision(8);
531 sol_z_ofs.precision(8);
532 u.real().Save(sol_r_ofs);
533 u.imag().Save(sol_i_ofs);
543 sol_sock_r <<
"parallel " << num_procs <<
" " << myid <<
"\n";
544 sol_sock_r.precision(8);
545 sol_sock_r <<
"solution\n" << *pmesh <<
u.real()
546 <<
"window_title 'Solution: Real Part'" << flush;
551 sol_sock_i <<
"parallel " << num_procs <<
" " << myid <<
"\n";
552 sol_sock_i.precision(8);
553 sol_sock_i <<
"solution\n" << *pmesh <<
u.imag()
554 <<
"window_title 'Solution: Imaginary Part'" << flush;
559 if (visualization && exact_sol)
566 sol_sock_r <<
"parallel " << num_procs <<
" " << myid <<
"\n";
567 sol_sock_r.precision(8);
568 sol_sock_r <<
"solution\n" << *pmesh <<
u_exact->real()
569 <<
"window_title 'Error: Real Part'" << flush;
574 sol_sock_i <<
"parallel " << num_procs <<
" " << myid <<
"\n";
575 sol_sock_i.precision(8);
576 sol_sock_i <<
"solution\n" << *pmesh <<
u_exact->imag()
577 <<
"window_title 'Error: Imaginary Part'" << flush;
589 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
590 sol_sock.precision(8);
591 sol_sock <<
"solution\n" << *pmesh << u_t
592 <<
"window_title 'Harmonic Solution (t = 0.0 T)'"
593 <<
"pause\n" << flush;
595 cout <<
"GLVis visualization paused."
596 <<
" Press space (in the GLVis window) to resume it.\n";
603 oss <<
"Harmonic Solution (t = " << t <<
" T)";
605 add(cos( 2.0 * M_PI * t),
u.real(),
606 sin(-2.0 * M_PI * t),
u.imag(), u_t);
607 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
608 sol_sock <<
"solution\n" << *pmesh << u_t
609 <<
"window_title '" << oss.str() <<
"'" << flush;
627 string file(mesh_file);
628 size_t p0 = file.find_last_of(
"/");
629 string s0 = file.substr((p0==string::npos)?0:(p0+1),7);
630 return s0 ==
"inline-";
636 complex<real_t> i(0.0, 1.0);
637 complex<real_t>
alpha = (epsilon_ * omega_ - i * sigma_);
638 complex<real_t>
kappa = std::sqrt(mu_ * omega_*
alpha);
639 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.
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
void Print(std::ostream &os=mfem::out)
Print the configuration of the MFEM virtual device object.
for Raviart-Thomas elements
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the FGMRES method.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
A general function coefficient.
Arbitrary order H1-conforming (continuous) finite elements.
The Auxiliary-space Divergence Solver in hypre.
The Auxiliary-space Maxwell Solver in hypre.
The BoomerAMG solver in hypre.
Wrapper for hypre's ParCSR matrix class.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
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.
int Dimension() const
Dimension of the reference space used within the elements.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
static int WorldRank()
Return the MPI rank in MPI_COMM_WORLD.
static int WorldSize()
Return the size of MPI_COMM_WORLD.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
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().
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.
Abstract parallel finite element space.
void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const override
HYPRE_BigInt GlobalTrueVSize() const
Class for parallel grid function.
Class for parallel meshes.
void Print(std::ostream &out=mfem::out, const std::string &comments="") const override
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.
const int * ess_tdof_list
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)