64 const bool print = getParam<bool>(
"print");
70 auto & dof_map = nl.dofMap();
73 const auto & u_var = nl.getVariable(0, getParam<NonlinearVariableName>(
"u"));
74 const auto & v_var = nl.getVariable(0, getParam<NonlinearVariableName>(
"v"));
78 p_var = &nl.getVariable(0, getParam<NonlinearVariableName>(
NS::pressure));
80 pb_var = &nl.getVariable(0, getParam<NonlinearVariableName>(
NS::pressure +
"_bar"));
83 std::vector<dof_id_type> u_indices, v_indices, p_vol_indices, pb_indices, vel_indices, p_indices;
84 dof_map.local_variable_indices(u_indices, lm_mesh, u_var.number());
85 dof_map.local_variable_indices(v_indices, lm_mesh, v_var.number());
87 dof_map.local_variable_indices(p_vol_indices, lm_mesh, p_var->
number());
89 dof_map.local_variable_indices(pb_indices, lm_mesh, pb_var->
number());
90 vel_indices = u_indices;
91 vel_indices.
insert(vel_indices.end(), v_indices.begin(), v_indices.end());
92 p_indices = p_vol_indices;
94 p_indices.insert(p_indices.end(), pb_indices.begin(), pb_indices.end());
100 auto & system_size_pressure_mass_matrix = nl.getMatrix(pressure_mass_matrix_tag_id);
102 auto & system_size_velocity_mass_matrix = nl.getMatrix(velocity_mass_matrix_tag_id);
103 auto *
const system_matrix =
104 dynamic_cast<PetscMatrix<Number> *
>(&nl.nonlinearSolver()->system().get_system_matrix());
105 mooseAssert(system_matrix,
"Must be a PETSc matrix");
107 auto write_matrix = [
this](Mat write_mat,
const std::string & mat_name)
109 PetscViewer matviewer;
112 PetscViewerBinaryOpen(
_communicator.
get(), mat_name.c_str(), FILE_MODE_WRITE, &matviewer));
122 &system_size_pressure_mass_matrix,
123 &system_size_velocity_mass_matrix,
128 &vel_mass_mat](
const auto & pressure_indices,
const std::string & outer_matrix_name)
131 auto compute_triple_product_matrix =
132 [
this, print, write_matrix](PetscMatrix<Number> & lhs,
133 PetscMatrix<Number> & mass_matrix,
134 PetscMatrix<Number> & rhs,
135 const std::string & inner_matrix_name)
141 mass_matrix.local_m(),
142 mass_matrix.local_n(),
147 const PetscScalar one = 1.0;
148 for (
const auto i : make_range(mass_matrix.row_start(), mass_matrix.row_stop()))
150 const auto petsc_i = cast_int<PetscInt>(i);
151 LibmeshPetscCall(MatSetValues(I, 1, &petsc_i, 1, &petsc_i, &one, INSERT_VALUES));
153 LibmeshPetscCall(MatAssemblyBegin(I, MAT_FINAL_ASSEMBLY));
154 LibmeshPetscCall(MatAssemblyEnd(I, MAT_FINAL_ASSEMBLY));
158 mass_matrix.local_m(),
159 mass_matrix.local_n(),
166 LibmeshPetscCall(MatConvert(mass_matrix.mat(), MATDENSE, MAT_INITIAL_MATRIX, &
M));
167 LibmeshPetscCall(MatLUFactor(
M,
nullptr,
nullptr,
nullptr));
170 LibmeshPetscCall(MatMatSolve(
M, I, Minv));
176 Mat triple_product_mat;
177 LibmeshPetscCall(MatMatMatMult(
178 lhs.mat(), Minv, rhs.mat(), MAT_INITIAL_MATRIX, PETSC_DEFAULT, &triple_product_mat));
179 LibmeshPetscCall(MatScale(triple_product_mat, -1));
181 PetscMatrix<Number> triple_product(triple_product_mat,
_communicator);
184 _console << std::endl <<
"Printing the '" << inner_matrix_name <<
"' matrix" << std::endl;
185 triple_product.print();
187 write_matrix(triple_product.mat(), inner_matrix_name + std::string(
".mat"));
189 LibmeshPetscCall(MatDestroy(&triple_product_mat));
190 LibmeshPetscCall(MatDestroy(&I));
191 LibmeshPetscCall(MatDestroy(&
M));
192 LibmeshPetscCall(MatDestroy(&Minv));
196 system_size_pressure_mass_matrix.create_submatrix(
197 p_mass_mat, pressure_indices, pressure_indices);
198 system_size_velocity_mass_matrix.create_submatrix(vel_mass_mat, vel_indices, vel_indices);
199 system_matrix->create_submatrix(vel_p_mat, vel_indices, pressure_indices);
200 system_matrix->create_submatrix(p_vel_mat, pressure_indices, vel_indices);
202 compute_triple_product_matrix(
203 vel_p_mat, p_mass_mat, p_vel_mat, outer_matrix_name +
"_grad_div");
204 compute_triple_product_matrix(
205 p_vel_mat, vel_mass_mat, vel_p_mat, outer_matrix_name +
"_div_grad");
209 do_vel_p(p_vol_indices,
"vel_p");
211 do_vel_p(pb_indices,
"vel_pb");
212 do_vel_p(p_indices,
"vel_all_p");
218 const auto jump_matrix_tag_id =
getMatrixTagID(augmented_lagrange_name);
219 auto & system_size_jump_matrix = nl.getMatrix(jump_matrix_tag_id);
220 system_size_jump_matrix.create_submatrix(jump_mat, vel_indices, vel_indices);
224 <<
"Printing the jump matrix '" << augmented_lagrange_name <<
"'" << std::endl;
227 write_matrix(jump_mat.mat(), augmented_lagrange_name + std::string(
".mat"));