79 const VectorType &scaling_vector,
81 MatrixType &augmented_matrix)
83# ifdef DEAL_II_WITH_TRILINOS
86 if constexpr (std::is_same_v<TrilinosWrappers::SparseMatrix, MatrixType>)
88 Assert((std::is_same_v<TrilinosWrappers::MPI::Vector, VectorType>),
89 ExcMessage(
"You must use Trilinos vectors, as you are using "
90 "Trilinos matrices."));
93 Epetra_CrsMatrix A_trilinos = A.trilinos_matrix();
94 Epetra_CrsMatrix Ct_trilinos = Ct.trilinos_matrix();
95 auto multi_vector = scaling_vector.trilinos_vector();
98 Assert((A_trilinos.NumGlobalRows() !=
99 Ct_trilinos.DomainMap().NumGlobalElements()),
100 ExcMessage(
"Number of columns in C must match dimension of A"));
104 Assert((multi_vector.NumVectors() == 1),
105 ExcMessage(
"The MultiVector must have exactly one column."));
110 const Epetra_Map &map =
111 static_cast<const Epetra_Map &
>(multi_vector.Map());
115 Epetra_CrsMatrix diag_matrix(Copy, map, 1);
116 for (
int i = 0; i < multi_vector.Map().NumMyElements(); ++i)
118 int global_row = multi_vector.Map().GID(i);
119 double val = multi_vector[0][i];
120 diag_matrix.InsertGlobalValues(global_row, 1, &val, &global_row);
122 diag_matrix.FillComplete();
125 Epetra_CrsMatrix *W =
126 new Epetra_CrsMatrix(Copy, Ct_trilinos.RowMap(), 0);
127 EpetraExt::MatrixMatrix::Multiply(
128 Ct_trilinos,
false, diag_matrix,
false, *W);
132 Epetra_CrsMatrix *CtT_W =
new Epetra_CrsMatrix(Copy, W->RangeMap(), 0);
133 EpetraExt::MatrixMatrix::Multiply(
134 *W,
false , Ct_trilinos,
true, *CtT_W);
138 Epetra_CrsMatrix *result =
139 new Epetra_CrsMatrix(Copy,
141 A_trilinos.MaxNumEntries());
142 EpetraExt::MatrixMatrix::Add(
143 A_trilinos,
false, 1.0, *CtT_W,
false, gamma, result);
144 result->FillComplete();
148 augmented_matrix.reinit(*result,
true );
159 AssertThrow(
false, ExcNotImplemented(
"Matrix type not supported!"));
165 "This function requires deal.II to be configured with Trilinos."));
171 (void)scaling_vector;
172 (void)velocity_constraints;
174 (void)augmented_matrix;
187 std::unique_ptr<Epetra_MultiVector> &ptr_distributed_modes,
188 const Epetra_RowMatrix &matrix,
189 const std::vector<VectorType> &modes)
191 static_assert((spacedim == 2 || spacedim == 3),
192 "This function only works for 2D and 3D.");
194# ifdef DEAL_II_WITH_TRILINOS
197 using size_type = TrilinosWrappers::PreconditionAMG::size_type;
198 const Epetra_Map &domain_map = matrix.OperatorDomainMap();
199 constexpr size_type modes_dimension = spacedim == 3 ? 6 : 3;
201 ptr_distributed_modes.reset(
202 new Epetra_MultiVector(domain_map, modes_dimension));
203 Assert(ptr_distributed_modes, ExcNotInitialized());
204 Epetra_MultiVector &distributed_modes = *ptr_distributed_modes;
208 Assert(global_size ==
static_cast<size_type
>(
210 ExcDimensionMismatch(
213 const size_type my_size = domain_map.NumMyElements();
217 [[maybe_unused]]
const size_type expected_mode_size = global_size;
218 for (size_type
d = 0;
d < modes_dimension; ++
d)
221 ExcDimensionMismatch(modes[
d].
size(), expected_mode_size));
222 for (size_type row = 0; row < my_size; ++row)
226 distributed_modes[
d][row] =
227 static_cast<double>(modes[
d][mode_index]);
231 parameter_list.set(
"null space: type",
"pre-computed");
232 parameter_list.set(
"null space: dimension", distributed_modes.NumVectors());
233 parameter_list.set(
"null space: vectors", distributed_modes.Values());
240 "This function requires deal.II to be configured with Trilinos."));