deal.II version 9.8.0
\(\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
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<
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 {
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 {
256 MPI_COMM_SELF,
257 n_entries_per_row);
258 }
259
260
261
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 // for more than one processor, need to specify only row map first and
289 // let the matrix entries decide about the column map (which says which
290 // columns are present in the matrix, not to be confused with the
291 // col_map that tells how the domain dofs of the matrix will be
292 // distributed). for only one processor, we can directly assign the
293 // columns as well. If we use a recent Trilinos version, we can also
294 // require building a non-local graph which gives us thread-safe
295 // initialization.
298 row_map,
299 n_entries_per_row);
300 }
301
302
303
304 template <typename MemorySpace>
305 void
307 const Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &row_map,
308 const Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &col_map,
309 const std::vector<size_type<MemorySpace>> &n_entries_per_row,
313 {
314 Assert(row_map->isOneToOne(),
315 ExcMessage("Row map must be 1-to-1, i.e., no overlap between "
316 "the maps of different processors."));
317 Assert(col_map->isOneToOne(),
318 ExcMessage("Column map must be 1-to-1, i.e., no overlap between "
319 "the maps of different processors."));
320
321 // release memory before reallocation
322 nonlocal_graph.reset();
323 graph.reset();
324 AssertDimension(n_entries_per_row.size(),
325 row_map->getGlobalNumElements());
326
327 column_space_map = col_map;
328
329 // Translate the vector of row lengths into one that only stores
330 // those entries that related to the locally stored rows of the matrix:
331 Kokkos::DualView<size_t *, typename MemorySpace::kokkos_space>
332 local_entries_per_row("local_entries_per_row",
333 row_map->getMaxGlobalIndex() -
334 row_map->getMinGlobalIndex());
335
336 auto local_entries_per_row_host =
337 local_entries_per_row
338 .template view<Kokkos::DefaultHostExecutionSpace>();
339
340 std::uint64_t total_size = 0;
341 for (unsigned int i = 0; i < local_entries_per_row.extent(0); ++i)
342 {
343 local_entries_per_row_host(i) =
344 n_entries_per_row[row_map->getMinGlobalIndex() + i];
345 total_size += local_entries_per_row_host[i];
346 }
347 local_entries_per_row
348 .template modify<Kokkos::DefaultHostExecutionSpace>();
349 local_entries_per_row
350 .template sync<typename MemorySpace::kokkos_space>();
351
353 total_size < static_cast<std::uint64_t>(
354 std::numeric_limits<
357 "You are requesting to store more elements than global ordinal type allows."));
358
361 col_map,
362 local_entries_per_row);
363 }
364
365
366
367 template <typename SparsityPatternType, typename MemorySpace>
368 void
370 const Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &row_map,
371 const Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &col_map,
372 const SparsityPatternType &sp,
373 [[maybe_unused]] const bool exchange_data,
374 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> &column_space_map,
375 Teuchos::RCP<TpetraTypes::GraphType<MemorySpace>> &graph,
376 Teuchos::RCP<TpetraTypes::GraphType<MemorySpace>> &nonlocal_graph)
377 {
378 nonlocal_graph.reset();
379 graph.reset();
380
381 AssertDimension(sp.n_rows(), row_map->getGlobalNumElements());
382 AssertDimension(sp.n_cols(), col_map->getGlobalNumElements());
383
386
387 Assert(row_map->isContiguous() == true,
389 "This function only works if the row map is contiguous."));
390
391 const size_type<MemorySpace> first_row = row_map->getMinGlobalIndex(),
392 last_row =
393 row_map->getMaxGlobalIndex() + 1;
394 Teuchos::Array<size_t> n_entries_per_row(last_row - first_row);
395
396 for (size_type<MemorySpace> row = first_row; row < last_row; ++row)
397 n_entries_per_row[row - first_row] = sp.row_length(row);
398
400 std::accumulate(n_entries_per_row.begin(),
401 n_entries_per_row.end(),
402 std::uint64_t(0)) <
403 static_cast<std::uint64_t>(std::numeric_limits<int>::max()),
405 "The TrilinosWrappers use Tpetra internally, and "
406 "Trilinos/Tpetra was compiled with 'local ordinate = int'. "
407 "Therefore, 'signed int' is used to represent local indices, "
408 "and only 2,147,483,647 nonzero matrix entries can be stored "
409 "on a single process, but you are requesting more than "
410 "that. Either use more MPI processes or recompile Trilinos "
411 "with 'local ordinate = long long' "));
412
413 if (row_map->getComm()->getSize() > 1)
415 TpetraTypes::GraphType<MemorySpace>>(row_map, n_entries_per_row);
416 else
419 col_map,
420 n_entries_per_row);
421
422 // We can't check for equality of sp.n_cols() and
423 // graph->getGlobalNumCols() here since we don't necessarily have a
424 // column map at this point.
425 AssertDimension(sp.n_rows(), graph->getGlobalNumRows());
426
427 std::vector<TrilinosWrappers::types::int_type> row_indices;
428
429 for (size_type<MemorySpace> row = first_row; row < last_row; ++row)
430 {
432 sp.row_length(row);
433 if (row_length == 0)
434 continue;
435
436 row_indices.resize(row_length, -1);
437 {
438 typename SparsityPatternType::iterator p = sp.begin(row);
439 // avoid incrementing p over the end of the current row because
440 // it is slow for DynamicSparsityPattern in parallel
441 for (int col = 0; col < row_length;)
442 {
443 row_indices[col++] = p->column();
444 if (col < row_length)
445 ++p;
446 }
447 }
448 graph->insertGlobalIndices(row, row_length, row_indices.data());
449 }
450
451 graph->globalAssemble();
452 }
453 } // namespace SparsityPatternImpl
454
455
456 template <typename MemorySpace>
457 void
458 SparsityPattern<MemorySpace>::reinit(const IndexSet &parallel_partitioning,
459 const MPI_Comm communicator,
460 const size_type n_entries_per_row)
461 {
462 SparsityPatternBase::resize(parallel_partitioning.size(),
463 parallel_partitioning.size());
464 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> map =
465 parallel_partitioning
466 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
467 communicator, false);
469 map, map, n_entries_per_row, column_space_map, graph, nonlocal_graph);
470 }
471
472
473
474 template <typename MemorySpace>
475 void
477 const IndexSet &parallel_partitioning,
478 const MPI_Comm communicator,
479 const std::vector<size_type> &n_entries_per_row)
480 {
481 SparsityPatternBase::resize(parallel_partitioning.size(),
482 parallel_partitioning.size());
483 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> map =
484 parallel_partitioning
485 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
486 communicator, false);
488 map, map, n_entries_per_row, column_space_map, graph, nonlocal_graph);
489 }
490
491
492
493 template <typename MemorySpace>
494 void
496 const IndexSet &row_parallel_partitioning,
497 const IndexSet &col_parallel_partitioning,
498 const MPI_Comm communicator,
499 const size_type n_entries_per_row)
500 {
501 SparsityPatternBase::resize(row_parallel_partitioning.size(),
502 col_parallel_partitioning.size());
503 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> row_map =
504 row_parallel_partitioning
505 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
506 communicator, false);
507 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> col_map =
508 col_parallel_partitioning
509 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
510 communicator, false);
512 col_map,
513 n_entries_per_row,
515 graph,
517 }
518
519
520
521 template <typename MemorySpace>
522 void
524 const IndexSet &row_parallel_partitioning,
525 const IndexSet &col_parallel_partitioning,
526 const MPI_Comm communicator,
527 const std::vector<size_type> &n_entries_per_row)
528 {
529 SparsityPatternBase::resize(row_parallel_partitioning.size(),
530 col_parallel_partitioning.size());
531 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> row_map =
532 row_parallel_partitioning
533 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
534 communicator, false);
535 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> col_map =
536 col_parallel_partitioning
537 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
538 communicator, false);
540 col_map,
541 n_entries_per_row,
543 graph,
545 }
546
547
548
549 template <typename MemorySpace>
550 void
552 const IndexSet &row_parallel_partitioning,
553 const IndexSet &col_parallel_partitioning,
554 const IndexSet &writable_rows,
555 const MPI_Comm communicator,
556 const size_type n_entries_per_row)
557 {
558 SparsityPatternBase::resize(row_parallel_partitioning.size(),
559 col_parallel_partitioning.size());
560 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> row_map =
561 row_parallel_partitioning
562 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
563 communicator, false);
564 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> col_map =
565 col_parallel_partitioning
566 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
567 communicator, false);
569 col_map,
570 n_entries_per_row,
572 graph,
574
575 IndexSet nonlocal_partitioner = writable_rows;
576 AssertDimension(nonlocal_partitioner.size(),
577 row_parallel_partitioning.size());
578 if constexpr (running_in_debug_mode())
579 {
580 {
581 IndexSet tmp = writable_rows & row_parallel_partitioning;
582 Assert(tmp == row_parallel_partitioning,
584 "The set of writable rows passed to this method does not "
585 "contain the locally owned rows, which is not allowed."));
586 }
587 }
588 nonlocal_partitioner.subtract_set(row_parallel_partitioning);
589 if (Utilities::MPI::n_mpi_processes(communicator) > 1)
590 {
591 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> nonlocal_map =
592 nonlocal_partitioner
593 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
594 communicator, true);
596 TpetraTypes::GraphType<MemorySpace>>(nonlocal_map, col_map, 0);
597 }
598 else
599 Assert(nonlocal_partitioner.n_elements() == 0, ExcInternalError());
600 }
601
602
603
604 template <typename MemorySpace>
605 template <typename SparsityPatternType>
606 void
608 const IndexSet &row_parallel_partitioning,
609 const IndexSet &col_parallel_partitioning,
610 const SparsityPatternType &nontrilinos_sparsity_pattern,
611 const MPI_Comm communicator,
612 const bool exchange_data)
613 {
614 SparsityPatternBase::resize(row_parallel_partitioning.size(),
615 col_parallel_partitioning.size());
616 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> row_map =
617 row_parallel_partitioning
618 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
619 communicator, false);
620 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> col_map =
621 col_parallel_partitioning
622 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
623 communicator, false);
625 row_map,
626 col_map,
627 nontrilinos_sparsity_pattern,
628 exchange_data,
630 graph,
632 }
633
634
635
636 template <typename MemorySpace>
637 template <typename SparsityPatternType>
638 void
640 const IndexSet &parallel_partitioning,
641 const SparsityPatternType &nontrilinos_sparsity_pattern,
642 const MPI_Comm communicator,
643 const bool exchange_data)
644 {
645 AssertDimension(nontrilinos_sparsity_pattern.n_rows(),
646 parallel_partitioning.size());
647 AssertDimension(nontrilinos_sparsity_pattern.n_cols(),
648 parallel_partitioning.size());
649 SparsityPatternBase::resize(parallel_partitioning.size(),
650 parallel_partitioning.size());
651 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> map =
652 parallel_partitioning
653 .template make_tpetra_map_rcp<TpetraTypes::NodeType<MemorySpace>>(
654 communicator, false);
656 map,
657 map,
658 nontrilinos_sparsity_pattern,
659 exchange_data,
661 graph,
663 }
665
666
667 template <typename MemorySpace>
675
677
678 template <typename MemorySpace>
679 void
682 {
688
689 if (sp.nonlocal_graph.get() != nullptr)
692 else
693 nonlocal_graph.reset();
694 }
695
696
697
698 template <typename MemorySpace>
699 template <typename SparsityPatternType>
700 void
701 SparsityPattern<MemorySpace>::copy_from(const SparsityPatternType &sp)
702 {
703 SparsityPatternBase::resize(sp.n_rows(), sp.n_cols());
704 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> rows =
708 0,
710 Teuchos::RCP<TpetraTypes::MapType<MemorySpace>> columns =
714 0,
716
718 rows, columns, sp, false, column_space_map, graph, nonlocal_graph);
719 }
721
722
723 template <typename MemorySpace>
724 void
726 {
728 // When we clear the matrix, reset
729 // the pointer and generate an
730 // empty sparsity pattern.
739 0);
740 graph->fillComplete();
742 nonlocal_graph.reset();
743 }
744
745
746
747 template <typename MemorySpace>
748 void
750 {
752 if (nonlocal_graph.get() != nullptr)
753 {
754# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
755 if (nonlocal_graph->getRowMap()->getLocalNumElements() > 0 &&
756 column_space_map->getGlobalNumElements() > 0)
757# else
758 if (nonlocal_graph->getRowMap()->getNodeNumElements() > 0 &&
759 column_space_map->getGlobalNumElements() > 0)
760# endif
761 {
762 // Insert dummy element at (row, column) that corresponds to row 0
763 // in local index counting.
765 nonlocal_graph->getRowMap()->getGlobalElement(0);
767
768 // in case we have a square sparsity pattern, add the entry on the
769 // diagonal
770 if (column_space_map->getGlobalNumElements() ==
771 graph->getRangeMap()->getGlobalNumElements())
772 column = row;
773 // if not, take a column index that we have ourselves since we
774 // know for sure it is there (and it will not create spurious
775 // messages to many ranks like putting index 0 on many
776 // processors)
777# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
778 else if (column_space_map->getLocalNumElements() > 0)
779# else
780 else if (column_space_map->getNodeNumElements() > 0)
781# endif
782 column = column_space_map->getGlobalElement(0);
783 nonlocal_graph->insertGlobalIndices(row, 1, &column);
784 }
785# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
786 Assert(nonlocal_graph->getRowMap()->getLocalNumElements() == 0 ||
787 column_space_map->getGlobalNumElements() == 0,
789# else
790 Assert(nonlocal_graph->getRowMap()->getNodeNumElements() == 0 ||
791 column_space_map->getGlobalNumElements() == 0,
793# endif
794
795 nonlocal_graph->fillComplete(column_space_map, graph->getRowMap());
796 }
797 graph->fillComplete(column_space_map, graph->getRowMap());
798
799 // Check consistency between the sizes set at the beginning and what
800 // Trilinos stores:
801 using namespace deal_II_exceptions::internals;
802 AssertDimension(n_rows(), graph->getGlobalNumRows());
803 AssertDimension(n_cols(), graph->getGlobalNumCols());
804 }
805
806
807
808 template <typename MemorySpace>
809 bool
811 {
812 return graph->getRowMap()->getLocalElement(i) !=
813 Teuchos::OrdinalTraits<int>::invalid();
814 }
816
817
818 template <typename MemorySpace>
819 bool
821 const size_type j) const
822 {
823 if (!row_is_stored_locally(i))
824 return false;
825
826 // Extract local indices in the matrix.
827 const auto trilinos_i = graph->getRowMap()->getLocalElement(i);
828 const auto trilinos_j = graph->getColMap()->getLocalElement(j);
829
831 col_indices;
832
833 // Generate the view.
834 graph->getLocalRowView(trilinos_i, col_indices);
835
836 // Search the index
837 const size_type local_col_index =
838 std::find(col_indices.data(),
839 col_indices.data() + col_indices.size(),
840 trilinos_j) -
841 col_indices.data();
842
843 return static_cast<std::size_t>(local_col_index) != col_indices.size();
844 }
845
846
847
848 template <typename MemorySpace>
851 {
852 size_type local_b = 0;
853 for (int i = 0; i < static_cast<int>(local_size()); ++i)
854 {
855 typename TpetraTypes::GraphType<
856 MemorySpace>::local_inds_host_view_type indices;
857
858 graph->getLocalRowView(i, indices);
859 const auto num_entries = indices.size();
860 for (unsigned int j = 0; j < static_cast<unsigned int>(num_entries);
861 ++j)
862 {
863 if (static_cast<size_type>(std::abs(i - indices[j])) > local_b)
864 local_b = std::abs(i - indices[j]);
865 }
866 }
867
869 Utilities::MPI::max(local_b,
871 graph->getComm()));
872 return static_cast<size_type>(global_b);
873 }
874
875
876
877 template <typename MemorySpace>
878 unsigned int
880 {
881# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
882 return graph->getLocalNumRows();
883# else
884 return graph->getNodeNumRows();
885# endif
886 }
887
888
889
890 template <typename MemorySpace>
891 std::pair<typename SparsityPattern<MemorySpace>::size_type,
894 {
895 const size_type begin = graph->getRowMap()->getMinGlobalIndex();
896 const size_type end = graph->getRowMap()->getMaxGlobalIndex() + 1;
897
898 return {begin, end};
899 }
900
902
903 template <typename MemorySpace>
904 std::uint64_t
906 {
907 return graph->getGlobalNumEntries();
908 }
909
910
911
912 template <typename MemorySpace>
913 unsigned int
915 {
916# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
917 return graph->getLocalMaxNumRowEntries();
918# else
919 return graph->getNodeMaxNumRowEntries();
920# endif
921 }
922
923
924
925 template <typename MemorySpace>
928 {
930
931 // Get a representation of the where the present row is located on
932 // the current processor
934 graph->getRowMap()->getLocalElement(row);
935
936 // On the processor who owns this row, we'll have a non-negative
937 // value for `local_row` and can ask for the length of the row.
938 if (local_row >= 0)
939 return graph->getNumEntriesInLocalRow(local_row);
940 else
941 return static_cast<size_type>(-1);
942 }
943
944
945
946 template <typename MemorySpace>
947 void
949 const ::types::global_dof_index &row,
951 const bool indices_are_sorted)
952 {
953 add_entries(row, columns.begin(), columns.end(), indices_are_sorted);
954 }
955
956
957
958 template <typename MemorySpace>
959 Teuchos::RCP<const typename TpetraTypes::MapType<MemorySpace>>
961 {
962 return graph->getDomainMap();
963 }
964
965
966
967 template <typename MemorySpace>
968 Teuchos::RCP<const typename TpetraTypes::MapType<MemorySpace>>
970 {
971 return graph->getRangeMap();
972 }
973
974
975
976 template <typename MemorySpace>
983
984
985
986 template <typename MemorySpace>
987 Teuchos::RCP<const Teuchos::Comm<int>>
989 {
990 return graph->getRangeMap()->getComm();
991 }
992
993
994
995 // As of now, no particularly neat
996 // output is generated in case of
997 // multiple processors.
998 template <typename MemorySpace>
999 void
1001 std::ostream &out,
1002 const bool write_extended_trilinos_info) const
1003 {
1004 if (write_extended_trilinos_info)
1005 {
1006 auto fancy_stream =
1007 Teuchos::getFancyOStream(Teuchos::RCP(&out, false));
1008 graph->describe(*fancy_stream);
1009 }
1010 else
1011 {
1012# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
1013 for (unsigned int i = 0; i < graph->getLocalNumRows(); ++i)
1014# else
1015 for (unsigned int i = 0; i < graph->getNodeNumRows(); ++i)
1016# endif
1017 {
1018 typename TpetraTypes::GraphType<
1019 MemorySpace>::local_inds_host_view_type indices;
1020 graph->getLocalRowView(i, indices);
1021 int num_entries = indices.size();
1022 for (int j = 0; j < num_entries; ++j)
1023 out << "(" << graph->getRowMap()->getGlobalElement(i) << ","
1024 << graph->getColMap()->getGlobalElement(indices[j]) << ") "
1025 << std::endl;
1026 }
1027 }
1028
1029 AssertThrow(out.fail() == false, ExcIO());
1030 }
1031
1032
1033
1034 template <typename MemorySpace>
1035 void
1037 {
1038 Assert(graph->isFillComplete(), ExcInternalError());
1039
1040 for (unsigned int row = 0; row < local_size(); ++row)
1041 {
1042 typename TpetraTypes::GraphType<
1043 MemorySpace>::local_inds_host_view_type indices;
1044
1045 graph->getLocalRowView(row, indices);
1046 int num_entries = indices.size();
1047
1048 Assert(num_entries >= 0, ExcInternalError());
1049 // avoid sign comparison warning
1050 const ::types::signed_global_dof_index num_entries_ =
1051 num_entries;
1052 for (::types::signed_global_dof_index j = 0; j < num_entries_;
1053 ++j)
1054 // while matrix entries are usually
1055 // written (i,j), with i vertical and
1056 // j horizontal, gnuplot output is
1057 // x-y, that is we have to exchange
1058 // the order of output
1059 out << static_cast<int>(
1060 graph->getColMap()->getGlobalElement(indices[j]))
1061 << " "
1062 << -static_cast<int>(graph->getRowMap()->getGlobalElement(row))
1063 << std::endl;
1064 }
1065
1066 AssertThrow(out.fail() == false, ExcIO());
1067 }
1068
1069 // TODO: Implement!
1070 template <typename MemorySpace>
1071 std::size_t
1077
1078
1079# ifndef DOXYGEN
1080 // explicit instantiations
1082
1083 template void
1085 const ::SparsityPattern &);
1086 template void
1088 const ::DynamicSparsityPattern &);
1089
1090 template void
1092 const IndexSet &,
1093 const ::SparsityPattern &,
1094 const MPI_Comm,
1095 bool);
1096 template void
1098 const IndexSet &,
1099 const ::DynamicSparsityPattern &,
1100 const MPI_Comm,
1101 bool);
1102
1103
1104 template void
1106 const IndexSet &,
1107 const IndexSet &,
1108 const ::SparsityPattern &,
1109 const MPI_Comm,
1110 bool);
1111 template void
1113 const IndexSet &,
1114 const IndexSet &,
1115 const ::DynamicSparsityPattern &,
1116 const MPI_Comm,
1117 bool);
1118
1119
1121
1122 template void
1124 const ::SparsityPattern &);
1125 template void
1127 const ::DynamicSparsityPattern &);
1128
1129 template void
1131 const IndexSet &,
1132 const ::SparsityPattern &,
1133 const MPI_Comm,
1134 bool);
1135 template void
1137 const IndexSet &,
1138 const ::DynamicSparsityPattern &,
1139 const MPI_Comm,
1140 bool);
1141
1142
1143 template void
1145 const IndexSet &,
1146 const IndexSet &,
1147 const ::SparsityPattern &,
1148 const MPI_Comm,
1149 bool);
1150 template void
1152 const IndexSet &,
1153 const IndexSet &,
1154 const ::DynamicSparsityPattern &,
1155 const MPI_Comm,
1156 bool);
1157
1158# endif
1159
1160 } // namespace TpetraWrappers
1161
1162} // namespace LinearAlgebra
1163
1164
1165#endif // DEAL_II_TRILINOS_WITH_TPETRA
iterator begin() const
Definition array_view.h:755
iterator end() const
Definition array_view.h:764
size_type size() const
Definition index_set.h:1783
size_type n_elements() const
Definition index_set.h:1941
void subtract_set(const IndexSet &other)
Definition index_set.cc:496
std::shared_ptr< std::vector<::types::signed_global_dof_index > > colnum_cache
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
void add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_sorted=false)
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:1211
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
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 > &)
int signed_global_dof_index
Definition types.h:103