215int main(
int argc,
char *argv[])
221 const char *mesh_file =
"../../data/inline-quad.mesh";
228 real_t relax_factor = 2.0/3;
229 bool static_cond =
false;
234 bool with_pml =
false;
235 bool visualization =
true;
237 bool paraview =
false;
240 args.
AddOption(&mesh_file,
"-m",
"--mesh",
241 "Mesh file to use.");
243 "Finite element order (polynomial degree)");
244 args.
AddOption(&rnum,
"-rnum",
"--number-of-wavelengths",
245 "Number of wavelengths");
247 "Permeability of free space (or 1/(spring constant)).");
249 "Permittivity of free space (or mass constant).");
250 args.
AddOption(&iprob,
"-prob",
"--problem",
"Problem case"
251 " 0: plane wave, 1: Fichera 'oven', "
252 " 2: Generic PML problem with point source given as a load "
253 " 3: Scattering of a plane wave, "
254 " 4: Point source given on the boundary");
255 args.
AddOption(&delta_order,
"-do",
"--delta-order",
256 "Order enrichment for DPG test space.");
257 args.
AddOption(&theta,
"-theta",
"--theta",
258 "Theta parameter for AMR");
259 args.
AddOption(&sr,
"-sref",
"--serial-ref",
260 "Number of parallel refinements.");
261 args.
AddOption(&pr,
"-pref",
"--parallel-ref",
262 "Number of parallel refinements.");
263 args.
AddOption(&pmg,
"-pmg",
"--p-refinement-multigrid",
"-no-pmg",
264 "--no-p-refinement-multigrid",
"Enable P-Refinement Multigrid.");
265 args.
AddOption(&pmg_levels,
"-pmgl",
"--p-refinement-multigrid-levels",
266 "Number of levels for P-Refinement Multigrid.");
267 args.
AddOption(&relax_factor,
"-rf",
"--relaxation-factor",
268 "Relaxation factor for the p-multigrid smoother.");
269 args.
AddOption(&static_cond,
"-sc",
"--static-condensation",
"-no-sc",
270 "--no-static-condensation",
"Enable static condensation.");
271 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
272 "--no-visualization",
273 "Enable or disable GLVis visualization.");
274 args.
AddOption(¶view,
"-paraview",
"--paraview",
"-no-paraview",
276 "Enable or disable ParaView visualization.");
277 args.
AddOption(&visport,
"-p",
"--send-port",
"Socket for GLVis.");
288 if (iprob > 4) { iprob = 0; }
290 omega = 2.*M_PI*rnum;
298 mesh_file =
"meshes/fichera-waveguide.mesh";
300 rnum =
omega/(2.*M_PI);
309 mesh_file =
"meshes/scatter.mesh";
317 Mesh mesh(mesh_file, 1, 1);
319 MFEM_VERIFY(
dim > 1,
"Dimension = 1 is not supported in this example");
323 for (
int i = 0; i<sr; i++)
338 ParMesh pmesh(MPI_COMM_WORLD, mesh);
371 int test_order = order+delta_order;
392 trial_fes.
Append(hatE_fes);
393 trial_fes.
Append(hatH_fes);
407 rot_mat(0,0) = 0.; rot_mat(0,1) = 1.;
408 rot_mat(1,0) = -1.; rot_mat(1,1) = 0.;
435 epsomeg_cf = &epsomeg;
436 negepsomeg_cf = &negepsomeg;
437 eps2omeg2_cf = &eps2omeg2;
439 negmuomeg_cf = &negmuomeg;
440 mu2omeg2_cf = &mu2omeg2;
442 negepsrot_cf = &negepsrot;
469 abs_detJ_Jt_J_inv_2);
471 abs_detJ_Jt_J_inv_2);
478 epsomeg_detJ_Jt_J_inv_i,attrPML);
480 epsomeg_detJ_Jt_J_inv_r,attrPML);
482 negepsomeg_detJ_Jt_J_inv_r,attrPML);
486 negmuomeg_detJ_Jt_J_inv_i,attrPML);
488 negmuomeg_detJ_Jt_J_inv_r,attrPML);
490 mu2omeg2_detJ_Jt_J_inv_2,attrPML);
492 eps2omeg2_detJ_Jt_J_inv_2,attrPML);
504 epsomeg_detJ_Jt_J_inv_i, rot);
506 epsomeg_detJ_Jt_J_inv_r, rot);
508 negepsomeg_detJ_Jt_J_inv_r, rot);
510 *epsomeg_detJ_Jt_J_inv_i_rot, attrPML);
512 *epsomeg_detJ_Jt_J_inv_r_rot, attrPML);
514 *negepsomeg_detJ_Jt_J_inv_r_rot, attrPML);
522 nullptr,TrialSpace::E_space, TestSpace::F_space);
524 a->AddTrialIntegrator(
nullptr,
526 TrialSpace::E_space,TestSpace::G_space);
529 nullptr,TrialSpace::H_space, TestSpace::G_space);
532 TrialSpace::hatH_space, TestSpace::G_space);
536 TestSpace::G_space,TestSpace::G_space);
539 TestSpace::G_space,TestSpace::G_space);
546 TrialSpace::H_space,TestSpace::F_space);
549 TrialSpace::hatE_space, TestSpace::F_space);
554 TestSpace::F_space, TestSpace::F_space);
557 TestSpace::F_space,TestSpace::F_space);
560 TestSpace::F_space, TestSpace::F_space);
563 TestSpace::F_space, TestSpace::G_space);
566 TestSpace::F_space, TestSpace::G_space);
569 TestSpace::G_space, TestSpace::F_space);
572 TestSpace::G_space, TestSpace::F_space);
575 TestSpace::G_space, TestSpace::G_space);
581 TrialSpace::H_space, TestSpace::F_space);
584 TrialSpace::hatE_space, TestSpace::F_space);
588 TestSpace::F_space, TestSpace::F_space);
591 TestSpace::F_space, TestSpace::F_space);
594 TestSpace::F_space, TestSpace::F_space);
596 a->AddTestIntegrator(
nullptr,
598 TestSpace::F_space, TestSpace::G_space);
601 TestSpace::F_space, TestSpace::G_space);
604 TestSpace::G_space, TestSpace::F_space);
606 a->AddTestIntegrator(
nullptr,
609 TestSpace::G_space, TestSpace::F_space);
612 TestSpace::G_space, TestSpace::G_space);
619 a->AddTrialIntegrator(
621 epsomeg_detJ_Jt_J_inv_i_restr)),
623 negepsomeg_detJ_Jt_J_inv_r_restr)),
624 TrialSpace::E_space,TestSpace::G_space);
630 a->AddTrialIntegrator(
632 negmuomeg_detJ_Jt_J_inv_i_restr)),
634 muomeg_detJ_Jt_J_inv_r_restr)),
635 TrialSpace::H_space, TestSpace::F_space);
638 a->AddTestIntegrator(
640 TestSpace::F_space, TestSpace::F_space);
645 negmuomeg_detJ_Jt_J_inv_i_restr),
647 TestSpace::F_space,TestSpace::G_space);
651 epsomeg_detJ_Jt_J_inv_i_restr),
653 TestSpace::F_space,TestSpace::G_space);
657 negmuomeg_detJ_Jt_J_inv_i_restr),
659 TestSpace::G_space, TestSpace::F_space);
663 epsomeg_detJ_Jt_J_inv_i_restr),
665 TestSpace::G_space, TestSpace::F_space);
668 eps2omeg2_detJ_Jt_J_inv_2_restr),
nullptr,
669 TestSpace::G_space, TestSpace::G_space);
676 a->AddTrialIntegrator(
679 TrialSpace::H_space, TestSpace::F_space);
682 a->AddTestIntegrator(
new MassIntegrator(mu2omeg2_detJ_2_restr),
nullptr,
683 TestSpace::F_space, TestSpace::F_space);
686 a->AddTestIntegrator(
689 TestSpace::F_space, TestSpace::G_space);
693 *epsomeg_detJ_Jt_J_inv_i_rot_restr),
695 TestSpace::F_space, TestSpace::G_space);
700 TestSpace::G_space, TestSpace::F_space);
703 a->AddTestIntegrator(
705 *epsomeg_detJ_Jt_J_inv_i_rot_restr)),
707 *epsomeg_detJ_Jt_J_inv_r_rot_restr)),
708 TestSpace::G_space, TestSpace::F_space);
711 eps2omeg2_detJ_Jt_J_inv_2_restr),
nullptr,
712 TestSpace::G_space, TestSpace::G_space);
738 std::cout <<
"\n Ref |"
743 std::cout <<
" L2 Error |"
746 std::cout <<
" Residual |"
748 <<
" PCG it |" << endl;
749 std::cout << std::string((
exact_known) ? 82 : 60,
'-')
778 if (static_cond) {
a->EnableStaticCondensation(); }
779 for (
int it = 0; it<=pr; it++)
840 a->GetTraceFESpaces(prec_fes);
844 prec_fes = trial_fes;
850 bool mumps_coarse_solver =
true;
852 bool mumps_coarse_solver =
false;
854 std::vector<Array<int>> ess_bdr_marker(prec_fes.
Size());
855 for (
int b = 0;
b<prec_fes.
Size();
b++)
860 int ess_block = (static_cond) ? 0 : 2;
863 ess_bdr_marker[
b] = ess_bdr;
867 ess_bdr_marker[
b] = 0;
872 pmg_levels, relax_factor, mumps_coarse_solver);
877 BlockA_r->RowOffsets());
879 for (
int i = 0; i<BlockA_r->NumRowBlocks(); i++)
882 prec->SetOperator(BlockA_r->GetBlock(i,i));
890 cg.SetMaxIter(10000);
892 cg.SetOperator(*Ahc);
893 cg.SetPreconditioner(*cprec);
898 int num_iter = cg.GetNumIterations();
900 a->RecoverFEMSolution(X,x);
902 Vector & residuals =
a->ComputeResidual(x);
906 real_t globalresidual = residual * residual;
908 MPI_MAX, MPI_COMM_WORLD);
909 MPI_Allreduce(MPI_IN_PLACE, &globalresidual, 1,
912 globalresidual = sqrt(globalresidual);
917 H_r.
MakeRef(H_fes,x, offsets[1]);
921 for (
int i = 0; i<trial_fes.
Size(); i++)
923 dofs += trial_fes[i]->GlobalTrueVSize();
939 L2Error = sqrt( E_err_r*E_err_r + E_err_i*E_err_i
940 + H_err_r*H_err_r + H_err_i*H_err_i );
941 rate_err = (it) ?
dim*log(err0/L2Error)/log((
real_t)dof0/dofs) : 0.0;
945 real_t rate_res = (it) ?
dim*log(res0/globalresidual)/log((
948 res0 = globalresidual;
953 std::ios oldState(
nullptr);
954 oldState.copyfmt(std::cout);
955 std::cout << std::right << std::setw(5) << it <<
" | "
956 << std::setw(10) << dof0 <<
" | "
957 << std::setprecision(1) << std::fixed
958 << std::setw(4) << 2.0*rnum <<
" π | "
959 << std::setprecision(3);
962 std::cout << std::setw(10) << std::scientific << err0 <<
" | "
963 << std::setprecision(2)
964 << std::setw(6) << std::fixed << rate_err <<
" | " ;
966 std::cout << std::setprecision(3)
967 << std::setw(10) << std::scientific << res0 <<
" | "
968 << std::setprecision(2)
969 << std::setw(6) << std::fixed << rate_res <<
" | "
970 << std::setw(6) << std::fixed << num_iter <<
" | "
972 std::cout.copyfmt(oldState);
977 const char * keys = (it == 0 &&
dim == 2) ?
"jRcml\n" :
nullptr;
980 "Numerical Electric field (real part)", 0, 0, 500, 500, keys);
982 "Numerical Magnetic field (real part)", 501, 0, 500, 500, keys);
1000 for (
int iel = 0; iel<pmesh.
GetNE(); iel++)
1002 if (residuals[iel] > theta * maxresidual)
1004 elements_to_refine.
Append(iel);
1014 for (
int i =0; i<trial_fes.
Size(); i++)
1016 trial_fes[i]->Update(
false);
1021 if (pml &&
dim == 2)
1023 delete epsomeg_detJ_Jt_J_inv_i_rot;
1024 delete epsomeg_detJ_Jt_J_inv_r_rot;
1025 delete negepsomeg_detJ_Jt_J_inv_r_rot;
1026 delete epsomeg_detJ_Jt_J_inv_i_rot_restr;
1027 delete epsomeg_detJ_Jt_J_inv_r_rot_restr;
1028 delete negepsomeg_detJ_Jt_J_inv_r_rot_restr;