71 #include "../common/mfem-common.hpp" 111 int main(
int argc,
char *argv[])
113 const char *mesh_file =
"../../data/inline-quad.mesh";
116 bool visualization =
true;
119 bool static_cond =
false;
123 args.
AddOption(&mesh_file,
"-m",
"--mesh",
124 "Mesh file to use.");
126 "Finite element order (polynomial degree)");
127 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
128 "--no-visualization",
129 "Enable or disable GLVis visualization.");
130 args.
AddOption(&rnum,
"-rnum",
"--number_of_wavelengths",
131 "Number of wavelengths");
132 args.
AddOption(&iprob,
"-prob",
"--problem",
"Problem case" 133 " 0: plane wave, 1: Gaussian beam");
134 args.
AddOption(&delta_order,
"-do",
"--delta_order",
135 "Order enrichment for DPG test space.");
136 args.
AddOption(&ref,
"-ref",
"--refinements",
137 "Number of serial refinements.");
138 args.
AddOption(&static_cond,
"-sc",
"--static-condensation",
"-no-sc",
139 "--no-static-condensation",
"Enable static condensation.");
148 if (iprob > 1) { iprob = 0; }
151 omega = 2.*M_PI*rnum;
153 Mesh mesh(mesh_file, 1, 1);
155 MFEM_VERIFY(
dim > 1,
"Dimension = 1 is not supported in this example");
188 int test_order = order+delta_order;
207 trial_fes.
Append(hatp_fes);
208 trial_fes.
Append(hatu_fes);
217 TrialSpace::p_space,TestSpace::q_space);
220 nullptr,TrialSpace::u_space,TestSpace::q_space);
223 TrialSpace::p_space,TestSpace::v_space);
225 a->AddTrialIntegrator(
nullptr,
227 TrialSpace::u_space,TestSpace::v_space);
230 TrialSpace::hatp_space,TestSpace::v_space);
233 TrialSpace::hatu_space,TestSpace::q_space);
238 TestSpace::q_space, TestSpace::q_space);
241 TestSpace::q_space, TestSpace::q_space);
244 TestSpace::v_space, TestSpace::v_space);
247 TestSpace::v_space, TestSpace::v_space);
250 TestSpace::q_space, TestSpace::v_space);
253 TestSpace::v_space, TestSpace::q_space);
256 TestSpace::v_space, TestSpace::v_space);
259 TestSpace::v_space, TestSpace::q_space);
262 TestSpace::q_space, TestSpace::v_space);
265 TestSpace::q_space, TestSpace::q_space);
287 std::cout <<
"\n Ref |" 292 <<
" PCG it |" << endl;
293 std::cout << std::string(60,
'-')
296 for (
int it = 0; it<=ref; it++)
298 if (static_cond) {
a->EnableStaticCondensation(); }
311 for (
int j = 0; j < ess_tdof_list.
Size(); j++)
330 hatp_gf_i.ProjectBdrCoefficient(hatpex_i, ess_bdr);
334 a->FormLinearSystem(ess_tdof_list,x,Ah, X,B);
345 int k = (static_cond) ? 2 : 0;
346 for (
int i=0; i<num_blocks; i++)
348 tdof_offsets[i+1] = trial_fes[i+k]->GetTrueVSize();
349 tdof_offsets[num_blocks+i+1] = trial_fes[i+k]->GetTrueVSize();
354 for (
int i = 0; i<num_blocks; i++)
356 for (
int j = 0; j<num_blocks; j++)
358 A.
SetBlock(i,j,&A_r->GetBlock(i,j));
360 A.
SetBlock(i+num_blocks,j+num_blocks,&A_r->GetBlock(i,j));
367 for (
int i = 0; i<num_blocks; i++)
382 a->RecoverFEMSolution(X,x);
397 for (
int i = 0; i<trial_fes.
Size(); i++)
399 dofs += trial_fes[i]->GetTrueVSize();
403 double p_err_i = p_i.ComputeL2Error(p_ex_i);
404 double u_err_r = u_r.ComputeL2Error(u_ex_r);
405 double u_err_i = u_i.ComputeL2Error(u_ex_i);
407 double L2Error = sqrt(p_err_r*p_err_r + p_err_i*p_err_i
408 +u_err_r*u_err_r + u_err_i*u_err_i);
410 double rate_err = (it) ?
dim*log(err0/L2Error)/log((
double)dof0/dofs) : 0.0;
415 std::ios oldState(
nullptr);
416 oldState.copyfmt(std::cout);
417 std::cout << std::right << std::setw(5) << it <<
" | " 418 << std::setw(10) << dof0 <<
" | " 419 << std::setprecision(1) << std::fixed
420 << std::setw(4) << 2*rnum <<
" π | " 421 << std::setprecision(3)
422 << std::setw(10) << std::scientific << err0 <<
" | " 423 << std::setprecision(2)
424 << std::setw(6) << std::fixed << rate_err <<
" | " 427 std::cout.copyfmt(oldState);
431 const char * keys = (it == 0 &&
dim == 2) ?
"jRcml\n" :
nullptr;
435 "Numerical presure (real part)", 0, 0, 500, 500, keys);
437 "Numerical presure (imaginary part)", 501, 0, 500, 500, keys);
446 for (
int i =0; i<trial_fes.
Size(); i++)
448 trial_fes[i]->Update(
false);
491 vector<complex<double>> grad;
493 for (
unsigned i = 0; i < grad.size(); i++)
495 grad_r[i] = grad[i].real();
502 vector<complex<double>> grad;
504 for (
unsigned i = 0; i < grad.size(); i++)
506 grad_i[i] = grad[i].imag();
577 complex<double> zi = complex<double>(0., 1.);
591 double alpha = (180+degrees) * M_PI/180.;
592 double sina = sin(
alpha);
593 double cosa = cos(
alpha);
595 double xprim=X(0) + 0.1;
596 double yprim=X(1) + 0.1;
598 double x = xprim*sina - yprim*cosa;
599 double y = xprim*cosa + yprim*sina;
601 double rl = 2.*M_PI/rk;
605 double fact = rl/M_PI/(w0*w0);
606 double aux = 1. + (fact*y)*(fact*y);
607 double w = w0*sqrt(aux);
608 double phi0 = atan(fact*y);
609 double r = y + 1./y/(fact*fact);
612 complex<double> ze = - x*x/(w*w) - zi*rk*y - zi * M_PI * x * x/rl/r +
615 double pf = pow(2.0/M_PI/(w*w),0.25);
625 complex<double> zi = complex<double>(0., 1.);
632 complex<double>
p = exp(
alpha);
633 for (
int i = 0; i<X.
Size(); i++)
635 dp[i] = zi *
beta *
p;
643 double alpha = (180+degrees) * M_PI/180.;
644 double sina = sin(
alpha);
645 double cosa = cos(
alpha);
647 double xprim=X(0) + 0.1;
648 double yprim=X(1) + 0.1;
650 double x = xprim*sina - yprim*cosa;
651 double y = xprim*cosa + yprim*sina;
652 double dxdxprim = sina, dxdyprim = -cosa;
653 double dydxprim = cosa, dydyprim = sina;
655 double rl = 2.*M_PI/rk;
661 double fact = rl/M_PI/(w0*w0);
662 double aux = 1. + (fact*y)*(fact*y);
664 double w = w0*sqrt(aux);
665 double dwdy = w0*fact*fact*y/sqrt(aux);
667 double phi0 = atan(fact*y);
668 double dphi0dy = cos(phi0)*cos(phi0)*fact;
670 double r = y + 1./y/(fact*fact);
671 double drdy = 1. - 1./(y*y)/(fact*fact);
674 complex<double> ze = - x*x/(w*w) - zi*rk*y - zi * M_PI * x * x/rl/r +
677 complex<double> zdedx = -2.*x/(w*w) - 2.*zi*M_PI*x/rl/r;
678 complex<double> zdedy = 2.*x*x/(w*w*w)*dwdy - zi*rk + zi*M_PI*x*x/rl/
679 (r*r)*drdy + zi*dphi0dy/2.;
681 double pf = pow(2.0/M_PI/(w*w),0.25);
682 double dpfdy = -pow(2./M_PI/(w*w),-0.75)/M_PI/(w*w*w)*dwdy;
684 complex<double> zp = pf*exp(ze);
685 complex<double> zdpdx = zp*zdedx;
686 complex<double> zdpdy = dpfdy*exp(ze)+zp*zdedy;
688 dp[0] = (zdpdx*dxdxprim + zdpdy*dydxprim);
689 dp[1] = (zdpdx*dxdyprim + zdpdy*dydyprim);
690 if (
dim == 3) { dp[2] = 0.0; }
698 complex<double> zi = complex<double>(0., 1.);
705 complex<double>
p = exp(
alpha);
713 double alpha = (180+degrees) * M_PI/180.;
714 double sina = sin(
alpha);
715 double cosa = cos(
alpha);
717 double xprim=X(0) + 0.1;
718 double yprim=X(1) + 0.1;
720 double x = xprim*sina - yprim*cosa;
721 double y = xprim*cosa + yprim*sina;
722 double dxdxprim = sina, dxdyprim = -cosa;
723 double dydxprim = cosa, dydyprim = sina;
725 double rl = 2.*M_PI/rk;
731 double fact = rl/M_PI/(w0*w0);
732 double aux = 1. + (fact*y)*(fact*y);
734 double w = w0*sqrt(aux);
735 double dwdy = w0*fact*fact*y/sqrt(aux);
736 double d2wdydy = w0*fact*fact*(1. - (fact*y)*(fact*y)/aux)/sqrt(aux);
738 double phi0 = atan(fact*y);
739 double dphi0dy = cos(phi0)*cos(phi0)*fact;
740 double d2phi0dydy = -2.*cos(phi0)*sin(phi0)*fact*dphi0dy;
742 double r = y + 1./y/(fact*fact);
743 double drdy = 1. - 1./(y*y)/(fact*fact);
744 double d2rdydy = 2./(y*y*y)/(fact*fact);
747 complex<double> ze = - x*x/(w*w) - zi*rk*y - zi * M_PI * x * x/rl/r +
750 complex<double> zdedx = -2.*x/(w*w) - 2.*zi*M_PI*x/rl/r;
751 complex<double> zdedy = 2.*x*x/(w*w*w)*dwdy - zi*rk + zi*M_PI*x*x/rl/
752 (r*r)*drdy + zi*dphi0dy/2.;
753 complex<double> zd2edxdx = -2./(w*w) - 2.*zi*M_PI/rl/r;
754 complex<double> zd2edxdy = 4.*x/(w*w*w)*dwdy + 2.*zi*M_PI*x/rl/(r*r)*drdy;
755 complex<double> zd2edydx = zd2edxdy;
756 complex<double> zd2edydy = -6.*x*x/(w*w*w*w)*dwdy*dwdy + 2.*x*x/
757 (w*w*w)*d2wdydy - 2.*zi*M_PI*x*x/rl/(r*r*r)*drdy*drdy
758 + zi*M_PI*x*x/rl/(r*r)*d2rdydy + zi/2.*d2phi0dydy;
760 double pf = pow(2.0/M_PI/(w*w),0.25);
761 double dpfdy = -pow(2./M_PI/(w*w),-0.75)/M_PI/(w*w*w)*dwdy;
762 double d2pfdydy = -1./M_PI*pow(2./M_PI,-0.75)*(-1.5*pow(w,-2.5)
763 *dwdy*dwdy + pow(w,-1.5)*d2wdydy);
765 complex<double> zp = pf*exp(ze);
766 complex<double> zdpdx = zp*zdedx;
767 complex<double> zdpdy = dpfdy*exp(ze)+zp*zdedy;
768 complex<double> zd2pdxdx = zdpdx*zdedx + zp*zd2edxdx;
769 complex<double> zd2pdxdy = zdpdy*zdedx + zp*zd2edxdy;
770 complex<double> zd2pdydx = dpfdy*exp(ze)*zdedx + zdpdx*zdedy + zp*zd2edydx;
771 complex<double> zd2pdydy = d2pfdydy*exp(ze) + dpfdy*exp(
772 ze)*zdedy + zdpdy*zdedy + zp*zd2edydy;
775 return (zd2pdxdx*dxdxprim + zd2pdydx*dydxprim)*dxdxprim
776 + (zd2pdxdy*dxdxprim + zd2pdydy*dydxprim)*dydxprim
777 + (zd2pdxdx*dxdyprim + zd2pdydx*dydyprim)*dxdyprim
778 + (zd2pdxdy*dxdyprim + zd2pdydy*dydyprim)*dydyprim;
virtual double ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const
double p_exact_i(const Vector &x)
Class for domain integration L(v) := (f, v)
Conjugate gradient method.
virtual Operator & real()
Real or imaginary part accessor methods.
Class for grid function - Vector with associated FE space.
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 u_exact_r(const Vector &x, Vector &u)
void SetSize(int s)
Resize the vector to size s.
Mimic the action of a complex operator using two real operators.
void hatu_exact_r(const Vector &X, Vector &hatu)
void PrintUsage(std::ostream &out) const
Print the usage message.
Vector coefficient that is constant in space and time.
Pointer to an Operator of a specified type.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
int Size() const
Returns the size of the vector.
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 ...
double d2_exact_i(const Vector &x)
bool Good() const
Return true if the command line options were parsed successfully.
int main(int argc, char *argv[])
double hatp_exact_r(const Vector &X)
double hatp_exact_i(const Vector &X)
(Q div u, div v) for RT elements
void gradp_exact_r(const Vector &x, Vector &gradu)
Data type for Gauss-Seidel smoother of sparse matrix.
double divu_exact_i(const Vector &x)
int NumRowBlocks() const
Return the number of row blocks.
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 Append(const T &el)
Append element 'el' to array, resize if necessary.
int GetNumIterations() const
Returns the number of iterations taken during the last call to Mult()
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Arbitrary order "H^{1/2}-conforming" trace finite elements defined on the interface between mesh elem...
void SetMaxIter(int max_it)
double Sum() const
Return the sum of the vector entries.
void VisualizeField(socketstream &sock, const char *vishost, int visport, ParGridFunction &gf, const char *title, int x=0, int y=0, int w=400, int h=400, bool vec=false)
complex< double > acoustics_solution(const Vector &X)
double rhs_func_i(const Vector &x)
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
A general vector function coefficient.
void acoustics_solution_grad(const Vector &X, vector< complex< double >> &dp)
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.
double p(const Vector &x, double t)
void SetRelTol(double rtol)
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.
virtual Operator & imag()
double p_exact_r(const Vector &x)
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
void hatu_exact_i(const Vector &X, Vector &hatu)
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
double divu_exact_r(const Vector &x)
SparseMatrix & GetBlock(int i, int j)
Return a reference to block (i,j). Reference may be invalid if Aij(i,j) == NULL.
complex< double > acoustics_solution_laplacian(const Vector &X)
void u_exact_i(const Vector &x, Vector &u)
int Size() const
Return the logical size of the array.
T & Last()
Return the last element in the array.
double rhs_func_r(const Vector &x)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
A general function coefficient.
double d2_exact_r(const Vector &x)
Arbitrary order "H^{-1/2}-conforming" face finite elements defined on the interface between mesh elem...
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Arbitrary order H1-conforming (continuous) finite elements.
double u(const Vector &xvec)
A class to handle Block systems in a matrix-free implementation.
void gradp_exact_i(const Vector &x, Vector &gradu)
void SetBlock(int iRow, int iCol, Operator *op, double c=1.0)
Add a block op in the block-entry (iblock, jblock).
void ProjectBdrCoefficient(Coefficient &coeff, Array< int > &attr)
Project a Coefficient on the GridFunction, modifying only DOFs on the boundary associated with the bo...
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).
Arbitrary order "L2-conforming" discontinuous finite elements.