15 #include "libmesh/nonlinear_solver.h" 16 #include "libmesh/petsc_matrix.h" 17 #include "libmesh/petsc_vector.h" 18 #include "libmesh/dof_map.h" 19 #include "libmesh/nonlinear_implicit_system.h" 30 "pressure_mass_matrix",
"The matrix tag name corresponding to the pressure mass matrix.");
32 "velocity_mass_matrix",
"The matrix tag name corresponding to the velocity mass matrix.");
33 params.
addParam<std::vector<TagName>>(
34 "augmented_lagrange_matrices",
36 "Matrices corresponding to finite element weak forms used to create augmented Lagrange " 37 "perturbations. Example weak forms include volumetric grad-div and face jumps for " 38 "discontinuous Galerkin discretizations. This is a vector because, for example, a user may " 39 "pass one matrix that corresponds just to grad-div, another corresponding to face jumps, and " 40 "yet another corresponding to the sum of the two.");
41 params.
addRequiredParam<NonlinearVariableName>(
"u",
"The interior x-velocity variable");
42 params.
addRequiredParam<NonlinearVariableName>(
"v",
"The interior y-velocity variable");
45 params.
addParam<
bool>(
"print",
true,
"Whether to print the matrices");
51 _pressure_mass_matrix(getParam<TagName>(
"pressure_mass_matrix")),
52 _velocity_mass_matrix(getParam<TagName>(
"velocity_mass_matrix")),
53 _augmented_lagrange_matrices(getParam<
std::vector<TagName>>(
"augmented_lagrange_matrices"))
56 mooseError(
"This problem can only be used in serial");
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));
183 _console << std::endl <<
"Printing the '" << inner_matrix_name <<
"' matrix" << std::endl;
186 write_matrix(
triple_product.mat(), inner_matrix_name + std::string(
".mat"));
188 LibmeshPetscCall(MatDestroy(&triple_product_mat));
189 LibmeshPetscCall(MatDestroy(&I));
190 LibmeshPetscCall(MatDestroy(&M));
191 LibmeshPetscCall(MatDestroy(&Minv));
195 system_size_pressure_mass_matrix.create_submatrix(
196 p_mass_mat, pressure_indices, pressure_indices);
197 system_size_velocity_mass_matrix.create_submatrix(vel_mass_mat, vel_indices, vel_indices);
198 system_matrix->create_submatrix(vel_p_mat, vel_indices, pressure_indices);
199 system_matrix->create_submatrix(p_vel_mat, pressure_indices, vel_indices);
201 compute_triple_product_matrix(
202 vel_p_mat, p_mass_mat, p_vel_mat, outer_matrix_name +
"_grad_div");
203 compute_triple_product_matrix(
204 p_vel_mat, vel_mass_mat, vel_p_mat, outer_matrix_name +
"_div_grad");
208 do_vel_p(p_vol_indices,
"vel_p");
210 do_vel_p(pb_indices,
"vel_pb");
211 do_vel_p(p_indices,
"vel_all_p");
217 const auto jump_matrix_tag_id =
getMatrixTagID(augmented_lagrange_name);
218 auto & system_size_jump_matrix = nl.getMatrix(jump_matrix_tag_id);
219 system_size_jump_matrix.create_submatrix(jump_mat, vel_indices, vel_indices);
223 <<
"Printing the jump matrix '" << augmented_lagrange_name <<
"'" << std::endl;
226 write_matrix(jump_mat.mat(), augmented_lagrange_name + std::string(
".mat"));
registerMooseObject("NavierStokesTestApp", PrintMatricesNSProblem)
unsigned int number() const
virtual void onTimestepEnd() override
A problem that solves and prints matrices used when solving the incompressible Navier-Stokes equation...
virtual void onTimestepEnd() override
const Parallel::Communicator & _communicator
static InputParameters validParams()
PrintMatricesNSProblem(const InputParameters ¶meters)
const TagName & _pressure_mass_matrix
The tag name of the pressure mass matrix.
bool isParamValid(const std::string &name) const
processor_id_type size() const
const TagName & _velocity_mass_matrix
The tag name of the velocity mass matrix.
T triple_product(const TypeVector< T > &a, const TypeVector< T > &b, const TypeVector< T > &c)
static InputParameters validParams()
const std::vector< TagName > & _augmented_lagrange_matrices
The tag name of the jump matrix.
virtual TagID getMatrixTagID(const TagName &tag_name) const
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
virtual void insert(libMesh::NumericVector< libMesh::Number > &vector)=0
static const std::string pressure
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
void mooseError(Args &&... args) const
const ConsoleStream _console