deal.II version GIT relicensing-2287-g6548a49e0a 2024-12-20 18:30:00+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_utilities.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2022 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#include <deal.II/base/mpi.h>
17
18#ifdef DEAL_II_WITH_TRILINOS
19# ifdef DEAL_II_WITH_MPI
20# include <Epetra_MpiComm.h>
21# include <Teuchos_DefaultComm.hpp>
22# endif
23# include <Epetra_SerialComm.h>
24# include <Teuchos_RCP.hpp>
25#endif
26
28
29namespace Utilities
30{
31#ifdef DEAL_II_WITH_TRILINOS
32 namespace Trilinos
33 {
34 const Epetra_Comm &
36 {
37# ifdef DEAL_II_WITH_MPI
38 static Teuchos::RCP<Epetra_MpiComm> communicator =
39 Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD), true);
40# else
41 static Teuchos::RCP<Epetra_SerialComm> communicator =
42 Teuchos::rcp(new Epetra_SerialComm(), true);
43# endif
44
45 return *communicator;
46 }
47
48
49
50 const Teuchos::RCP<const Teuchos::Comm<int>> &
52 {
53# ifdef DEAL_II_WITH_MPI
54 static auto communicator = Teuchos::RCP<const Teuchos::Comm<int>>(
55 new Teuchos::MpiComm<int>(MPI_COMM_SELF));
56# else
57 static auto communicator =
58 Teuchos::RCP<const Teuchos::Comm<int>>(new Teuchos::Comm<int>());
59# endif
60
61 return communicator;
62 }
63
64
65
66 const Epetra_Comm &
68 {
69# ifdef DEAL_II_WITH_MPI
70 static Teuchos::RCP<Epetra_MpiComm> communicator =
71 Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_SELF), true);
72# else
73 static Teuchos::RCP<Epetra_SerialComm> communicator =
74 Teuchos::rcp(new Epetra_SerialComm(), true);
75# endif
76
77 return *communicator;
78 }
79
80
81
82 Epetra_Comm *
83 duplicate_communicator(const Epetra_Comm &communicator)
84 {
85# ifdef DEAL_II_WITH_MPI
86
87 // see if the communicator is in fact a
88 // parallel MPI communicator; if so,
89 // return a duplicate of it
90 const Epetra_MpiComm *mpi_comm =
91 dynamic_cast<const Epetra_MpiComm *>(&communicator);
92 if (mpi_comm != nullptr)
93 return new Epetra_MpiComm(
94 Utilities::MPI::duplicate_communicator(mpi_comm->GetMpiComm()));
95# endif
96
97 // if we don't support MPI, or if the
98 // communicator in question was in fact
99 // not an MPI communicator, return a
100 // copy of the same object again
101 Assert(dynamic_cast<const Epetra_SerialComm *>(&communicator) != nullptr,
103 return new Epetra_SerialComm(
104 dynamic_cast<const Epetra_SerialComm &>(communicator));
105 }
106
107
108
109 void
110 destroy_communicator(Epetra_Comm &communicator)
111 {
112 // save the communicator, reset the map, and delete the communicator if
113 // this whole thing was created as an MPI communicator
114# ifdef DEAL_II_WITH_MPI
115 Epetra_MpiComm *mpi_comm = dynamic_cast<Epetra_MpiComm *>(&communicator);
116 if (mpi_comm != nullptr)
117 {
118 MPI_Comm comm = mpi_comm->GetMpiComm();
119 *mpi_comm = Epetra_MpiComm(MPI_COMM_SELF);
120
122 }
123# endif
124 }
125
126
127
128 unsigned int
129 get_n_mpi_processes(const Epetra_Comm &mpi_communicator)
130 {
131 return mpi_communicator.NumProc();
132 }
133
134
135 unsigned int
136 get_this_mpi_process(const Epetra_Comm &mpi_communicator)
137 {
138 return static_cast<unsigned int>(mpi_communicator.MyPID());
139 }
140
141
142
143 Epetra_Map
144 duplicate_map(const Epetra_BlockMap &map, const Epetra_Comm &comm)
145 {
146 if (map.LinearMap() == true)
147 {
148 // each processor stores a
149 // contiguous range of
150 // elements in the
151 // following constructor
152 // call
153 return Epetra_Map(map.NumGlobalElements(),
154 map.NumMyElements(),
155 map.IndexBase(),
156 comm);
157 }
158 else
159 {
160 // the range is not
161 // contiguous
162 return Epetra_Map(map.NumGlobalElements(),
163 map.NumMyElements(),
164 map.MyGlobalElements(),
165 0,
166 comm);
167 }
168 }
169 } // namespace Trilinos
170#endif
171
172
173#ifdef DEAL_II_TRILINOS_WITH_TPETRA
174 namespace Trilinos
175 {
178 const Teuchos::RCP<const Teuchos::Comm<int>> &teuchos_comm)
179 {
180 MPI_Comm out;
181# ifdef DEAL_II_WITH_MPI
182 // Cast from Teuchos::Comm<int> to Teuchos::MpiComm<int>.
183 const Teuchos::MpiComm<int> *mpi_comm =
184 dynamic_cast<const Teuchos::MpiComm<int> *>(teuchos_comm.get());
185 Assert(mpi_comm != nullptr, ExcInternalError());
186 // From the Teuchos::MpiComm<int> object we can extract
187 // the MPI_Comm object via the getRawMpiComm() function.
188 out = *(mpi_comm->getRawMpiComm())();
189# else
190 out = MPI_COMM_SELF;
191# endif
192 return out;
193 }
194 } // namespace Trilinos
195#endif // DEAL_II_TRILINOS_WITH_TPETRA
196
197} // namespace Utilities
198
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
const MPI_Comm comm
Definition mpi.cc:913
MPI_Comm duplicate_communicator(const MPI_Comm mpi_communicator)
Definition mpi.cc:143
void free_communicator(MPI_Comm mpi_communicator)
Definition mpi.cc:154
void destroy_communicator(Epetra_Comm &communicator)
Epetra_Map duplicate_map(const Epetra_BlockMap &map, const Epetra_Comm &comm)
unsigned int get_this_mpi_process(const Epetra_Comm &mpi_communicator)
unsigned int get_n_mpi_processes(const Epetra_Comm &mpi_communicator)
const Epetra_Comm & comm_self()
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()
Epetra_Comm * duplicate_communicator(const Epetra_Comm &communicator)
const Epetra_Comm & comm_world()