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