41 int main(
int argc,
char *argv[])
49 const char *mesh_file =
"../data/inline-quad.mesh";
50 int ser_ref_levels = 2;
51 int par_ref_levels = 1;
54 bool visualization = 1;
57 args.
AddOption(&mesh_file,
"-m",
"--mesh",
59 args.
AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
60 "Number of times to refine the mesh uniformly in serial.");
61 args.
AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
62 "Number of times to refine the mesh uniformly in parallel.");
64 "Finite element order (polynomial degree) or -1 for"
65 " isoparametric space.");
67 "Number of desired eigenmodes.");
68 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
70 "Enable or disable GLVis visualization.");
76 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
86 for (
int lev = 0; lev < ser_ref_levels; lev++)
95 ParMesh pmesh(MPI_COMM_WORLD, *mesh);
97 for (
int lev = 0; lev < par_ref_levels; lev++)
127 cout <<
"Number of H(Curl) unknowns: " << size_nd << endl;
128 cout <<
"Number of H(Div) unknowns: " << size_rt << endl;
145 epsilonMat(0,0) = 2.0; epsilonMat(1,1) = 2.0; epsilonMat(2,2) = 2.0;
146 epsilonMat(0,2) = 0.0; epsilonMat(2,0) = 0.0;
147 epsilonMat(0,1) = M_SQRT1_2; epsilonMat(1,0) = M_SQRT1_2;
148 epsilonMat(1,2) = M_SQRT1_2; epsilonMat(2,1) = M_SQRT1_2;
169 cout <<
"Computing eigenvalues shifted by " << shift << endl;
220 ostringstream mesh_name, mode_name, mode_deriv_name;
221 mesh_name <<
"mesh." << setfill(
'0') << setw(6) << myid;
223 ofstream mesh_ofs(mesh_name.str().c_str());
224 mesh_ofs.precision(8);
225 pmesh.
Print(mesh_ofs);
227 for (
int i=0; i<nev; i++)
233 mode_name <<
"mode_" << setfill(
'0') << setw(2) << i <<
"."
234 << setfill(
'0') << setw(6) << myid;
235 mode_deriv_name <<
"mode_deriv_" << setfill(
'0') << setw(2) << i <<
"."
236 << setfill(
'0') << setw(6) << myid;
238 ofstream mode_ofs(mode_name.str().c_str());
239 mode_ofs.precision(8);
243 ofstream mode_deriv_ofs(mode_deriv_name.str().c_str());
244 mode_deriv_ofs.precision(8);
245 dx.
Save(mode_deriv_ofs);
246 mode_deriv_name.str(
"");
262 mode_x_sock.precision(8);
263 mode_y_sock.precision(8);
264 mode_z_sock.precision(8);
265 mode_dy_sock.precision(8);
266 mode_dz_sock.precision(8);
268 Vector xVec(3); xVec = 0.0; xVec(0) = 1;
269 Vector yVec(3); yVec = 0.0; yVec(1) = 1;
270 Vector zVec(3); zVec = 0.0; zVec(2) = 1;
288 for (
int i=0; i<nev; i++)
292 cout <<
"Eigenmode " << i+1 <<
'/' << nev
293 <<
", Lambda = " << eigenvalues[i] - shift << endl;
313 double max_r = std::max(max_x, std::max(max_y, max_z));
316 x_cmd <<
" window_title 'Eigenmode " << i+1 <<
'/' << nev
317 <<
" X, Lambda = " << eigenvalues[i] - shift <<
"'"
318 <<
" valuerange -"<< max_r <<
' ' << max_r;
322 <<
" window_geometry 0 0 400 350";
325 mode_x_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
326 <<
"solution\n" << pmesh << xComp << flush
327 << x_cmd.str() << endl << flush;
329 MPI_Barrier(MPI_COMM_WORLD);
332 y_cmd <<
" window_title 'Eigenmode " << i+1 <<
'/' << nev
333 <<
" Y, Lambda = " << eigenvalues[i] - shift <<
"'"
334 <<
" valuerange -"<< max_r <<
' ' << max_r;
338 <<
" window_geometry 403 0 400 350";
341 mode_y_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
342 <<
"solution\n" << pmesh << yComp << flush
343 << y_cmd.str() << endl << flush;
345 MPI_Barrier(MPI_COMM_WORLD);
348 z_cmd <<
" window_title 'Eigenmode " << i+1 <<
'/' << nev
349 <<
" Z, Lambda = " << eigenvalues[i] - shift <<
"'"
350 <<
" valuerange -"<< max_r <<
' ' << max_r;
354 <<
" window_geometry 806 0 400 350";
357 mode_z_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
358 <<
"solution\n" << pmesh << zComp << flush
359 << z_cmd.str() << endl << flush;
361 MPI_Barrier(MPI_COMM_WORLD);
370 double min_d = max_r / (bbMax[0] - bbMin[0]);
374 max_r = std::max(std::max(max_y, max_z), min_d);
376 ostringstream dy_cmd;
377 dy_cmd <<
" window_title 'Curl Eigenmode "
379 <<
" Y, Lambda = " << eigenvalues[i] - shift <<
"'"
380 <<
"valuerange -"<< max_r <<
' ' << max_r;
384 <<
" window_geometry 403 375 400 350";
387 mode_dy_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
388 <<
"solution\n" << pmesh << dyComp << flush
389 << dy_cmd.str() << endl << flush;
391 MPI_Barrier(MPI_COMM_WORLD);
393 ostringstream dz_cmd;
394 dz_cmd <<
" window_title 'Curl Eigenmode "
396 <<
" Z, Lambda = " << eigenvalues[i] - shift <<
"'"
397 <<
"valuerange -"<< max_r <<
' ' << max_r;
401 <<
" window_geometry 806 375 400 350";
404 mode_dz_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
405 <<
"solution\n" << pmesh << dzComp << flush
406 << dz_cmd.str() << endl << flush;
408 MPI_Barrier(MPI_COMM_WORLD);
413 cout <<
"press (q)uit or (c)ontinue --> " << flush;
416 MPI_Bcast(&c, 1, MPI_CHAR, 0, MPI_COMM_WORLD);
426 mode_dy_sock.
close();
427 mode_dz_sock.
close();
435 mode_xy_sock.precision(8);
436 mode_z_sock.precision(8);
437 mode_dxy_sock.precision(8);
438 mode_dz_sock.precision(8);
441 xyMat(0,0) = 1.0; xyMat(1,1) = 1.0;
443 Vector zVec(3); zVec = 0.0; zVec(2) = 1;
462 for (
int i=0; i<nev; i++)
466 cout <<
"Eigenmode " << i+1 <<
'/' << nev
467 <<
", Lambda = " << eigenvalues[i] - shift << endl;
484 double max_r = std::max(max_v, max_s);
486 ostringstream xy_cmd;
487 xy_cmd <<
" window_title 'Eigenmode " << i+1 <<
'/' << nev
488 <<
" XY, Lambda = " << eigenvalues[i] - shift <<
"'"
489 <<
" valuerange 0.0 " << max_r;
492 xy_cmd <<
" keys aavvv"
493 <<
" window_geometry 0 0 400 350";
496 mode_xy_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
497 <<
"solution\n" << pmesh << xyComp << flush
498 << xy_cmd.str() << endl << flush;
500 MPI_Barrier(MPI_COMM_WORLD);
503 z_cmd <<
" window_title 'Eigenmode " << i+1 <<
'/' << nev
504 <<
" Z, Lambda = " << eigenvalues[i] - shift <<
"'"
505 <<
" valuerange -"<< max_r <<
' ' << max_r;
509 <<
" window_geometry 403 0 400 350";
512 mode_z_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
513 <<
"solution\n" << pmesh << zComp << flush
514 << z_cmd.str() << endl << flush;
516 MPI_Barrier(MPI_COMM_WORLD);
525 double min_d = max_r / std::min(bbMax[0] - bbMin[0],
526 bbMax[1] - bbMin[1]);
530 max_r = std::max(std::max(max_v, max_s), min_d);
532 ostringstream dxy_cmd;
533 dxy_cmd <<
" window_title 'Curl Eigenmode "
535 <<
" XY, Lambda = " << eigenvalues[i] - shift <<
"'"
536 <<
" valuerange 0.0 " << max_r <<
'\n';
539 dxy_cmd <<
" keys aavvv "
540 <<
" window_geometry 0 375 400 350";
544 mode_dxy_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
545 <<
"solution\n" << pmesh << dxyComp << flush
546 << dxy_cmd.str() << endl << flush;
548 MPI_Barrier(MPI_COMM_WORLD);
550 ostringstream dz_cmd;
551 dz_cmd <<
" window_title 'Curl Eigenmode "
553 <<
" Z, Lambda = " << eigenvalues[i] - shift <<
"'"
554 <<
" valuerange -" << max_r <<
' ' << max_r;
558 <<
" window_geometry 403 375 400 350";
561 mode_dz_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
562 <<
"solution\n" << pmesh << dzComp << flush
563 << dz_cmd.str() << endl << flush;
565 MPI_Barrier(MPI_COMM_WORLD);
570 cout <<
"press (q)uit or (c)ontinue --> " << flush;
573 MPI_Bcast(&c, 1, MPI_CHAR, 0, MPI_COMM_WORLD);
580 mode_xy_sock.
close();
582 mode_dxy_sock.
close();
583 mode_dz_sock.
close();
589 mode_sock.precision(8);
590 mode_deriv_sock.precision(8);
592 for (
int i=0; i<nev; i++)
596 cout <<
"Eigenmode " << i+1 <<
'/' << nev
597 <<
", Lambda = " << eigenvalues[i] - shift << endl;
604 mode_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
605 <<
"solution\n" << pmesh << x << flush
606 <<
"window_title 'Eigenmode " << i+1 <<
'/' << nev
607 <<
", Lambda = " << eigenvalues[i] - shift
610 MPI_Barrier(MPI_COMM_WORLD);
612 mode_deriv_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n"
613 <<
"solution\n" << pmesh << dx << flush
614 <<
"window_geometry 0 375 400 350 "
615 <<
"window_title 'Curl Eigenmode "
617 <<
", Lambda = " << eigenvalues[i] - shift
620 MPI_Barrier(MPI_COMM_WORLD);
625 cout <<
"press (q)uit or (c)ontinue --> " << flush;
628 MPI_Bcast(&c, 1, MPI_CHAR, 0, MPI_COMM_WORLD);
653 Vector zeroVec(vdim); zeroVec = 0.0;
int WorldSize() const
Return MPI_COMM_WORLD's size.
A matrix coefficient that is constant in space and time.
int Size() const
Return the logical size of the array.
The Auxiliary-space Maxwell Solver in hypre.
A coefficient that is constant across space and time.
void SetMassMatrix(const HypreParMatrix &M)
Scalar coefficient defined as the inner product of two vector coefficients.
Arbitrary order 3D H(curl)-conforming Nedelec finite elements in 1D.
Integrator for (curl u, curl v) for Nedelec elements.
double GetVectorMax(int vdim, const ParGridFunction &x)
Vector coefficient that is constant in space and time.
void GetBoundingBox(Vector &min, Vector &max, int ref=2)
Returns the minimum and maximum corners of the mesh bounding box.
HYPRE_BigInt GlobalTrueVSize() const
void SetPreconditioner(HypreSolver &precond)
Data type dense matrix using column-major storage.
Arbitrary order 3D H(curl)-conforming Nedelec finite elements in 2D.
virtual void Save(std::ostream &out) const
Abstract parallel finite element space.
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
void AddDomainInterpolator(DiscreteInterpolator *di)
Adds a domain interpolator. Assumes ownership of di.
int close()
Close the socketstream.
A simple convenience class based on the Mpi singleton class above. Preserved for backward compatibili...
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
bool Root() const
Return true if WorldRank() == 0.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
int WorldRank() const
Return MPI_COMM_WORLD's rank.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
void SetPrintLevel(int print_lvl)
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 Solve()
Solve the eigenproblem.
virtual double ComputeMaxError(Coefficient *exsol[], const IntegrationRule *irs[]=NULL) const
void SetNumModes(int num_eigs)
const HypreParVector & GetEigenvector(unsigned int i) const
Extract a single eigenvector.
Vector coefficient defined as a product of a matrix coefficient and a vector coefficient.
void SetMaxIter(int max_iter)
void GetEigenvalues(Array< double > &eigenvalues) const
Collect the converged eigenvalues.
void SetPrintLevel(int logging)
Arbitrary order H(curl)-conforming Nedelec finite elements.
Vector coefficient defined by a vector GridFunction.
void SetOperator(const HypreParMatrix &A)
Arbitrary order 3D H(div)-conforming Raviart-Thomas finite elements in 2D.
Arbitrary order H1-conforming (continuous) finite elements.
void Print(std::ostream &out=mfem::out) const override
Class for parallel grid function.
Wrapper for hypre's ParCSR matrix class.
virtual void Assemble(int skip_zeros=1)
Construct the internal matrix representation of the discrete linear operator.
Class for parallel meshes.
void SetSingularProblem()
Set this option when solving a curl-curl problem with zero mass term.
Arbitrary order 3D H(div)-conforming Raviart-Thomas finite elements in 1D.
void ParseCheck(std::ostream &out=mfem::out)
double GetScalarMax(const ParGridFunction &x)
Arbitrary order "L2-conforming" discontinuous finite elements.