35 #define jn(n, x) _jn(n, x)
36 #define yn(n, x) _yn(n, x)
77 Array<int> * GetMarkedPMLElements() {
return &elems;}
80 void SetAttributes(
Mesh *mesh_);
83 void StretchFunction(
const Vector &x, vector<complex<double>> &dxs);
90 CartesianPML * pml =
nullptr;
91 void (*Function)(
const Vector &, CartesianPML * ,
Vector &);
93 PMLDiagMatrixCoefficient(
int dim,
void(*F)(
const Vector &, CartesianPML *,
99 using VectorCoefficient::Eval;
108 (*Function)(transip, pml, K);
151 int main(
int argc,
char *argv[])
154 const char *mesh_file =
nullptr;
159 bool herm_conv =
true;
160 bool visualization = 1;
163 args.
AddOption(&mesh_file,
"-m",
"--mesh",
164 "Mesh file to use.");
166 "Finite element order (polynomial degree).");
167 args.
AddOption(&iprob,
"-prob",
"--problem",
"Problem case"
168 " 0: beam, 1: disc, 2: lshape, 3: fichera, 4: General");
169 args.
AddOption(&ref_levels,
"-ref",
"--refinements",
170 "Number of refinements");
172 "Permeability of free space (or 1/(spring constant)).");
174 "Permittivity of free space (or mass constant).");
175 args.
AddOption(&freq,
"-f",
"--frequency",
176 "Frequency (in Hz).");
177 args.
AddOption(&herm_conv,
"-herm",
"--hermitian",
"-no-herm",
178 "--no-hermitian",
"Use convention for Hermitian operators.");
179 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
180 "--no-visualization",
181 "Enable or disable GLVis visualization.");
184 if (iprob > 4) { iprob = 4; }
194 mesh_file =
"../data/beam-hex.mesh";
197 mesh_file =
"../data/square-disc.mesh";
200 mesh_file =
"../data/l-shape.mesh";
203 mesh_file =
"../data/fichera.mesh";
207 mesh_file =
"../data/inline-quad.mesh";
219 Mesh * mesh =
new Mesh(mesh_file, 1, 1);
250 CartesianPML * pml =
new CartesianPML(mesh,length);
255 for (
int l = 0; l < ref_levels; l++)
264 pml->SetAttributes(mesh);
272 cout <<
"Number of finite element unknowns: " << size << endl;
286 for (
int j = 0; j < mesh->
GetNBE(); j++)
296 if (center[0] == 1.0 || center[0] == 0.5 || center[1] == 0.5)
302 if (center[0] == -1.0 || center[0] == 0.0 ||
303 center[1] == 0.0 || center[2] == 0.0)
318 herm_conv ? ComplexOperator::HERMITIAN : ComplexOperator::BLOCK_SYMMETRIC;
328 b.Vector::operator=(0.0);
354 attr = 0; attr[0] = 1;
372 int cdim = (dim == 2) ? 1 : dim;
404 #ifdef MFEM_USE_SUITESPARSE
407 csolver.
Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
454 (conv == ComplexOperator::HERMITIAN) ? -1.0 : 1.0);
479 int order_quad = max(2, 2 * order + 1);
481 for (
int i = 0; i < Geometry::NumGeom; ++i)
487 pml->GetMarkedPMLElements());
489 pml->GetMarkedPMLElements());
493 double norm_E_Re, norm_E_Im;
495 pml->GetMarkedPMLElements());
497 pml->GetMarkedPMLElements());
499 cout <<
"\n Relative Error (Re part): || E_h - E || / ||E|| = "
500 << L2Error_Re / norm_E_Re
501 <<
"\n Relative Error (Im part): || E_h - E || / ||E|| = "
502 << L2Error_Im / norm_E_Im
503 <<
"\n Total Error: "
504 << sqrt(L2Error_Re*L2Error_Re + L2Error_Im*L2Error_Im) <<
"\n\n";
510 ofstream mesh_ofs(
"ex25.mesh");
511 mesh_ofs.precision(8);
512 mesh->
Print(mesh_ofs);
514 ofstream sol_r_ofs(
"ex25-sol_r.gf");
515 ofstream sol_i_ofs(
"ex25-sol_i.gf");
516 sol_r_ofs.precision(8);
517 sol_i_ofs.precision(8);
527 keys = (dim == 3) ?
"keys macF\n" : keys =
"keys amrRljcUUuu\n";
528 if (
prob ==
beam && dim == 3) {keys =
"keys macFFiYYYYYYYYYYYYYYYYYY\n";}
529 if (
prob ==
beam && dim == 2) {keys =
"keys amrRljcUUuuu\n"; }
535 sol_sock_re.precision(8);
536 sol_sock_re <<
"solution\n"
537 << *mesh << x.
real() << keys
538 <<
"window_title 'Solution real part'" << flush;
541 sol_sock_im.precision(8);
542 sol_sock_im <<
"solution\n"
543 << *mesh << x.
imag() << keys
544 <<
"window_title 'Solution imag part'" << flush;
549 sol_sock.precision(8);
550 sol_sock <<
"solution\n"
551 << *mesh << x_t << keys <<
"autoscale off\n"
552 <<
"window_title 'Harmonic Solution (t = 0.0 T)'"
553 <<
"pause\n" << flush;
554 cout <<
"GLVis visualization paused."
555 <<
" Press space (in the GLVis window) to resume it.\n";
560 double t = (double)(i % num_frames) / num_frames;
562 oss <<
"Harmonic Solution (t = " << t <<
" T)";
564 add(cos(2.0 * M_PI * t), x.
real(),
565 sin(2.0 * M_PI * t), x.
imag(), x_t);
566 sol_sock <<
"solution\n"
568 <<
"window_title '" << oss.str() <<
"'" << flush;
585 for (
int i = 0; i <
dim; ++i)
588 r += pow(x[i] - center[i], 2.);
591 double coeff = pow(n, 2) / M_PI;
592 double alpha = -pow(n, 2) * r;
594 f[0] = coeff * exp(alpha);
600 for (
int i = 0; i <
dim; ++i)
605 complex<double> zi = complex<double>(0., 1.);
621 double x0 = x(0) + shift(0);
622 double x1 = x(1) + shift(1);
623 double r = sqrt(x0 * x0 + x1 * x1);
627 complex<double> Ho, Ho_r, Ho_rr;
628 Ho = jn(0, beta) + zi * yn(0, beta);
629 Ho_r = -k * (jn(1, beta) + zi * yn(1, beta));
630 Ho_rr = -k * k * (1.0 / beta *
631 (jn(1, beta) + zi * yn(1, beta)) -
632 (jn(2, beta) + zi * yn(2, beta)));
637 double r_xy = -(r_x / r) * r_y;
638 double r_xx = (1.0 / r) * (1.0 - r_x * r_x);
640 complex<double> val, val_xx, val_xy;
641 val = 0.25 * zi * Ho;
642 val_xx = 0.25 * zi * (r_xx * Ho_r + r_x * r_x * Ho_rr);
643 val_xy = 0.25 * zi * (r_xy * Ho_r + r_x * r_y * Ho_rr);
644 E[0] = zi / k * (k * k * val + val_xx);
645 E[1] = zi / k * val_xy;
649 double x0 = x(0) + shift(0);
650 double x1 = x(1) + shift(1);
651 double x2 = x(2) + shift(2);
652 double r = sqrt(x0 * x0 + x1 * x1 + x2 * x2);
657 double r_xx = (1.0 / r) * (1.0 - r_x * r_x);
658 double r_yx = -(r_y / r) * r_x;
659 double r_zx = -(r_z / r) * r_x;
661 complex<double> val, val_r, val_rr;
662 val = exp(zi * k * r) / r;
663 val_r = val / r * (zi * k * r - 1.0);
664 val_rr = val / (r * r) * (-k * k * r * r
665 - 2.0 * zi * k * r + 2.0);
667 complex<double> val_xx, val_yx, val_zx;
668 val_xx = val_rr * r_x * r_x + val_r * r_xx;
669 val_yx = val_rr * r_x * r_y + val_r * r_yx;
670 val_zx = val_rr * r_x * r_z + val_r * r_zx;
672 complex<double>
alpha = zi * k / 4.0 / M_PI / k / k;
673 E[0] = alpha * (k * k * val + val_xx);
674 E[1] = alpha * val_yx;
675 E[2] = alpha * val_zx;
684 double k10 = sqrt(k * k - M_PI * M_PI);
685 E[1] = -zi * k / M_PI * sin(M_PI*x(2))*exp(zi * k10 * x(0));
689 E[1] = -zi * k / M_PI * exp(zi * k * x(0));
700 vector<complex<double>> Eval(E.
Size());
702 for (
int i = 0; i <
dim; ++i)
704 E[i] = Eval[i].real();
710 vector<complex<double>> Eval(E.
Size());
712 for (
int i = 0; i <
dim; ++i)
714 E[i] = Eval[i].imag();
723 for (
int i = 0; i <
dim; ++i)
735 vector<complex<double>> Eval(E.
Size());
737 for (
int i = 0; i <
dim; ++i)
739 E[i] = Eval[i].real();
750 for (
int i = 0; i <
dim; ++i)
762 vector<complex<double>> Eval(E.
Size());
764 for (
int i = 0; i <
dim; ++i)
766 E[i] = Eval[i].imag();
773 vector<complex<double>> dxs(dim);
774 complex<double> det(1.0, 0.0);
775 pml->StretchFunction(x, dxs);
777 for (
int i = 0; i <
dim; ++i)
782 for (
int i = 0; i <
dim; ++i)
784 D(i) = (det / pow(dxs[i], 2)).real();
790 vector<complex<double>> dxs(dim);
791 complex<double> det = 1.0;
792 pml->StretchFunction(x, dxs);
794 for (
int i = 0; i <
dim; ++i)
799 for (
int i = 0; i <
dim; ++i)
801 D(i) = (det / pow(dxs[i], 2)).imag();
807 vector<complex<double>> dxs(dim);
808 complex<double> det = 1.0;
809 pml->StretchFunction(x, dxs);
811 for (
int i = 0; i <
dim; ++i)
816 for (
int i = 0; i <
dim; ++i)
818 D(i) = abs(det / pow(dxs[i], 2));
824 vector<complex<double>> dxs(dim);
825 complex<double> det(1.0, 0.0);
826 pml->StretchFunction(x, dxs);
828 for (
int i = 0; i <
dim; ++i)
836 D = (1.0 / det).real();
840 for (
int i = 0; i <
dim; ++i)
842 D(i) = (pow(dxs[i], 2) / det).real();
849 vector<complex<double>> dxs(dim);
850 complex<double> det = 1.0;
851 pml->StretchFunction(x, dxs);
853 for (
int i = 0; i <
dim; ++i)
860 D = (1.0 / det).imag();
864 for (
int i = 0; i <
dim; ++i)
866 D(i) = (pow(dxs[i], 2) / det).imag();
873 vector<complex<double>> dxs(dim);
874 complex<double> det = 1.0;
875 pml->StretchFunction(x, dxs);
877 for (
int i = 0; i <
dim; ++i)
888 for (
int i = 0; i <
dim; ++i)
890 D(i) = abs(pow(dxs[i], 2) / det);
896 : mesh(mesh_), length(length_)
898 dim = mesh->Dimension();
902 void CartesianPML::SetBoundaries()
904 comp_dom_bdr.SetSize(dim, 2);
905 dom_bdr.SetSize(dim, 2);
907 mesh->GetBoundingBox(pmin, pmax);
908 for (
int i = 0; i <
dim; i++)
910 dom_bdr(i, 0) = pmin(i);
911 dom_bdr(i, 1) = pmax(i);
912 comp_dom_bdr(i, 0) = dom_bdr(i, 0) + length(i, 0);
913 comp_dom_bdr(i, 1) = dom_bdr(i, 1) - length(i, 1);
917 void CartesianPML::SetAttributes(
Mesh *mesh_)
919 int nrelem = mesh_->
GetNE();
920 elems.SetSize(nrelem);
923 for (
int i = 0; i < nrelem; ++i)
933 int nrvert = vertices.
Size();
936 for (
int iv = 0; iv < nrvert; ++iv)
938 int vert_idx = vertices[iv];
939 double *coords = mesh_->
GetVertex(vert_idx);
940 for (
int comp = 0; comp <
dim; ++comp)
942 if (coords[comp] > comp_dom_bdr(comp, 1) ||
943 coords[comp] < comp_dom_bdr(comp, 0))
959 void CartesianPML::StretchFunction(
const Vector &x,
960 vector<complex<double>> &dxs)
962 complex<double> zi = complex<double>(0., 1.);
970 for (
int i = 0; i <
dim; ++i)
975 coeff = n * c / k / pow(length(i, 1), n);
976 dxs[i] = 1.0 + zi * coeff *
981 coeff = n * c / k / pow(length(i, 0), n);
982 dxs[i] = 1.0 + zi * coeff *
double Control[UMFPACK_CONTROL]
int Size() const
Return the logical size of the array.
virtual void Print(std::ostream &out=mfem::out) const
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
virtual void ProjectBdrCoefficientTangent(VectorCoefficient &real_coeff, VectorCoefficient &imag_coeff, Array< int > &attr)
Class for an integration rule - an Array of IntegrationPoint.
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
const double * GetVertex(int i) const
Return pointer to vertex i's coordinates.
Class for grid function - Vector with associated FE space.
void SetPrintLevel(int print_lvl)
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Base class for vector Coefficients that optionally depend on time and space.
A coefficient that is constant across space and time.
virtual double ComputeL2Error(Coefficient &exsol, const IntegrationRule *irs[]=NULL) const
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
Interface with UMFPack solver specialized for ComplexSparseMatrix This approach avoids forming a mono...
void E_exact_Re(const Vector &x, Vector &E)
void SetSize(int s)
Resize the vector to size s.
int GetNBE() const
Returns number of boundary elements.
Integrator for (curl u, curl v) for Nedelec elements.
Pointer to an Operator of a specified type.
int Size() const
Returns the size of the vector.
void maxwell_solution(const Vector &x, vector< complex< double >> &Eval)
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 ...
int GetNE() const
Returns number of elements.
void detJ_JT_J_inv_abs(const Vector &x, CartesianPML *pml, Vector &D)
void detJ_inv_JT_J_abs(const Vector &x, CartesianPML *pml, Vector &D)
void E_bdr_data_Re(const Vector &x, Vector &E)
const IntegrationPoint & GetCenter(int GeomType)
Return the center of the given Geometry::Type, GeomType.
int main(int argc, char *argv[])
void add(const Vector &v1, const Vector &v2, Vector &v)
Data type for Gauss-Seidel smoother of sparse matrix.
ElementTransformation * GetBdrElementTransformation(int i)
Returns the transformation defining the i-th boundary element.
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Derived vector coefficient that has the value of the parent vector where it is active and is zero oth...
void source(const Vector &x, Vector &f)
void E_exact_Im(const Vector &x, Vector &E)
void SetPrintLevel(int print_lvl)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
Array2D< double > domain_bdr
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. ...
virtual void SetAttributes()
Derived coefficient that takes the value of the parent coefficient for the active attributes and is z...
void E_bdr_data_Im(const Vector &x, Vector &E)
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
void detJ_inv_JT_J_Im(const Vector &x, CartesianPML *pml, Vector &D)
void SetMaxIter(int max_it)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void SetKDim(int dim)
Set the number of iteration to perform between restarts, default is 50.
const Element * GetElement(int i) const
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
virtual void ReorientTetMesh()
void PrintUsage(std::ostream &out) const
Print the usage message.
A general vector function coefficient.
void SetAbsTol(double atol)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Array2D< double > comp_domain_bdr
void SetRelTol(double rtol)
Scaled Operator B: x -> a A(x).
Specialization of the ComplexOperator built from a pair of Sparse Matrices.
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...
Vector coefficient defined as a product of scalar and vector coefficients.
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.
void detJ_JT_J_inv_Re(const Vector &x, CartesianPML *pml, Vector &D)
Class for integration point with weight.
virtual void Mult(const Vector &b, Vector &x) const
This is solving the system A x = b.
void detJ_JT_J_inv_Im(const Vector &x, CartesianPML *pml, Vector &D)
void PrintOptions(std::ostream &out) const
Print the options.
void SetAttribute(const int attr)
Set element's attribute.
Geometry::Type GetBdrElementBaseGeometry(int i) const
for VectorFiniteElements (Nedelec, Raviart-Thomas)
Arbitrary order H(curl)-conforming Nedelec finite elements.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
void detJ_inv_JT_J_Re(const Vector &x, CartesianPML *pml, Vector &D)
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Abstract data type element.
Array< int > attributes
A list of all unique element attributes used by the Mesh.
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).
double f(const Vector &p)
bool Good() const
Return true if the command line options were parsed successfully.