111int main(
int argc,
char *argv[])
113 const char *mesh_file =
"../../data/inline-quad.mesh";
116 bool visualization =
true;
119 bool static_cond =
false;
124 args.
AddOption(&mesh_file,
"-m",
"--mesh",
125 "Mesh file to use.");
127 "Finite element order (polynomial degree)");
128 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
129 "--no-visualization",
130 "Enable or disable GLVis visualization.");
131 args.
AddOption(&rnum,
"-rnum",
"--number_of_wavelengths",
132 "Number of wavelengths");
133 args.
AddOption(&iprob,
"-prob",
"--problem",
"Problem case"
134 " 0: plane wave, 1: Gaussian beam");
135 args.
AddOption(&delta_order,
"-do",
"--delta_order",
136 "Order enrichment for DPG test space.");
137 args.
AddOption(&ref,
"-ref",
"--refinements",
138 "Number of serial refinements.");
139 args.
AddOption(&static_cond,
"-sc",
"--static-condensation",
"-no-sc",
140 "--no-static-condensation",
"Enable static condensation.");
141 args.
AddOption(&visport,
"-p",
"--send-port",
"Socket for GLVis.");
150 if (iprob > 1) { iprob = 0; }
153 omega = 2.*M_PI*rnum;
155 Mesh mesh(mesh_file, 1, 1);
157 MFEM_VERIFY(
dim > 1,
"Dimension = 1 is not supported in this example");
190 int test_order = order+delta_order;
209 trial_fes.
Append(hatp_fes);
210 trial_fes.
Append(hatu_fes);
219 TrialSpace::p_space,TestSpace::q_space);
222 nullptr,TrialSpace::u_space,TestSpace::q_space);
225 TrialSpace::p_space,TestSpace::v_space);
227 a->AddTrialIntegrator(
nullptr,
229 TrialSpace::u_space,TestSpace::v_space);
232 TrialSpace::hatp_space,TestSpace::v_space);
235 TrialSpace::hatu_space,TestSpace::q_space);
240 TestSpace::q_space, TestSpace::q_space);
243 TestSpace::q_space, TestSpace::q_space);
246 TestSpace::v_space, TestSpace::v_space);
249 TestSpace::v_space, TestSpace::v_space);
252 TestSpace::q_space, TestSpace::v_space);
255 TestSpace::v_space, TestSpace::q_space);
258 TestSpace::v_space, TestSpace::v_space);
261 TestSpace::v_space, TestSpace::q_space);
264 TestSpace::q_space, TestSpace::v_space);
267 TestSpace::q_space, TestSpace::q_space);
272 if (
prob == prob_type::gaussian_beam)
289 std::cout <<
"\n Ref |"
294 <<
" PCG it |" << endl;
295 std::cout << std::string(60,
'-')
298 for (
int it = 0; it<=ref; it++)
300 if (static_cond) {
a->EnableStaticCondensation(); }
313 for (
int j = 0; j < ess_tdof_list.
Size(); j++)
336 a->FormLinearSystem(ess_tdof_list,x,Ah, X,B);
347 int k = (static_cond) ? 2 : 0;
348 for (
int i=0; i<num_blocks; i++)
350 tdof_offsets[i+1] = trial_fes[i+k]->GetTrueVSize();
351 tdof_offsets[num_blocks+i+1] = trial_fes[i+k]->GetTrueVSize();
356 for (
int i = 0; i<num_blocks; i++)
358 for (
int j = 0; j<num_blocks; j++)
360 A.
SetBlock(i,j,&A_r->GetBlock(i,j));
362 A.
SetBlock(i+num_blocks,j+num_blocks,&A_r->GetBlock(i,j));
369 for (
int i = 0; i<num_blocks; i++)
384 a->RecoverFEMSolution(X,x);
399 for (
int i = 0; i<trial_fes.
Size(); i++)
401 dofs += trial_fes[i]->GetTrueVSize();
409 real_t L2Error = sqrt(p_err_r*p_err_r + p_err_i*p_err_i
410 +u_err_r*u_err_r + u_err_i*u_err_i);
412 real_t rate_err = (it) ?
dim*log(err0/L2Error)/log((
real_t)dof0/dofs) : 0.0;
417 std::ios oldState(
nullptr);
418 oldState.copyfmt(std::cout);
419 std::cout << std::right << std::setw(5) << it <<
" | "
420 << std::setw(10) << dof0 <<
" | "
421 << std::setprecision(1) << std::fixed
422 << std::setw(4) << 2*rnum <<
" π | "
423 << std::setprecision(3)
424 << std::setw(10) << std::scientific << err0 <<
" | "
425 << std::setprecision(2)
426 << std::setw(6) << std::fixed << rate_err <<
" | "
429 std::cout.copyfmt(oldState);
433 const char * keys = (it == 0 &&
dim == 2) ?
"jRcml\n" :
nullptr;
436 "Numerical presure (real part)", 0, 0, 500, 500, keys);
438 "Numerical presure (imaginary part)", 501, 0, 500, 500, keys);
447 for (
int i =0; i<trial_fes.
Size(); i++)
449 trial_fes[i]->Update(
false);
492 vector<complex<real_t>> grad;
494 for (
unsigned i = 0; i < grad.size(); i++)
496 grad_r[i] = grad[i].real();
503 vector<complex<real_t>> grad;
505 for (
unsigned i = 0; i < grad.size(); i++)
507 grad_i[i] = grad[i].imag();
578 complex<real_t> zi = complex<real_t>(0., 1.);
599 real_t x = xprim*sina - yprim*cosa;
600 real_t y = xprim*cosa + yprim*sina;
606 real_t fact = rl/M_PI/(w0*w0);
607 real_t aux = 1. + (fact*y)*(fact*y);
609 real_t phi0 = atan(fact*y);
610 real_t r = y + 1./y/(fact*fact);
613 complex<real_t> ze = - x*x/(w*w) - zi*rk*y - zi *
real_t(M_PI) * x * x/rl/r +
616 real_t pf = pow(2.0/M_PI/(w*w),0.25);
626 complex<real_t> zi = complex<real_t>(0., 1.);
633 complex<real_t>
p = exp(
alpha);
634 for (
int i = 0; i<X.
Size(); i++)
636 dp[i] = zi *
beta *
p;
651 real_t x = xprim*sina - yprim*cosa;
652 real_t y = xprim*cosa + yprim*sina;
653 real_t dxdxprim = sina, dxdyprim = -cosa;
654 real_t dydxprim = cosa, dydyprim = sina;
662 real_t fact = rl/M_PI/(w0*w0);
663 real_t aux = 1. + (fact*y)*(fact*y);
666 real_t dwdy = w0*fact*fact*y/sqrt(aux);
668 real_t phi0 = atan(fact*y);
669 real_t dphi0dy = cos(phi0)*cos(phi0)*fact;
671 real_t r = y + 1./y/(fact*fact);
672 real_t drdy = 1. - 1./(y*y)/(fact*fact);
674 constexpr real_t r2 = 2.0;
678 complex<real_t> ze = - x*x/(w*w) - zi*rk*y - zi * rPI * x * x/rl/r +
681 complex<real_t> zdedx = -r2*x/(w*w) - r2*zi*rPI*x/rl/r;
682 complex<real_t> zdedy = r2*x*x/(w*w*w)*dwdy - zi*rk + zi*rPI*x*x/rl/
683 (r*r)*drdy + zi*dphi0dy/r2;
685 real_t pf = pow(2.0/M_PI/(w*w),0.25);
686 real_t dpfdy = -pow(2./M_PI/(w*w),-0.75)/M_PI/(w*w*w)*dwdy;
688 complex<real_t> zp = pf*exp(ze);
689 complex<real_t> zdpdx = zp*zdedx;
690 complex<real_t> zdpdy = dpfdy*exp(ze)+zp*zdedy;
692 dp[0] = (zdpdx*dxdxprim + zdpdy*dydxprim);
693 dp[1] = (zdpdx*dxdyprim + zdpdy*dydyprim);
694 if (
dim == 3) { dp[2] = 0.0; }
702 complex<real_t> zi = complex<real_t>(0., 1.);
709 complex<real_t>
p = exp(
alpha);
724 real_t x = xprim*sina - yprim*cosa;
725 real_t y = xprim*cosa + yprim*sina;
726 real_t dxdxprim = sina, dxdyprim = -cosa;
727 real_t dydxprim = cosa, dydyprim = sina;
735 real_t fact = rl/M_PI/(w0*w0);
736 real_t aux = 1. + (fact*y)*(fact*y);
739 real_t dwdy = w0*fact*fact*y/sqrt(aux);
740 real_t d2wdydy = w0*fact*fact*(1. - (fact*y)*(fact*y)/aux)/sqrt(aux);
742 real_t phi0 = atan(fact*y);
743 real_t dphi0dy = cos(phi0)*cos(phi0)*fact;
744 real_t d2phi0dydy = -2.*cos(phi0)*sin(phi0)*fact*dphi0dy;
746 real_t r = y + 1./y/(fact*fact);
747 real_t drdy = 1. - 1./(y*y)/(fact*fact);
748 real_t d2rdydy = 2./(y*y*y)/(fact*fact);
750 constexpr real_t r2 = 2.0;
754 complex<real_t> ze = - x*x/(w*w) - zi*rk*y - zi * rPI * x * x/rl/r +
757 complex<real_t> zdedx = -r2*x/(w*w) - r2*zi*rPI*x/rl/r;
758 complex<real_t> zdedy = r2*x*x/(w*w*w)*dwdy - zi*rk + zi*rPI*x*x/rl/
759 (r*r)*drdy + zi*dphi0dy/r2;
760 complex<real_t> zd2edxdx = -r2/(w*w) - r2*zi*rPI/rl/r;
761 complex<real_t> zd2edxdy = 4_r*x/(w*w*w)*dwdy + r2*zi*rPI*x/rl/(r*r)*drdy;
762 complex<real_t> zd2edydx = zd2edxdy;
763 complex<real_t> zd2edydy = -6_r*x*x/(w*w*w*w)*dwdy*dwdy + r2*x*x/
764 complex<real_t>(w*w*w)*d2wdydy - r2*zi*rPI*x*x/rl/(r*r*r)*drdy*drdy
765 + zi*rPI*x*x/rl/(r*r)*d2rdydy + zi/r2*d2phi0dydy;
767 real_t pf = pow(2.0/M_PI/(w*w),0.25);
768 real_t dpfdy = -pow(2./M_PI/(w*w),-0.75)/M_PI/(w*w*w)*dwdy;
769 real_t d2pfdydy = -1./M_PI*pow(2./M_PI,-0.75)*(-1.5*pow(w,-2.5)
770 *dwdy*dwdy + pow(w,-1.5)*d2wdydy);
772 complex<real_t> zp = pf*exp(ze);
773 complex<real_t> zdpdx = zp*zdedx;
774 complex<real_t> zdpdy = dpfdy*exp(ze)+zp*zdedy;
775 complex<real_t> zd2pdxdx = zdpdx*zdedx + zp*zd2edxdx;
776 complex<real_t> zd2pdxdy = zdpdy*zdedx + zp*zd2edxdy;
777 complex<real_t> zd2pdydx = dpfdy*exp(ze)*zdedx + zdpdx*zdedy + zp*zd2edydx;
778 complex<real_t> zd2pdydy = d2pfdydy*exp(ze) + dpfdy*exp(
779 ze)*zdedy + zdpdy*zdedy + zp*zd2edydy;
782 return (zd2pdxdx*dxdxprim + zd2pdydx*dydxprim)*dxdxprim
783 + (zd2pdxdy*dxdxprim + zd2pdydy*dydxprim)*dydxprim
784 + (zd2pdxdx*dxdyprim + zd2pdydx*dydyprim)*dxdyprim
785 + (zd2pdxdy*dxdyprim + zd2pdydy*dydyprim)*dydyprim;
real_t hatp_exact_r(const Vector &X)
void hatu_exact_i(const Vector &X, Vector &hatu)
real_t p_exact_r(const Vector &x)
complex< real_t > acoustics_solution(const Vector &X)
void gradp_exact_i(const Vector &x, Vector &gradu)
void gradp_exact_r(const Vector &x, Vector &gradu)
real_t rhs_func_r(const Vector &x)
complex< real_t > acoustics_solution_laplacian(const Vector &X)
real_t divu_exact_i(const Vector &x)
void u_exact_r(const Vector &x, Vector &u)
real_t divu_exact_r(const Vector &x)
real_t d2_exact_r(const Vector &x)
real_t hatp_exact_i(const Vector &X)
real_t d2_exact_i(const Vector &x)
real_t rhs_func_i(const Vector &x)
void acoustics_solution_grad(const Vector &X, vector< complex< real_t > > &dp)
real_t p_exact_i(const Vector &x)
void hatu_exact_r(const Vector &X, Vector &hatu)
void u_exact_i(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.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
T & Last()
Return the last element in the array.
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).
SparseMatrix & GetBlock(int i, int j)
Return a reference to block (i,j). Reference may be invalid if Aij(i,j) == NULL.
int NumRowBlocks() const
Return the number of row blocks.
A class to handle Block systems in a matrix-free implementation.
void SetBlock(int iRow, int iCol, Operator *op, real_t c=1.0)
Add a block op in the block-entry (iblock, jblock).
Conjugate gradient method.
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the Conjugate Gradient method.
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
Mimic the action of a complex operator using two real operators.
virtual Operator & imag()
virtual Operator & real()
Real or imaginary part accessor methods.
A coefficient that is constant across space and time.
for Raviart-Thomas elements
Class for domain integration .
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const
Get a list of essential true dofs, ess_tdof_list, corresponding to the boundary attributes marked in ...
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
A general function coefficient.
Data type for Gauss-Seidel smoother of sparse matrix.
Class for grid function - Vector with associated FE space.
virtual real_t ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const
Returns ||exsol - u_h||_L2 for scalar or vector H1 or L2 elements.
void ProjectBdrCoefficient(Coefficient &coeff, const Array< int > &attr)
Project a Coefficient on the GridFunction, modifying only DOFs on the boundary associated with the bo...
Arbitrary order H1-conforming (continuous) finite elements.
Arbitrary order "H^{1/2}-conforming" trace finite elements defined on the interface between mesh elem...
void SetRelTol(real_t rtol)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
int GetNumIterations() const
Returns the number of iterations taken during the last call to Mult()
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void SetMaxIter(int max_it)
Arbitrary order "L2-conforming" discontinuous finite elements.
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 *)
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().
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.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Arbitrary order "H^{-1/2}-conforming" face finite elements defined on the interface between mesh elem...
Vector coefficient that is constant in space and time.
A general vector function coefficient.
int Size() const
Returns the size of the vector.
real_t Sum() const
Return the sum of the vector entries.
void SetSize(int s)
Resize the vector to size s.
void VisualizeField(socketstream &sock, const char *vishost, int visport, GridFunction &gf, const char *title, int x, int y, int w, int h, const char *keys, bool vec)
real_t u(const Vector &xvec)
real_t p(const Vector &x, real_t t)