deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
trilinos_tpetra_sparsity_pattern.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2024 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#include <deal.II/base/config.h>
14
15#ifdef DEAL_II_TRILINOS_WITH_TPETRA
16
17# include <deal.II/base/mpi.h>
19
24
25# include <Teuchos_FancyOStream.hpp>
26
27# include <limits>
28
29
30#endif // DEAL_II_TRILINOS_WITH_TPETRA
31
33
34#ifdef DEAL_II_TRILINOS_WITH_TPETRA
35
36namespace LinearAlgebra
37{
38
39 namespace TpetraWrappers
40 {
42 {
43 template <typename MemorySpace>
44 void
46 {
47 // if we are asked to visit the past-the-end line, then simply
48 // release all our caches and go on with life
49 if (static_cast<std::size_t>(this->a_row) == sparsity_pattern->n_rows())
50 {
51 colnum_cache.reset();
52 return;
53 }
54
55 // otherwise first flush Trilinos caches if necessary
56 if (!sparsity_pattern->is_compressed())
57 sparsity_pattern->compress();
58
59 colnum_cache =
60 std::make_shared<std::vector<::types::signed_global_dof_index>>(
61 sparsity_pattern->row_length(this->a_row));
62
63 if (colnum_cache->size() > 0)
64 {
65 // get a representation of the present row
66 std::size_t ncols;
68 MemorySpace>::nonconst_global_inds_host_view_type
69 column_indices_view(colnum_cache->data(), colnum_cache->size());
70
71 sparsity_pattern->graph->getGlobalRowCopy(this->a_row,
72 column_indices_view,
73 ncols);
74 AssertThrow(ncols == colnum_cache->size(), ExcInternalError());
75 }
76 }
77 } // namespace SparsityPatternIterators
78
79
80 // The constructor is actually the only point where we have to check whether
81 // we build a serial or a parallel Trilinos matrix. Actually, it does not
82 // even matter how many threads there are, but only if we use an MPI
83 // compiler or a standard compiler. So, even one thread on a configuration
84 // with MPI will still get a parallel interface.
85 template <typename MemorySpace>
99
100
101
102 template <typename MemorySpace>
104 const size_type m,
105 const size_type n,
106 const size_type n_entries_per_row)
107 {
108 reinit(m, n, n_entries_per_row);
109 }
110
111
112
113 template <typename MemorySpace>
115 const size_type m,
116 const size_type n,
117 const std::vector<size_type> &n_entries_per_row)
118 {
119 reinit(m, n, n_entries_per_row);
120 }
121
122
123
124 template <typename MemorySpace>
126 SparsityPattern<MemorySpace> &&other) noexcept
127 : SparsityPatternBase(std::move(other))
128 , column_space_map(std::move(other.column_space_map))
129 , graph(std::move(other.graph))
130 , nonlocal_graph(std::move(other.nonlocal_graph))
131 {}
132
133
134
135 // Copy function only works if the sparsity pattern is empty.
136 template <typename MemorySpace>
138 const SparsityPattern<MemorySpace> &input_sparsity)
139 : SparsityPatternBase(input_sparsity)
140 , column_space_map(Utilities::Trilinos::internal::make_rcp<
141 TpetraTypes::MapType<MemorySpace>>(
142 0,
143 0,
144 Utilities::Trilinos::tpetra_comm_self()))
145 , graph(Utilities::Trilinos::internal::make_rcp<
146 TpetraTypes::GraphType<MemorySpace>>(column_space_map,
147 column_space_map,
148 0))
149 {
150 (void)input_sparsity;
151 Assert(input_sparsity.n_rows() == 0,
153 "Copy constructor only works for empty sparsity patterns."));
154 }
155
156
157
158 template <typename MemorySpace>
160 const IndexSet &parallel_partitioning,
161 const MPI_Comm communicator,
162 const size_type n_entries_per_row)
163 {
164 reinit(parallel_partitioning,
165 parallel_partitioning,
166 communicator,
167 n_entries_per_row);
168 }
169
171
172 template <typename MemorySpace>
174 const IndexSet &parallel_partitioning,
175 const MPI_Comm communicator,
176 const std::vector<size_type> &n_entries_per_row)
177 {
178 reinit(parallel_partitioning,
179 parallel_partitioning,
180 communicator,
181 n_entries_per_row);
182 }
183
184
185
186 template <typename MemorySpace>
188 const IndexSet &row_parallel_partitioning,
189 const IndexSet &col_parallel_partitioning,
190 const MPI_Comm communicator,
191 const size_type n_entries_per_row)
192 {
193 reinit(row_parallel_partitioning,
194 col_parallel_partitioning,
195 communicator,
196 n_entries_per_row);
197 }
198
199
200
201 template <typename MemorySpace>
203 const IndexSet &row_parallel_partitioning,
204 const IndexSet &col_parallel_partitioning,
205 const MPI_Comm communicator,
206 const std::vector<size_type> &n_entries_per_row)
207 {
208 reinit(row_parallel_partitioning,
209 col_parallel_partitioning,
210 communicator,
211 n_entries_per_row);
212 }
213
214
215
216 template <typename MemorySpace>
218 const IndexSet &row_parallel_partitioning,
219 const IndexSet &col_parallel_partitioning,
220 const IndexSet &writable_rows,
221 const MPI_Comm communicator,
222 const size_type n_max_entries_per_row)
223 {
224 reinit(row_parallel_partitioning,
225 col_parallel_partitioning,
226 writable_rows,
227 communicator,
228 n_max_entries_per_row);
229 }
230
231
232
233 template <typename MemorySpace>
234 void
236 const size_type n,
237 const size_type n_entries_per_row)
238 {
239 reinit(complete_index_set(m),
241 MPI_COMM_SELF,
242 n_entries_per_row);
243 }
244
245
246
247 template <typename MemorySpace>
248 void
250 const size_type m,
251 const size_type n,
252 const std::vector<size_type> &n_entries_per_row)
253 {
254 reinit(complete_index_set(m),
256 MPI_COMM_SELF,
257 n_entries_per_row);
258 }
259
260
261
262 namespace SparsityPatternImpl
263 {
264 template <typename MemorySpace>
266
267 template <typename MemorySpace>
268 void
270 const Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &row_map,
271 const Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &col_map,
272 const size_type<MemorySpace> n_entries_per_row,
273 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &column_space_map,
274 Teuchos::RCP<TpetraTypes::GraphType<MemorySpace>> &graph,
275 Teuchos::RCP<TpetraTypes::GraphType<MemorySpace>> &nonlocal_graph)
276 {
277 Assert(row_map->isOneToOne(),
278 ExcMessage("Row map must be 1-to-1, i.e., no overlap between "
279 "the maps of different processors."));
280 Assert(col_map->isOneToOne(),
281 ExcMessage("Column map must be 1-to-1, i.e., no overlap between "
282 "the maps of different processors."));
283
284 nonlocal_graph.reset();
285 graph.reset();
286 column_space_map = col_map;
287
288 // We only specify the row map and let the sparsity pattern entries
289 // decide about the column map (which says which columns are present
290 // locally, not to be confused with the col_map that tells how the
291 // domain dofs of the matrix will be distributed). If we use a recent
292 // Trilinos version, we can also require building a non-local graph
293 // which gives us thread-safe initialization.
295 TpetraTypes::GraphType<MemorySpace>>(row_map, n_entries_per_row);
296 }
297
298
299
300 template <typename MemorySpace>
301 void
303 const Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &row_map,
304 const Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &col_map,
305 const std::vector<size_type<MemorySpace>> &n_entries_per_row,
306 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &column_space_map,
307 Teuchos::RCP<TpetraTypes::GraphType<MemorySpace>> &graph,
308 Teuchos::RCP<TpetraTypes::GraphType<MemorySpace>> &nonlocal_graph)
309 {
310 Assert(row_map->isOneToOne(),
311 ExcMessage("Row map must be 1-to-1, i.e., no overlap between "
312 "the maps of different processors."));
313 Assert(col_map->isOneToOne(),
314 ExcMessage("Column map must be 1-to-1, i.e., no overlap between "
315 "the maps of different processors."));
316
317 // release memory before reallocation
318 nonlocal_graph.reset();
319 graph.reset();
320 AssertDimension(n_entries_per_row.size(),
321 row_map->getGlobalNumElements());
322
323 column_space_map = col_map;
324
325 // Translate the vector of row lengths into one that only stores
326 // those entries that related to the locally stored rows of the matrix:
327 Kokkos::DualView<size_t *, typename MemorySpace::kokkos_space>
328 local_entries_per_row("local_entries_per_row",
329 row_map->getMaxGlobalIndex() -
330 row_map->getMinGlobalIndex());
331
332 auto local_entries_per_row_host =
333 local_entries_per_row
334 .template view<Kokkos::DefaultHostExecutionSpace>();
336 std::uint64_t total_size = 0;
337 for (unsigned int i = 0; i < local_entries_per_row.extent(0); ++i)
338 {
339 local_entries_per_row_host(i) =
340 n_entries_per_row[row_map->getMinGlobalIndex() + i];
341 total_size += local_entries_per_row_host[i];
342 }
343 local_entries_per_row
344 .template modify<Kokkos::DefaultHostExecutionSpace>();
345 local_entries_per_row
346 .template sync<typename MemorySpace::kokkos_space>();
347
349 total_size < static_cast<std::uint64_t>(
350 std::numeric_limits<
353 "You are requesting to store more elements than global ordinal type allows."));
354
356 TpetraTypes::GraphType<MemorySpace>>(row_map, local_entries_per_row);
358
359
360
361 template <typename SparsityPatternType, typename MemorySpace>
362 void
364 const Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &row_map,
365 const Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &col_map,
366 const SparsityPatternType &sp,
367 [[maybe_unused]] const bool exchange_data,
368 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &column_space_map,
369 Teuchos::RCP<TpetraTypes::GraphType<MemorySpace>> &graph,
370 Teuchos::RCP<TpetraTypes::GraphType<MemorySpace>> &nonlocal_graph)
371 {
372 nonlocal_graph.reset();
373 graph.reset();
374
375 AssertDimension(sp.n_rows(), row_map->getGlobalNumElements());
376 AssertDimension(sp.n_cols(), col_map->getGlobalNumElements());
377
380
381 Assert(row_map->isContiguous() == true,
383 "This function only works if the row map is contiguous."));
384
385 const size_type<MemorySpace> first_row = row_map->getMinGlobalIndex(),
386 last_row =
387 row_map->getMaxGlobalIndex() + 1;
389 Teuchos::Array<size_t> n_entries_per_row(
390 row_map->getLocalNumElements());
391
392 if (row_map->getLocalNumElements() > 0)
393 {
394 for (size_type<MemorySpace> row = first_row; row < last_row; ++row)
395 n_entries_per_row[row - first_row] = sp.row_length(row);
396 }
399 std::accumulate(n_entries_per_row.begin(),
400 n_entries_per_row.end(),
401 std::uint64_t(0)) <
402 static_cast<std::uint64_t>(std::numeric_limits<int>::max()),
404 "The TrilinosWrappers use Tpetra internally, and "
405 "Trilinos/Tpetra was compiled with 'local ordinate = int'. "
406 "Therefore, 'signed int' is used to represent local indices, "
407 "and only 2,147,483,647 nonzero matrix entries can be stored "
408 "on a single process, but you are requesting more than "
409 "that. Either use more MPI processes or recompile Trilinos "
410 "with 'local ordinate = long long' "));
411
413 TpetraTypes::GraphType<MemorySpace>>(row_map, n_entries_per_row);
414
415 // We can't check for equality of sp.n_cols() and
416 // graph->getGlobalNumCols() here since we don't necessarily have a
417 // column map at this point.
418 AssertDimension(sp.n_rows(), graph->getGlobalNumRows());
420 std::vector<TrilinosWrappers::types::int_type> row_indices;
421
422 if (row_map->getLocalNumElements() > 0)
423 {
424 for (size_type<MemorySpace> row = first_row; row < last_row; ++row)
425 {
426 const TrilinosWrappers::types::int_type row_length =
427 sp.row_length(row);
428 if (row_length == 0)
429 continue;
430
431 row_indices.resize(row_length, -1);
433 typename SparsityPatternType::iterator p = sp.begin(row);
434 // avoid incrementing p over the end of the current row
435 // because it is slow for DynamicSparsityPattern in parallel
436 for (int col = 0; col < row_length;)
437 {
438 row_indices[col++] = p->column();
439 if (col < row_length)
440 ++p;
441 }
442 }
443 graph->insertGlobalIndices(row, row_length, row_indices.data());
444 }
445 }
447 graph->globalAssemble();
448 }
449 } // namespace SparsityPatternImpl
450
451
452 template <typename MemorySpace>
453 void
454 SparsityPattern<MemorySpace>::reinit(const IndexSet &parallel_partitioning,
455 const MPI_Comm communicator,
456 const size_type n_entries_per_row)
457 {
458 SparsityPatternBase::resize(parallel_partitioning.size(),
459 parallel_partitioning.size());
460 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> map =
461 parallel_partitioning
462 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
463 communicator, false);
464 SparsityPatternImpl::reinit_sp<MemorySpace>(
465 map, map, n_entries_per_row, column_space_map, graph, nonlocal_graph);
466 }
467
468
469
470 template <typename MemorySpace>
471 void
473 const IndexSet &parallel_partitioning,
474 const MPI_Comm communicator,
475 const std::vector<size_type> &n_entries_per_row)
476 {
477 SparsityPatternBase::resize(parallel_partitioning.size(),
478 parallel_partitioning.size());
479 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> map =
480 parallel_partitioning
481 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
482 communicator, false);
483 SparsityPatternImpl::reinit_sp<MemorySpace>(
484 map, map, n_entries_per_row, column_space_map, graph, nonlocal_graph);
485 }
486
487
488
489 template <typename MemorySpace>
490 void
492 const IndexSet &row_parallel_partitioning,
493 const IndexSet &col_parallel_partitioning,
494 const MPI_Comm communicator,
495 const size_type n_entries_per_row)
496 {
497 SparsityPatternBase::resize(row_parallel_partitioning.size(),
498 col_parallel_partitioning.size());
499 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> row_map =
500 row_parallel_partitioning
501 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
502 communicator, false);
503 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> col_map =
504 col_parallel_partitioning
505 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
506 communicator, false);
507 SparsityPatternImpl::reinit_sp<MemorySpace>(row_map,
508 col_map,
509 n_entries_per_row,
510 column_space_map,
511 graph,
512 nonlocal_graph);
513 }
514
515
516
517 template <typename MemorySpace>
518 void
520 const IndexSet &row_parallel_partitioning,
521 const IndexSet &col_parallel_partitioning,
522 const MPI_Comm communicator,
523 const std::vector<size_type> &n_entries_per_row)
524 {
525 SparsityPatternBase::resize(row_parallel_partitioning.size(),
526 col_parallel_partitioning.size());
527 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> row_map =
528 row_parallel_partitioning
529 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
530 communicator, false);
531 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> col_map =
532 col_parallel_partitioning
533 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
534 communicator, false);
535 SparsityPatternImpl::reinit_sp<MemorySpace>(row_map,
536 col_map,
537 n_entries_per_row,
538 column_space_map,
539 graph,
540 nonlocal_graph);
541 }
542
543
544
545 template <typename MemorySpace>
546 void
548 const IndexSet &row_parallel_partitioning,
549 const IndexSet &col_parallel_partitioning,
550 const IndexSet &writable_rows,
551 const MPI_Comm communicator,
552 const size_type n_entries_per_row)
553 {
554 SparsityPatternBase::resize(row_parallel_partitioning.size(),
555 col_parallel_partitioning.size());
556 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> row_map =
557 row_parallel_partitioning
558 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
559 communicator, false);
560 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> col_map =
561 col_parallel_partitioning
562 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
563 communicator, false);
564 SparsityPatternImpl::reinit_sp<MemorySpace>(row_map,
565 col_map,
566 n_entries_per_row,
567 column_space_map,
568 graph,
569 nonlocal_graph);
570
571 IndexSet nonlocal_partitioner = writable_rows;
572 AssertDimension(nonlocal_partitioner.size(),
573 row_parallel_partitioning.size());
574 if constexpr (running_in_debug_mode())
575 {
576 {
577 IndexSet tmp = writable_rows & row_parallel_partitioning;
578 Assert(tmp == row_parallel_partitioning,
580 "The set of writable rows passed to this method does not "
581 "contain the locally owned rows, which is not allowed."));
582 }
583 }
584 nonlocal_partitioner.subtract_set(row_parallel_partitioning);
585 if (Utilities::MPI::n_mpi_processes(communicator) > 1)
586 {
587 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> nonlocal_map =
588 nonlocal_partitioner
589 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
590 communicator, true);
592 TpetraTypes::GraphType<MemorySpace>>(nonlocal_map,
593 n_entries_per_row);
594 }
595 else
596 Assert(nonlocal_partitioner.n_elements() == 0, ExcInternalError());
597 }
598
599
601 template <typename MemorySpace>
602 template <typename SparsityPatternType>
603 void
605 const IndexSet &row_parallel_partitioning,
606 const IndexSet &col_parallel_partitioning,
607 const SparsityPatternType &nontrilinos_sparsity_pattern,
608 const MPI_Comm communicator,
609 const bool exchange_data)
610 {
611 SparsityPatternBase::resize(row_parallel_partitioning.size(),
612 col_parallel_partitioning.size());
613 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> row_map =
614 row_parallel_partitioning
615 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
616 communicator, false);
617 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> col_map =
618 col_parallel_partitioning
619 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
620 communicator, false);
621 SparsityPatternImpl::reinit_sp<SparsityPatternType, MemorySpace>(
622 row_map,
623 col_map,
624 nontrilinos_sparsity_pattern,
625 exchange_data,
626 column_space_map,
627 graph,
628 nonlocal_graph);
629 }
630
631
632
633 template <typename MemorySpace>
634 template <typename SparsityPatternType>
635 void
637 const IndexSet &parallel_partitioning,
638 const SparsityPatternType &nontrilinos_sparsity_pattern,
639 const MPI_Comm communicator,
640 const bool exchange_data)
641 {
642 AssertDimension(nontrilinos_sparsity_pattern.n_rows(),
643 parallel_partitioning.size());
644 AssertDimension(nontrilinos_sparsity_pattern.n_cols(),
645 parallel_partitioning.size());
646 SparsityPatternBase::resize(parallel_partitioning.size(),
647 parallel_partitioning.size());
648 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> map =
649 parallel_partitioning
650 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
651 communicator, false);
652 SparsityPatternImpl::reinit_sp<SparsityPatternType, MemorySpace>(
653 map,
654 map,
655 nontrilinos_sparsity_pattern,
656 exchange_data,
657 column_space_map,
658 graph,
659 nonlocal_graph);
660 }
661
662
663
664 template <typename MemorySpace>
672
673
674
675 template <typename MemorySpace>
676 void
679 {
685
686 if (sp.nonlocal_graph.get() != nullptr)
689 else
690 nonlocal_graph.reset();
691 }
692
693
694
695 template <typename MemorySpace>
696 template <typename SparsityPatternType>
697 void
698 SparsityPattern<MemorySpace>::copy_from(const SparsityPatternType &sp)
699 {
700 SparsityPatternBase::resize(sp.n_rows(), sp.n_cols());
701 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> rows =
705 0,
707 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> columns =
711 0,
713
714 SparsityPatternImpl::reinit_sp<SparsityPatternType, MemorySpace>(
715 rows, columns, sp, false, column_space_map, graph, nonlocal_graph);
716 }
717
718
719
720 template <typename MemorySpace>
721 void
723 {
725 // When we clear the matrix, reset
726 // the pointer and generate an
727 // empty sparsity pattern.
735 column_space_map,
736 0);
737 graph->fillComplete();
738
739 nonlocal_graph.reset();
740 }
742
743
744 template <typename MemorySpace>
745 void
747 {
748 Assert(column_space_map.get(), ExcInternalError());
749 if (nonlocal_graph.get() != nullptr)
750 {
751 // Finalize the nonlocal graph. Note that in contrast to Epetra,
752 // Tpetra can finalize empty graphs without inserting dummy entries.
753 nonlocal_graph->fillComplete(column_space_map, graph->getRowMap());
754
755 // Export the nonlocal entries to their owners in the main graph.
757 nonlocal_graph->getRowMap(), graph->getRowMap());
758 graph->doExport(*nonlocal_graph, exporter, Tpetra::ADD);
759 }
760 graph->fillComplete(column_space_map, graph->getRowMap());
761
762 // Check consistency between the sizes set at the beginning and what
763 // Trilinos stores:
764 using namespace deal_II_exceptions::internals;
765 AssertDimension(n_rows(), graph->getGlobalNumRows());
766 AssertDimension(n_cols(), graph->getGlobalNumCols());
767 }
768
769
770
771 template <typename MemorySpace>
772 bool
774 {
775 return graph->getRowMap()->getLocalElement(i) !=
776 Teuchos::OrdinalTraits<int>::invalid();
777 }
778
779
780
781 template <typename MemorySpace>
782 bool
784 const size_type j) const
785 {
786 if (!row_is_stored_locally(i))
787 return false;
788
789 // Extract local indices in the matrix.
790 const auto trilinos_i = graph->getRowMap()->getLocalElement(i);
791 const auto trilinos_j = graph->getColMap()->getLocalElement(j);
792
794 col_indices;
795
796 // Generate the view.
797 graph->getLocalRowView(trilinos_i, col_indices);
798
799 // Search the index
800 const size_type local_col_index =
801 std::find(col_indices.data(),
802 col_indices.data() + col_indices.size(),
803 trilinos_j) -
804 col_indices.data();
805
806 return static_cast<std::size_t>(local_col_index) != col_indices.size();
807 }
808
810
811 template <typename MemorySpace>
814 {
815 size_type local_b = 0;
816 for (int i = 0; i < static_cast<int>(local_size()); ++i)
817 {
818 typename TpetraTypes::GraphType<
819 MemorySpace>::local_inds_host_view_type indices;
820
821 graph->getLocalRowView(i, indices);
822 const auto num_entries = indices.size();
823 for (unsigned int j = 0; j < static_cast<unsigned int>(num_entries);
824 ++j)
825 {
826 if (static_cast<size_type>(std::abs(i - indices[j])) > local_b)
827 local_b = std::abs(i - indices[j]);
828 }
829 }
830
832 Utilities::MPI::max(local_b,
834 graph->getComm()));
835 return static_cast<size_type>(global_b);
836 }
837
838
839
840 template <typename MemorySpace>
841 unsigned int
843 {
844# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
845 return graph->getLocalNumRows();
846# else
847 return graph->getNodeNumRows();
848# endif
849 }
850
851
852
853 template <typename MemorySpace>
854 std::pair<typename SparsityPattern<MemorySpace>::size_type,
857 {
858 const size_type begin = graph->getRowMap()->getMinGlobalIndex();
859 const size_type end = graph->getRowMap()->getMaxGlobalIndex() + 1;
860
861 return {begin, end};
862 }
863
864
865
866 template <typename MemorySpace>
867 std::uint64_t
869 {
870 return graph->getGlobalNumEntries();
871 }
872
873
874
875 template <typename MemorySpace>
876 unsigned int
878 {
879# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
880 return graph->getLocalMaxNumRowEntries();
881# else
882 return graph->getNodeMaxNumRowEntries();
883# endif
884 }
885
886
887
888 template <typename MemorySpace>
891 {
892 Assert(row < (size_type)n_rows(), ExcInternalError());
893
894 // Get a representation of the where the present row is located on
895 // the current processor
897 graph->getRowMap()->getLocalElement(row);
898
899 // On the processor who owns this row, we'll have a non-negative
900 // value for `local_row` and can ask for the length of the row.
901 if (local_row >= 0)
902 return graph->getNumEntriesInLocalRow(local_row);
903 else
904 return static_cast<size_type>(-1);
905 }
906
907
908
909 template <typename MemorySpace>
910 void
912 const ::types::global_dof_index &row,
914 const bool indices_are_sorted)
915 {
916 add_entries(row, columns.begin(), columns.end(), indices_are_sorted);
917 }
918
920
921 template <typename MemorySpace>
922 Teuchos::RCP<const typename TpetraTypes::MapType<MemorySpace>>
924 {
925 return graph->getDomainMap();
926 }
927
928
929
930 template <typename MemorySpace>
931 Teuchos::RCP<const typename TpetraTypes::MapType<MemorySpace>>
933 {
934 return graph->getRangeMap();
935 }
936
937
938
939 template <typename MemorySpace>
942 {
944 graph->getRangeMap()->getComm());
945 }
946
947
948
949 template <typename MemorySpace>
950 Teuchos::RCP<const Teuchos::Comm<int>>
952 {
953 return graph->getRangeMap()->getComm();
954 }
955
956
957
958 // As of now, no particularly neat
959 // output is generated in case of
960 // multiple processors.
961 template <typename MemorySpace>
962 void
964 std::ostream &out,
965 const bool write_extended_trilinos_info) const
966 {
967 if (write_extended_trilinos_info)
968 {
969 auto fancy_stream =
970 Teuchos::getFancyOStream(Teuchos::RCP(&out, false));
971 graph->describe(*fancy_stream);
972 }
973 else
974 {
975# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
976 for (unsigned int i = 0; i < graph->getLocalNumRows(); ++i)
977# else
978 for (unsigned int i = 0; i < graph->getNodeNumRows(); ++i)
979# endif
980 {
981 typename TpetraTypes::GraphType<
982 MemorySpace>::local_inds_host_view_type indices;
983 graph->getLocalRowView(i, indices);
984 int num_entries = indices.size();
985 for (int j = 0; j < num_entries; ++j)
986 out << "(" << graph->getRowMap()->getGlobalElement(i) << ","
987 << graph->getColMap()->getGlobalElement(indices[j]) << ") "
988 << std::endl;
989 }
990 }
991
992 AssertThrow(out.fail() == false, ExcIO());
993 }
994
995
996
997 template <typename MemorySpace>
998 void
1000 {
1001 Assert(graph->isFillComplete(), ExcInternalError());
1002
1003 for (unsigned int row = 0; row < local_size(); ++row)
1004 {
1005 typename TpetraTypes::GraphType<
1006 MemorySpace>::local_inds_host_view_type indices;
1007
1008 graph->getLocalRowView(row, indices);
1009 int num_entries = indices.size();
1010
1011 Assert(num_entries >= 0, ExcInternalError());
1012 // avoid sign comparison warning
1013 const ::types::signed_global_dof_index num_entries_ =
1014 num_entries;
1015 for (::types::signed_global_dof_index j = 0; j < num_entries_;
1016 ++j)
1017 // while matrix entries are usually
1018 // written (i,j), with i vertical and
1019 // j horizontal, gnuplot output is
1020 // x-y, that is we have to exchange
1021 // the order of output
1022 out << static_cast<int>(
1023 graph->getColMap()->getGlobalElement(indices[j]))
1024 << " "
1025 << -static_cast<int>(graph->getRowMap()->getGlobalElement(row))
1026 << std::endl;
1027 }
1028
1029 AssertThrow(out.fail() == false, ExcIO());
1030 }
1031
1032 // TODO: Implement!
1033 template <typename MemorySpace>
1034 std::size_t
1040
1041
1042# ifndef DOXYGEN
1043 // explicit instantiations
1045
1046 template void
1048 const ::SparsityPattern &);
1049 template void
1051 const ::DynamicSparsityPattern &);
1052
1053 template void
1055 const IndexSet &,
1056 const ::SparsityPattern &,
1057 const MPI_Comm,
1058 bool);
1059 template void
1061 const IndexSet &,
1062 const ::DynamicSparsityPattern &,
1063 const MPI_Comm,
1064 bool);
1065
1066
1067 template void
1069 const IndexSet &,
1070 const IndexSet &,
1071 const ::SparsityPattern &,
1072 const MPI_Comm,
1073 bool);
1074 template void
1076 const IndexSet &,
1077 const IndexSet &,
1078 const ::DynamicSparsityPattern &,
1079 const MPI_Comm,
1080 bool);
1081
1082
1084
1085 template void
1087 const ::SparsityPattern &);
1088 template void
1090 const ::DynamicSparsityPattern &);
1091
1092 template void
1094 const IndexSet &,
1095 const ::SparsityPattern &,
1096 const MPI_Comm,
1097 bool);
1098 template void
1100 const IndexSet &,
1101 const ::DynamicSparsityPattern &,
1102 const MPI_Comm,
1103 bool);
1104
1105
1106 template void
1108 const IndexSet &,
1109 const IndexSet &,
1110 const ::SparsityPattern &,
1111 const MPI_Comm,
1112 bool);
1113 template void
1115 const IndexSet &,
1116 const IndexSet &,
1117 const ::DynamicSparsityPattern &,
1118 const MPI_Comm,
1119 bool);
1120
1121# endif
1122
1123 } // namespace TpetraWrappers
1124
1125} // namespace LinearAlgebra
1126
1127
1128#endif // DEAL_II_TRILINOS_WITH_TPETRA
*  iterator end()
*  *  iterator begin()
iterator begin() const
Definition array_view.h:755
iterator end() const
Definition array_view.h:764
size_type size() const
Definition index_set.h:1759
size_type n_elements() const
Definition index_set.h:1917
void subtract_set(const IndexSet &other)
Definition index_set.cc:496
Teuchos::RCP< TpetraTypes::GraphType< MemorySpace > > graph
Teuchos::RCP< const Teuchos::Comm< int > > get_teuchos_mpi_communicator() const
Teuchos::RCP< const TpetraTypes::MapType< MemorySpace > > range_partitioner() const
void copy_from(const SparsityPattern< MemorySpace > &input_sparsity_pattern)
SparsityPattern< MemorySpace > & operator=(const SparsityPattern< MemorySpace > &input_sparsity_pattern)
void print(std::ostream &out, const bool write_extended_trilinos_info=false) const
Teuchos::RCP< TpetraTypes::GraphType< MemorySpace > > nonlocal_graph
Teuchos::RCP< const TpetraTypes::MapType< MemorySpace > > domain_partitioner() const
bool exists(const size_type i, const size_type j) const
Teuchos::RCP< TpetraTypes::MapType< MemorySpace > > column_space_map
void reinit(const size_type m, const size_type n, const size_type n_entries_per_row)
virtual void add_row_entries(const ::types::global_dof_index &row, const ArrayView< const ::types::global_dof_index > &columns, const bool indices_are_sorted=false) override
virtual void resize(const size_type rows, const size_type cols)
size_type n_rows() const
size_type n_cols() const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
constexpr bool running_in_debug_mode()
Definition config.h:76
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcIO()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
IndexSet complete_index_set(const IndexSet::size_type N)
Definition index_set.h:1187
void reinit_sp(const Teuchos::RCP< TpetraTypes::MapType< MemorySpace > > &row_map, const Teuchos::RCP< TpetraTypes::MapType< MemorySpace > > &col_map, const size_type< MemorySpace > n_entries_per_row, Teuchos::RCP< TpetraTypes::MapType< MemorySpace > > &column_space_map, Teuchos::RCP< TpetraTypes::GraphType< MemorySpace > > &graph, Teuchos::RCP< TpetraTypes::GraphType< MemorySpace > > &nonlocal_graph)
typename SparsityPattern< MemorySpace >::size_type size_type
Tpetra::CrsGraph< LO, GO, NodeType< MemorySpace > > GraphType
Tpetra::Map< LO, GO, NodeType< MemorySpace > > MapType
Tpetra::Export< LO, GO, NodeType< MemorySpace > > ExportType
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
Definition mpi.cc:103
T max(const T &t, const MPI_Comm mpi_communicator)
Teuchos::RCP< T > make_rcp(Args &&...args)
MPI_Comm teuchos_comm_to_mpi_comm(const Teuchos::RCP< const Teuchos::Comm< int > > &teuchos_comm)
const Teuchos::RCP< const Teuchos::Comm< int > > & tpetra_comm_self()
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)