213int main(
int argc,
char *argv[])
219 const char *mesh_file =
"../../data/inline-quad.mesh";
224 bool static_cond =
false;
229 bool with_pml =
false;
230 bool visualization =
true;
231 bool paraview =
false;
234 args.
AddOption(&mesh_file,
"-m",
"--mesh",
235 "Mesh file to use.");
237 "Finite element order (polynomial degree)");
238 args.
AddOption(&rnum,
"-rnum",
"--number-of-wavelengths",
239 "Number of wavelengths");
241 "Permeability of free space (or 1/(spring constant)).");
243 "Permittivity of free space (or mass constant).");
244 args.
AddOption(&iprob,
"-prob",
"--problem",
"Problem case"
245 " 0: plane wave, 1: Fichera 'oven', "
246 " 2: Generic PML problem with point source given as a load "
247 " 3: Scattering of a plane wave, "
248 " 4: Point source given on the boundary");
249 args.
AddOption(&delta_order,
"-do",
"--delta-order",
250 "Order enrichment for DPG test space.");
251 args.
AddOption(&theta,
"-theta",
"--theta",
252 "Theta parameter for AMR");
253 args.
AddOption(&sr,
"-sref",
"--serial-ref",
254 "Number of parallel refinements.");
255 args.
AddOption(&pr,
"-pref",
"--parallel-ref",
256 "Number of parallel refinements.");
257 args.
AddOption(&static_cond,
"-sc",
"--static-condensation",
"-no-sc",
258 "--no-static-condensation",
"Enable static condensation.");
259 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
260 "--no-visualization",
261 "Enable or disable GLVis visualization.");
262 args.
AddOption(¶view,
"-paraview",
"--paraview",
"-no-paraview",
264 "Enable or disable ParaView visualization.");
275 if (iprob > 4) { iprob = 0; }
277 omega = 2.*M_PI*rnum;
285 mesh_file =
"meshes/fichera-waveguide.mesh";
287 rnum =
omega/(2.*M_PI);
296 mesh_file =
"meshes/scatter.mesh";
304 Mesh mesh(mesh_file, 1, 1);
306 MFEM_VERIFY(
dim > 1,
"Dimension = 1 is not supported in this example");
310 for (
int i = 0; i<sr; i++)
325 ParMesh pmesh(MPI_COMM_WORLD, mesh);
358 int test_order = order+delta_order;
379 trial_fes.
Append(hatE_fes);
380 trial_fes.
Append(hatH_fes);
394 rot_mat(0,0) = 0.; rot_mat(0,1) = 1.;
395 rot_mat(1,0) = -1.; rot_mat(1,1) = 0.;
422 epsomeg_cf = &epsomeg;
423 negepsomeg_cf = &negepsomeg;
424 eps2omeg2_cf = &eps2omeg2;
426 negmuomeg_cf = &negmuomeg;
427 mu2omeg2_cf = &mu2omeg2;
429 negepsrot_cf = &negepsrot;
456 abs_detJ_Jt_J_inv_2);
458 abs_detJ_Jt_J_inv_2);
465 epsomeg_detJ_Jt_J_inv_i,attrPML);
467 epsomeg_detJ_Jt_J_inv_r,attrPML);
469 negepsomeg_detJ_Jt_J_inv_r,attrPML);
473 negmuomeg_detJ_Jt_J_inv_i,attrPML);
475 negmuomeg_detJ_Jt_J_inv_r,attrPML);
477 mu2omeg2_detJ_Jt_J_inv_2,attrPML);
479 eps2omeg2_detJ_Jt_J_inv_2,attrPML);
491 epsomeg_detJ_Jt_J_inv_i, rot);
493 epsomeg_detJ_Jt_J_inv_r, rot);
495 negepsomeg_detJ_Jt_J_inv_r, rot);
497 *epsomeg_detJ_Jt_J_inv_i_rot, attrPML);
499 *epsomeg_detJ_Jt_J_inv_r_rot, attrPML);
501 *negepsomeg_detJ_Jt_J_inv_r_rot, attrPML);
509 nullptr,TrialSpace::E_space, TestSpace::F_space);
511 a->AddTrialIntegrator(
nullptr,
513 TrialSpace::E_space,TestSpace::G_space);
516 nullptr,TrialSpace::H_space, TestSpace::G_space);
519 TrialSpace::hatH_space, TestSpace::G_space);
523 TestSpace::G_space,TestSpace::G_space);
526 TestSpace::G_space,TestSpace::G_space);
533 TrialSpace::H_space,TestSpace::F_space);
536 TrialSpace::hatE_space, TestSpace::F_space);
541 TestSpace::F_space, TestSpace::F_space);
544 TestSpace::F_space,TestSpace::F_space);
547 TestSpace::F_space, TestSpace::F_space);
550 TestSpace::F_space, TestSpace::G_space);
553 TestSpace::F_space, TestSpace::G_space);
556 TestSpace::G_space, TestSpace::F_space);
559 TestSpace::G_space, TestSpace::F_space);
562 TestSpace::G_space, TestSpace::G_space);
568 TrialSpace::H_space, TestSpace::F_space);
571 TrialSpace::hatE_space, TestSpace::F_space);
575 TestSpace::F_space, TestSpace::F_space);
578 TestSpace::F_space, TestSpace::F_space);
581 TestSpace::F_space, TestSpace::F_space);
583 a->AddTestIntegrator(
nullptr,
585 TestSpace::F_space, TestSpace::G_space);
588 TestSpace::F_space, TestSpace::G_space);
591 TestSpace::G_space, TestSpace::F_space);
593 a->AddTestIntegrator(
nullptr,
596 TestSpace::G_space, TestSpace::F_space);
599 TestSpace::G_space, TestSpace::G_space);
606 a->AddTrialIntegrator(
608 epsomeg_detJ_Jt_J_inv_i_restr)),
610 negepsomeg_detJ_Jt_J_inv_r_restr)),
611 TrialSpace::E_space,TestSpace::G_space);
617 a->AddTrialIntegrator(
619 negmuomeg_detJ_Jt_J_inv_i_restr)),
621 muomeg_detJ_Jt_J_inv_r_restr)),
622 TrialSpace::H_space, TestSpace::F_space);
625 a->AddTestIntegrator(
627 TestSpace::F_space, TestSpace::F_space);
632 negmuomeg_detJ_Jt_J_inv_i_restr),
634 TestSpace::F_space,TestSpace::G_space);
638 epsomeg_detJ_Jt_J_inv_i_restr),
640 TestSpace::F_space,TestSpace::G_space);
644 negmuomeg_detJ_Jt_J_inv_i_restr),
646 TestSpace::G_space, TestSpace::F_space);
650 epsomeg_detJ_Jt_J_inv_i_restr),
652 TestSpace::G_space, TestSpace::F_space);
655 eps2omeg2_detJ_Jt_J_inv_2_restr),
nullptr,
656 TestSpace::G_space, TestSpace::G_space);
663 a->AddTrialIntegrator(
666 TrialSpace::H_space, TestSpace::F_space);
669 a->AddTestIntegrator(
new MassIntegrator(mu2omeg2_detJ_2_restr),
nullptr,
670 TestSpace::F_space, TestSpace::F_space);
673 a->AddTestIntegrator(
676 TestSpace::F_space, TestSpace::G_space);
680 *epsomeg_detJ_Jt_J_inv_i_rot_restr),
682 TestSpace::F_space, TestSpace::G_space);
687 TestSpace::G_space, TestSpace::F_space);
690 a->AddTestIntegrator(
692 *epsomeg_detJ_Jt_J_inv_i_rot_restr)),
694 *epsomeg_detJ_Jt_J_inv_r_rot_restr)),
695 TestSpace::G_space, TestSpace::F_space);
698 eps2omeg2_detJ_Jt_J_inv_2_restr),
nullptr,
699 TestSpace::G_space, TestSpace::G_space);
725 std::cout <<
"\n Ref |"
730 std::cout <<
" L2 Error |"
733 std::cout <<
" Residual |"
735 <<
" PCG it |" << endl;
736 std::cout << std::string((
exact_known) ? 82 : 60,
'-')
765 if (static_cond) {
a->EnableStaticCondensation(); }
766 for (
int it = 0; it<=pr; it++)
785 for (
int j = 0; j < ess_tdof_list.
Size(); j++)
819 a->FormLinearSystem(ess_tdof_list,x,Ah, X,B);
830 int skip = (static_cond) ? 0 : 2;
831 int k = (static_cond) ? 2 : 0;
832 for (
int i=0; i<num_blocks; i++)
834 tdof_offsets[i+1] = trial_fes[i+k]->GetTrueVSize();
835 tdof_offsets[num_blocks+i+1] = trial_fes[i+k]->GetTrueVSize();
840 for (
int i = 0; i<num_blocks; i++)
842 for (
int j = 0; j<num_blocks; j++)
844 blockA.
SetBlock(i,j,&BlockA_r->GetBlock(i,j));
846 blockA.
SetBlock(i+num_blocks,j+num_blocks,&BlockA_r->GetBlock(i,j));
857 BlockA_r->GetBlock(0,0));
861 BlockA_r->GetBlock(1,1));
885 dynamic_cast<HypreAMS*
>(solver_hatH)->SetPrintLevel(0);
901 for (
int i = 0; i<num_blocks; i++)
908 a->RecoverFEMSolution(X,x);
910 Vector & residuals =
a->ComputeResidual(x);
914 real_t globalresidual = residual * residual;
916 MPI_MAX, MPI_COMM_WORLD);
917 MPI_Allreduce(MPI_IN_PLACE, &globalresidual, 1,
920 globalresidual = sqrt(globalresidual);
925 H_r.
MakeRef(H_fes,x, offsets[1]);
929 for (
int i = 0; i<trial_fes.
Size(); i++)
931 dofs += trial_fes[i]->GlobalTrueVSize();
947 L2Error = sqrt( E_err_r*E_err_r + E_err_i*E_err_i
948 + H_err_r*H_err_r + H_err_i*H_err_i );
949 rate_err = (it) ?
dim*log(err0/L2Error)/log((
real_t)dof0/dofs) : 0.0;
953 real_t rate_res = (it) ?
dim*log(res0/globalresidual)/log((
956 res0 = globalresidual;
961 std::ios oldState(
nullptr);
962 oldState.copyfmt(std::cout);
963 std::cout << std::right << std::setw(5) << it <<
" | "
964 << std::setw(10) << dof0 <<
" | "
965 << std::setprecision(1) << std::fixed
966 << std::setw(4) << 2.0*rnum <<
" π | "
967 << std::setprecision(3);
970 std::cout << std::setw(10) << std::scientific << err0 <<
" | "
971 << std::setprecision(2)
972 << std::setw(6) << std::fixed << rate_err <<
" | " ;
974 std::cout << std::setprecision(3)
975 << std::setw(10) << std::scientific << res0 <<
" | "
976 << std::setprecision(2)
977 << std::setw(6) << std::fixed << rate_res <<
" | "
978 << std::setw(6) << std::fixed << num_iter <<
" | "
980 std::cout.copyfmt(oldState);
985 const char * keys = (it == 0 &&
dim == 2) ?
"jRcml\n" :
nullptr;
989 "Numerical Electric field (real part)", 0, 0, 500, 500, keys);
991 "Numerical Magnetic field (real part)", 501, 0, 500, 500, keys);
1008 elements_to_refine.
SetSize(0);
1009 for (
int iel = 0; iel<pmesh.
GetNE(); iel++)
1011 if (residuals[iel] > theta * maxresidual)
1013 elements_to_refine.
Append(iel);
1023 for (
int i =0; i<trial_fes.
Size(); i++)
1025 trial_fes[i]->Update(
false);
1030 if (pml &&
dim == 2)
1032 delete epsomeg_detJ_Jt_J_inv_i_rot;
1033 delete epsomeg_detJ_Jt_J_inv_r_rot;
1034 delete negepsomeg_detJ_Jt_J_inv_r_rot;
1035 delete epsomeg_detJ_Jt_J_inv_i_rot_restr;
1036 delete epsomeg_detJ_Jt_J_inv_r_rot_restr;
1037 delete negepsomeg_detJ_Jt_J_inv_r_rot_restr;