58 static double mu_ = 1.0;
59 static double epsilon_ = 1.0;
60 static double sigma_ = 20.0;
61 static double omega_ = 10.0;
74 int main(
int argc,
char *argv[])
78 MPI_Init(&argc, &argv);
79 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
80 MPI_Comm_rank(MPI_COMM_WORLD, &myid);
83 const char *mesh_file =
"../data/inline-quad.mesh";
84 int ser_ref_levels = 1;
85 int par_ref_levels = 1;
90 bool visualization = 1;
91 bool herm_conv =
true;
92 bool exact_sol =
true;
94 const char *device_config =
"cpu";
97 args.
AddOption(&mesh_file,
"-m",
"--mesh",
99 args.
AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
100 "Number of times to refine the mesh uniformly in serial.");
101 args.
AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
102 "Number of times to refine the mesh uniformly in parallel.");
104 "Finite element order (polynomial degree).");
105 args.
AddOption(&prob,
"-p",
"--problem-type",
106 "Choose between 0: H_1, 1: H(Curl), or 2: H(Div) "
107 "damped harmonic oscillator.");
108 args.
AddOption(&a_coef,
"-a",
"--stiffness-coef",
109 "Stiffness coefficient (spring constant or 1/mu).");
110 args.
AddOption(&epsilon_,
"-b",
"--mass-coef",
111 "Mass coefficient (or epsilon).");
112 args.
AddOption(&sigma_,
"-c",
"--damping-coef",
113 "Damping coefficient (or sigma).");
114 args.
AddOption(&mu_,
"-mu",
"--permeability",
115 "Permeability of free space (or 1/(spring constant)).");
116 args.
AddOption(&epsilon_,
"-eps",
"--permittivity",
117 "Permittivity of free space (or mass constant).");
118 args.
AddOption(&sigma_,
"-sigma",
"--conductivity",
119 "Conductivity (or damping constant).");
120 args.
AddOption(&freq,
"-f",
"--frequency",
121 "Frequency (in Hz).");
122 args.
AddOption(&herm_conv,
"-herm",
"--hermitian",
"-no-herm",
123 "--no-hermitian",
"Use convention for Hermitian operators.");
124 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
125 "--no-visualization",
126 "Enable or disable GLVis visualization.");
127 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
128 "--no-partial-assembly",
"Enable Partial Assembly.");
129 args.
AddOption(&device_config,
"-d",
"--device",
130 "Device configuration string, see Device::Configure().");
146 MFEM_VERIFY(prob >= 0 && prob <=2,
147 "Unrecognized problem type: " << prob);
155 omega_ = 2.0 * M_PI *
freq;
159 if (myid == 0 && exact_sol)
161 cout <<
"Identified a mesh with known exact solution" << endl;
165 herm_conv ? ComplexOperator::HERMITIAN : ComplexOperator::BLOCK_SYMMETRIC;
169 Device device(device_config);
170 if (myid == 0) { device.
Print(); }
175 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
179 for (
int l = 0; l < ser_ref_levels; l++)
189 for (
int l = 0; l < par_ref_levels; l++)
197 if (dim == 1 && prob != 0 )
201 cout <<
"Switching to problem type 0, H1 basis functions, "
202 <<
"for 1 dimensional mesh." << endl;
219 cout <<
"Number of finite element unknowns: " << size << endl;
237 b.Vector::operator=(0.0);
256 Vector zeroVec(dim); zeroVec = 0.0;
257 Vector oneVec(dim); oneVec = 0.0; oneVec[(prob==2)?(dim-1):0] = 1.0;
299 if (visualization && exact_sol)
305 sol_sock_r <<
"parallel " << num_procs <<
" " << myid <<
"\n";
306 sol_sock_i <<
"parallel " << num_procs <<
" " << myid <<
"\n";
307 sol_sock_r.precision(8);
308 sol_sock_i.precision(8);
309 sol_sock_r <<
"solution\n" << *pmesh << u_exact->
real()
310 <<
"window_title 'Exact: Real Part'" << flush;
311 sol_sock_i <<
"solution\n" << *pmesh << u_exact->
imag()
312 <<
"window_title 'Exact: Imaginary Part'" << flush;
406 cout <<
"Size of linear system: "
416 blockTrueOffsets[0] = 0;
417 blockTrueOffsets[1] = A->
Height() / 2;
418 blockTrueOffsets[2] = A->
Height() / 2;
456 (conv == ComplexOperator::HERMITIAN) ?
500 cout <<
"|| Re (u_h - u) ||_{L^2} = " << err_r << endl;
501 cout <<
"|| Im (u_h - u) ||_{L^2} = " << err_i << endl;
509 ostringstream mesh_name, sol_r_name, sol_i_name;
510 mesh_name <<
"mesh." << setfill(
'0') << setw(6) << myid;
511 sol_r_name <<
"sol_r." << setfill(
'0') << setw(6) << myid;
512 sol_i_name <<
"sol_i." << setfill(
'0') << setw(6) << myid;
514 ofstream mesh_ofs(mesh_name.str().c_str());
515 mesh_ofs.precision(8);
516 pmesh->
Print(mesh_ofs);
518 ofstream sol_r_ofs(sol_r_name.str().c_str());
519 ofstream sol_i_ofs(sol_i_name.str().c_str());
520 sol_r_ofs.precision(8);
521 sol_i_ofs.precision(8);
533 sol_sock_r <<
"parallel " << num_procs <<
" " << myid <<
"\n";
534 sol_sock_i <<
"parallel " << num_procs <<
" " << myid <<
"\n";
535 sol_sock_r.precision(8);
536 sol_sock_i.precision(8);
537 sol_sock_r <<
"solution\n" << *pmesh << u.
real()
538 <<
"window_title 'Solution: Real Part'" << flush;
539 sol_sock_i <<
"solution\n" << *pmesh << u.
imag()
540 <<
"window_title 'Solution: Imaginary Part'" << flush;
542 if (visualization && exact_sol)
550 sol_sock_r <<
"parallel " << num_procs <<
" " << myid <<
"\n";
551 sol_sock_i <<
"parallel " << num_procs <<
" " << myid <<
"\n";
552 sol_sock_r.precision(8);
553 sol_sock_i.precision(8);
554 sol_sock_r <<
"solution\n" << *pmesh << u_exact->
real()
555 <<
"window_title 'Error: Real Part'" << flush;
556 sol_sock_i <<
"solution\n" << *pmesh << u_exact->
imag()
557 <<
"window_title 'Error: Imaginary Part'" << flush;
566 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
567 sol_sock.precision(8);
568 sol_sock <<
"solution\n" << *pmesh << u_t
569 <<
"window_title 'Harmonic Solution (t = 0.0 T)'"
570 <<
"pause\n" << flush;
572 cout <<
"GLVis visualization paused."
573 <<
" Press space (in the GLVis window) to resume it.\n";
578 double t = (double)(i % num_frames) / num_frames;
580 oss <<
"Harmonic Solution (t = " << t <<
" T)";
582 add(cos( 2.0 * M_PI * t), u.
real(),
583 sin(-2.0 * M_PI * t), u.
imag(), u_t);
584 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
585 sol_sock <<
"solution\n" << *pmesh << u_t
586 <<
"window_title '" << oss.str() <<
"'" << flush;
606 string file(mesh_file);
607 size_t p0 = file.find_last_of(
"/");
608 string s0 = file.substr((p0==string::npos)?0:(p0+1),7);
609 return s0 ==
"inline-";
615 complex<double> i(0.0, 1.0);
616 complex<double>
alpha = (epsilon_ * omega_ - i * sigma_);
617 complex<double>
kappa = std::sqrt(mu_ * omega_* alpha);
618 return std::exp(-i * kappa * x[dim - 1]);
int Size() const
Return the logical size of the array.
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
The Auxiliary-space Maxwell Solver in hypre.
The Auxiliary-space Divergence Solver in hypre.
A coefficient that is constant across space and time.
virtual void ProjectBdrCoefficient(Coefficient &real_coeff, Coefficient &imag_coeff, Array< int > &attr)
void u2_imag_exact(const Vector &, Vector &)
void SetSize(int s)
Resize the vector to size s.
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.
HYPRE_BigInt GlobalTrueVSize() const
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
int Size() const
Returns the size of the vector.
virtual void Save(std::ostream &out) const
void Print(std::ostream &out=mfem::out)
Print the configuration of the MFEM virtual device object.
Abstract parallel finite element space.
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)
The BoomerAMG solver in hypre.
void SetPrintLevel(int print_lvl)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
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 Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
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)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
virtual void Print(std::ostream &out=mfem::out) const
void PrintUsage(std::ostream &out) const
Print the usage message.
Operator * Ptr() const
Access the underlying Operator pointer.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
A general vector function coefficient.
virtual void ProjectBdrCoefficientNormal(VectorCoefficient &real_coeff, VectorCoefficient &imag_coeff, Array< int > &attr)
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).
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.
virtual void ProjectBdrCoefficientTangent(VectorCoefficient &real_coeff, VectorCoefficient &imag_coeff, Array< int > &attr)
virtual double ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL) const
void PrintOptions(std::ostream &out) const
Print the options.
A general function coefficient.
Arbitrary order H(curl)-conforming Nedelec finite elements.
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)
Class for parallel grid function.
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)
Wrapper for hypre's ParCSR matrix class.
Class for parallel meshes.
virtual void ProjectCoefficient(Coefficient &real_coeff, Coefficient &imag_coeff)
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).
void u2_real_exact(const Vector &, Vector &)
bool Good() const
Return true if the command line options were parsed successfully.
double u0_real_exact(const Vector &)