91 std::vector<complex<real_t>> &curlE);
94 std::vector<complex<real_t>> &curlcurlE);
128int main(
int argc,
char *argv[])
130 const char *mesh_file =
"../../data/inline-quad.mesh";
133 bool visualization =
true;
137 bool static_cond =
false;
140 args.
AddOption(&mesh_file,
"-m",
"--mesh",
141 "Mesh file to use.");
143 "Finite element order (polynomial degree)");
144 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
145 "--no-visualization",
146 "Enable or disable GLVis visualization.");
147 args.
AddOption(&rnum,
"-rnum",
"--number-of-wavelengths",
148 "Number of wavelengths");
150 "Permeability of free space (or 1/(spring constant)).");
152 "Permittivity of free space (or mass constant).");
153 args.
AddOption(&delta_order,
"-do",
"--delta-order",
154 "Order enrichment for DPG test space.");
155 args.
AddOption(&ref,
"-ref",
"--serial-ref",
156 "Number of serial refinements.");
157 args.
AddOption(&static_cond,
"-sc",
"--static-condensation",
"-no-sc",
158 "--no-static-condensation",
"Enable static condensation.");
159 args.
AddOption(&visport,
"-p",
"--send-port",
"Socket for GLVis.");
168 omega = 2.*M_PI*rnum;
170 Mesh mesh(mesh_file, 1, 1);
172 MFEM_VERIFY(
dim > 1,
"Dimension = 1 is not supported in this example");
175 int test_order = order+delta_order;
228 rot_mat(0,0) = 0.; rot_mat(0,1) = 1.;
229 rot_mat(1,0) = -1.; rot_mat(1,1) = 0.;
239 trial_fes.
Append(hatE_fes);
240 trial_fes.
Append(hatH_fes);
250 nullptr,TrialSpace::E_space,TestSpace::F_space);
252 a->AddTrialIntegrator(
nullptr,
254 TrialSpace::E_space,TestSpace::G_space);
257 nullptr, TrialSpace::H_space,TestSpace::G_space);
262 a->AddTrialIntegrator(
nullptr,
264 TrialSpace::H_space,TestSpace::F_space);
267 TrialSpace::hatE_space,TestSpace::F_space);
273 TrialSpace::H_space,TestSpace::F_space);
276 TrialSpace::hatE_space, TestSpace::F_space);
280 TrialSpace::hatH_space, TestSpace::G_space);
285 TestSpace::G_space,TestSpace::G_space);
288 TestSpace::G_space, TestSpace::G_space);
294 TestSpace::F_space, TestSpace::F_space);
297 TestSpace::F_space,TestSpace::F_space);
300 TestSpace::F_space, TestSpace::F_space);
303 TestSpace::F_space, TestSpace::G_space);
306 TestSpace::F_space, TestSpace::G_space);
309 TestSpace::G_space, TestSpace::F_space);
312 TestSpace::G_space, TestSpace::F_space);
315 TestSpace::G_space, TestSpace::G_space);
321 TestSpace::F_space, TestSpace::F_space);
324 TestSpace::F_space, TestSpace::F_space);
327 TestSpace::F_space, TestSpace::F_space);
329 a->AddTestIntegrator(
nullptr,
331 TestSpace::F_space, TestSpace::G_space);
334 TestSpace::F_space, TestSpace::G_space);
337 TestSpace::G_space, TestSpace::F_space);
339 a->AddTestIntegrator(
nullptr,
341 TestSpace::G_space, TestSpace::F_space);
344 TestSpace::G_space, TestSpace::G_space);
363 std::cout <<
"\n Ref |"
368 <<
" PCG it |" << endl;
369 std::cout << std::string(60,
'-')
372 for (
int it = 0; it<=ref; it++)
374 if (static_cond) {
a->EnableStaticCondensation(); }
387 for (
int j = 0; j < ess_tdof_list.
Size(); j++)
417 a->FormLinearSystem(ess_tdof_list,x,Ah, X,B);
427 int k = (static_cond) ? 2 : 0;
428 for (
int i=0; i<num_blocks; i++)
430 tdof_offsets[i+1] = trial_fes[i+k]->GetTrueVSize();
431 tdof_offsets[num_blocks+i+1] = trial_fes[i+k]->GetTrueVSize();
436 for (
int i = 0; i<num_blocks; i++)
438 for (
int j = 0; j<num_blocks; j++)
440 A.
SetBlock(i,j,&A_r->GetBlock(i,j));
442 A.
SetBlock(i+num_blocks,j+num_blocks,&A_r->GetBlock(i,j));
449 for (
int i = 0; i<num_blocks; i++)
464 a->RecoverFEMSolution(X,x);
479 for (
int i = 0; i<trial_fes.
Size(); i++)
481 dofs += trial_fes[i]->GetTrueVSize();
489 real_t L2Error = sqrt(E_err_r*E_err_r + E_err_i*E_err_i
490 + H_err_r*H_err_r + H_err_i*H_err_i);
492 real_t rate_err = (it) ?
dim*log(err0/L2Error)/log((
real_t)dof0/dofs) : 0.0;
497 std::ios oldState(
nullptr);
498 oldState.copyfmt(std::cout);
499 std::cout << std::right << std::setw(5) << it <<
" | "
500 << std::setw(10) << dof0 <<
" | "
501 << std::setprecision(1) << std::fixed
502 << std::setw(4) << 2*rnum <<
" π | "
503 << std::setprecision(3)
504 << std::setw(10) << std::scientific << err0 <<
" | "
505 << std::setprecision(2)
506 << std::setw(6) << std::fixed << rate_err <<
" | "
509 std::cout.copyfmt(oldState);
513 const char * keys = (it == 0 &&
dim == 2) ?
"jRcml\n" :
nullptr;
516 "Numerical Electric field (real part)", 0, 0, 500, 500, keys);
518 "Numerical Electric field (imaginary part)", 501, 0, 500, 500, keys);
527 for (
int i =0; i<trial_fes.
Size(); i++)
529 trial_fes[i]->Update(
false);
551 std::vector<std::complex<real_t>> E;
554 for (
unsigned i = 0; i < E.size(); i++)
562 std::vector<std::complex<real_t>> E;
565 for (
unsigned i = 0; i < E.size(); i++)
573 std::vector<std::complex<real_t>> curlE;
576 for (
unsigned i = 0; i < curlE.size(); i++)
578 curlE_r[i]= curlE[i].real();
584 std::vector<std::complex<real_t>> curlE;
587 for (
unsigned i = 0; i < curlE.size(); i++)
589 curlE_i[i]= curlE[i].imag();
595 std::vector<std::complex<real_t>> curlcurlE;
597 curlcurlE_r.
SetSize(curlcurlE.size());
598 for (
unsigned i = 0; i < curlcurlE.size(); i++)
600 curlcurlE_r[i]= curlcurlE[i].real();
606 std::vector<std::complex<real_t>> curlcurlE;
608 curlcurlE_i.
SetSize(curlcurlE.size());
609 for (
unsigned i = 0; i < curlcurlE.size(); i++)
611 curlcurlE_i[i]= curlcurlE[i].imag();
622 for (
int i = 0; i<
dimc; i++)
624 H_r(i) = - curlE_i(i) / (
omega *
mu);
635 for (
int i = 0; i<
dimc; i++)
637 H_i(i) = curlE_r(i) / (
omega *
mu);
647 for (
int i = 0; i<
dim; i++)
649 curlH_r(i) = -curlcurlE_i(i) / (
omega *
mu);
659 for (
int i = 0; i<
dim; i++)
661 curlH_i(i) = curlcurlE_r(i) / (
omega *
mu);
732 for (
int i = 0; i<
dim; i++)
745 for (
int i = 0; i<
dim; i++)
754 std::complex<real_t> zi(0,1);
755 std::complex<real_t> pw = exp(-zi *
omega * (X.
Sum()));
758 if (
dim == 3) { E[2] = 0.0; }
762 std::vector<complex<real_t>> &curlE)
765 std::complex<real_t> zi(0,1);
766 std::complex<real_t> pw = exp(-zi *
omega * (X.
Sum()));
770 curlE[1] = -zi *
omega * pw;
771 curlE[2] = zi *
omega * pw;
775 curlE[0] = zi *
omega * pw;
780 std::vector<complex<real_t>> &curlcurlE)
782 curlcurlE.resize(
dim);
783 std::complex<real_t> zi(0,1);
784 std::complex<real_t> pw = exp(-zi *
omega * (X.
Sum()));
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.
Integrator for for Nedelec elements.
Data type dense matrix using column-major storage.
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().
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.
virtual void ProjectBdrCoefficientTangent(VectorCoefficient &vcoeff, const Array< int > &bdr_attr)
Project the tangential components of the given VectorCoefficient on the boundary. Only boundary attri...
void ProjectBdrCoefficientNormal(VectorCoefficient &vcoeff, const Array< int > &bdr_attr)
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.
A matrix coefficient that is constant in space and time.
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 *)
Arbitrary order H(curl)-conforming Nedelec finite elements.
Arbitrary order H(curl)-trace finite elements defined on the interface between mesh elements (faces,...
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^{-1/2}-conforming" face finite elements defined on the interface between mesh elem...
Matrix coefficient defined as a product of a scalar coefficient and a matrix coefficient.
for VectorFiniteElements (Nedelec, Raviart-Thomas)
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 curlE_exact_i(const Vector &x, Vector &curlE_i)
void H_exact_i(const Vector &x, Vector &H_i)
void curlcurlE_exact_r(const Vector &x, Vector &curlcurlE_r)
void hatH_exact_r(const Vector &X, Vector &hatH_r)
void hatE_exact_r(const Vector &X, Vector &hatE_r)
void H_exact_r(const Vector &x, Vector &H_r)
real_t hatH_exact_scalar_i(const Vector &X)
void curlH_exact_r(const Vector &x, Vector &curlH_r)
real_t hatH_exact_scalar_r(const Vector &X)
void rhs_func_r(const Vector &x, Vector &J_r)
void hatH_exact_i(const Vector &X, Vector &hatH_i)
void rhs_func_i(const Vector &x, Vector &J_i)
void curlcurlE_exact_i(const Vector &x, Vector &curlcurlE_i)
void E_exact_r(const Vector &x, Vector &E_r)
void maxwell_solution_curlcurl(const Vector &X, std::vector< complex< real_t > > &curlcurlE)
void E_exact_i(const Vector &x, Vector &E_i)
void hatE_exact_i(const Vector &X, Vector &hatE_i)
void maxwell_solution_curl(const Vector &X, std::vector< complex< real_t > > &curlE)
void maxwell_solution(const Vector &X, std::vector< complex< real_t > > &E)
void curlE_exact_r(const Vector &x, Vector &curlE_r)
void curlH_exact_i(const Vector &x, Vector &curlH_i)
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)