7 const mfem::SparseMatrix& matrix,
8 const mfem::Array<int>& trialEssentialDofs,
9 const mfem::Array<int>& testEssentialDofs
11 int M_orig = matrix.Height();
12 int N_orig = matrix.Width();
16 mfem::Array<bool> row_is_eliminated(M_orig);
17 row_is_eliminated =
false;
18 for (
int i = 0; i < testEssentialDofs.Size(); ++i) {
19 int r_idx = testEssentialDofs[i];
20 if (r_idx >= 0 && r_idx < M_orig) {
21 row_is_eliminated[r_idx] =
true;
25 mfem::Array<bool> col_is_eliminated(N_orig);
26 col_is_eliminated =
false;
27 for (
int i = 0; i < trialEssentialDofs.Size(); ++i) {
28 int c_idx = trialEssentialDofs[i];
29 if (c_idx >= 0 && c_idx < N_orig) {
30 col_is_eliminated[c_idx] =
true;
36 mfem::Array<int> old_row_to_new_row(M_orig);
38 for (
int i = 0; i < M_orig; ++i) {
39 if (row_is_eliminated[i]) {
40 old_row_to_new_row[i] = -1;
42 old_row_to_new_row[i] = num_new_rows++;
46 mfem::Array<int> old_col_to_new_col(N_orig);
48 for (
int i = 0; i < N_orig; ++i) {
49 if (col_is_eliminated[i]) {
50 old_col_to_new_col[i] = -1;
52 old_col_to_new_col[i] = num_new_cols++;
58 mfem::SparseMatrix A_new(num_new_rows, num_new_cols);
63 const int* I_orig = matrix.GetI();
64 const int* J_orig = matrix.GetJ();
65 const double* V_orig = matrix.GetData();
67 for (
int r_orig = 0; r_orig < M_orig; ++r_orig) {
69 if (row_is_eliminated[r_orig]) {
74 int r_new = old_row_to_new_row[r_orig];
79 for (
int k = I_orig[r_orig]; k < I_orig[r_orig + 1]; ++k) {
80 int c_orig = J_orig[k];
81 double val = V_orig[k];
83 if (col_is_eliminated[c_orig]) {
87 int c_new = old_col_to_new_col[c_orig];
89 A_new.Add(r_new, c_new, val);
106 mfem::Mesh*
mesh = phi_gf.FESpace()->GetMesh();
107 const int dim =
mesh->Dimension();
109 const int order = phi_gf.FESpace()->GetOrder(0);
110 mfem::Vector curl_mag_vec;
112 for (
int ne = 0; ne <
mesh->GetNE(); ++ne) {
113 if (
mesh->GetElementType(ne) != mfem::Element::TRIANGLE &&
114 mesh->GetElementType(ne) != mfem::Element::QUADRILATERAL &&
115 mesh->GetElementType(ne) != mfem::Element::TETRAHEDRON &&
116 mesh->GetElementType(ne) != mfem::Element::HEXAHEDRON) {
117 throw std::invalid_argument(
"Mesh element type not supported for curl computation.");
119 mfem::IsoparametricTransformation T;
120 mesh->GetElementTransformation(ne, &T);
121 phi_gf.GetCurl(T, curl_mag_vec);
123 mfem::L2_FECollection fac(order, dim);
124 mfem::FiniteElementSpace fs(
mesh, &fac);
125 mfem::GridFunction curl_gf(&fs);