oomph::DoubleVectorHaloScheme Class Reference

#include <double_vector_with_halo.h>

Public Member Functions

 DoubleVectorHaloScheme (LinearAlgebraDistribution *const &dist_pt, const Vector< unsigned > &required_global_eqn)
 
unsigned n_halo_values () const
 Return the number of halo values. More...
 
LinearAlgebraDistribution *& distribution_pt ()
 
void setup_halo_dofs (const std::map< unsigned, double * > &halo_data_pt, Vector< double * > &halo_dof_pt)
 
unsigned local_index (const unsigned &global_eqn)
 Return the local index associated with the global equation. More...
 

Private Attributes

std::map< unsigned, unsignedLocal_index
 
Vector< unsignedHaloed_eqns
 
Vector< intHaloed_n
 
Vector< intHaloed_displacement
 
Vector< unsignedHalo_eqns
 
Vector< intHalo_n
 
Vector< intHalo_displacement
 
LinearAlgebraDistributionDistribution_pt
 Store the distribution that was used to setup the halo scheme. More...
 

Friends

class DoubleVectorWithHaloEntries
 

Detailed Description

A class that stores the halo/haloed entries required when using a DoubleVectorWithHaloEntries. This is a separate class so thay many different Vectors can share the same object. The constructor requires the distribution of the DoubleVector (if you pass in a different distribution things will go badly wrong) and a vector that specifies which GLOBAL eqn numbers are required on each processor.

Constructor & Destructor Documentation

◆ DoubleVectorHaloScheme()

oomph::DoubleVectorHaloScheme::DoubleVectorHaloScheme ( LinearAlgebraDistribution *const &  dist_pt,
const Vector< unsigned > &  required_global_eqn 
)

Constructor that sets up the required information communicating between all processors. Requires two "all to all" communications. Arguments are the distribution of the DoubleVector and a Vector of global unknowns required on this processor.

39  : Distribution_pt(dist_pt)
40  {
41 #ifdef OOMPH_HAS_MPI
42  // Only bother to do anything if the vector is distributed
43  if (dist_pt->distributed())
44  {
45  // First create temporary maps for halo requests.
46  // Using the map structure ensures that the data will be sorted
47  // into processor order: the order of the unsigned integer key
48 
49  // These are the halo requests indexed by master processor and the
50  // local equation number that is to be haloed on that processor
51  std::map<unsigned, Vector<unsigned>> to_be_haloed;
52  // These are the halo requests indexed by master processor and the
53  // index in the additional storage
54  // that corresponds to the halo data on this processor
55  std::map<unsigned, Vector<unsigned>> halo_entries;
56 
57  // Find rank of current processor
58  const unsigned my_rank =
59  static_cast<int>(dist_pt->communicator_pt()->my_rank());
60  // Loop over the desired equations (on this processor)
61  // and work out whether we need to halo them according to the
62  // given distribution
63  const unsigned n_global_eqn = required_global_eqn.size();
64  // Index for the locally stored halo values
65  unsigned index = 0;
66  for (unsigned n = 0; n < n_global_eqn; n++)
67  {
68  // Cache the required GLOBAL equation number
69  const unsigned i_global = required_global_eqn[n];
70  // Where is it stored?
71  unsigned rank_of_global = dist_pt->rank_of_global_row(i_global);
72  // If the equation is not stored locally then
73  // populate the two maps
74  if (my_rank != rank_of_global)
75  {
76  // Work out the local entry on the appropriate processor
77  unsigned i_local = i_global - dist_pt->first_row(rank_of_global);
78  // Mark the local storage index as halo with rank_of_global as master
79  halo_entries[rank_of_global].push_back(index);
80  // Mark the local equation of the rank_of_global as to be
81  // haloed
82  to_be_haloed[rank_of_global].push_back(i_local);
83  // Store the local index corresponding to the global equation
84  Local_index[i_global] = index;
85  // Increment the index
86  ++index;
87  }
88  }
89 
90  // We now need to tell the other processors which of their data are
91  // haloed on this processor
92 
93  // First find out how many processors there are!
94  const int n_proc = dist_pt->communicator_pt()->nproc();
95 
96  // Setup storage for number of data to be sent to each processor
97  Vector<int> send_n(n_proc, 0);
98  Vector<int> send_displacement(n_proc, 0);
99  int send_data_count = 0;
100 
101  // Iterate over the entries in the map
102  // This will be in rank order because of the ordering of the map
103  for (std::map<unsigned, Vector<unsigned>>::iterator it =
104  to_be_haloed.begin();
105  it != to_be_haloed.end();
106  ++it)
107  {
108  const unsigned rank = it->first;
109  const unsigned size_ = it->second.size();
110  // The displacement is the current number of data
111  send_displacement[rank] = send_data_count;
112  // The number to send is just the size of the array
113  send_n[rank] = static_cast<int>(size_);
114  send_data_count += size_;
115  }
116 
117  // Now send the number of haloed entries from every processor
118  // to every processor
119 
120  // Receive the data directly into the storage for haloed daa
121  Haloed_n.resize(n_proc, 0);
122  MPI_Alltoall(&send_n[0],
123  1,
124  MPI_INT,
125  &Haloed_n[0],
126  1,
127  MPI_INT,
128  dist_pt->communicator_pt()->mpi_comm());
129 
130  // Prepare the data to be sent
131  // Always resize to at least one
132  if (send_data_count == 0)
133  {
134  ++send_data_count;
135  }
136  Vector<unsigned> send_data(send_data_count);
137  // Iterate over the entries in the map
138  unsigned count = 0;
139  for (std::map<unsigned, Vector<unsigned>>::iterator it =
140  to_be_haloed.begin();
141  it != to_be_haloed.end();
142  ++it)
143  {
144  // Iterate over the vector
145  for (Vector<unsigned>::iterator it2 = it->second.begin();
146  it2 != it->second.end();
147  ++it2)
148  {
149  send_data[count] = (*it2);
150  ++count;
151  }
152  }
153 
154  // Prepare the data to be received,
155  // Again this can go directly into Haloed storage
156  int receive_data_count = 0;
157  Haloed_displacement.resize(n_proc);
158  for (int d = 0; d < n_proc; d++)
159  {
160  // The displacement is the amount of data received so far
161  Haloed_displacement[d] = receive_data_count;
162  receive_data_count += Haloed_n[d];
163  }
164 
165  // Now resize the receive buffer
166  // Always make sure that it has size of at least one
167  if (receive_data_count == 0)
168  {
169  ++receive_data_count;
170  }
171  Haloed_eqns.resize(receive_data_count);
172  // Send the data between all the processors
173  MPI_Alltoallv(&send_data[0],
174  &send_n[0],
175  &send_displacement[0],
176  MPI_UNSIGNED,
177  &Haloed_eqns[0],
178  &Haloed_n[0],
180  MPI_UNSIGNED,
181  dist_pt->communicator_pt()->mpi_comm());
182 
183  // Finally, we translate the map of halo entries into the permanent
184  // storage
185  Halo_n.resize(n_proc, 0);
186  Halo_displacement.resize(n_proc, 0);
187 
188  // Loop over all the entries in the map
189  unsigned receive_haloed_count = 0;
190  for (int d = 0; d < n_proc; d++)
191  {
192  // Pointer to the map entry
193  std::map<unsigned, Vector<unsigned>>::iterator it =
194  halo_entries.find(d);
195  // If we don't have it in the map, skip
196  if (it == halo_entries.end())
197  {
198  Halo_displacement[d] = receive_haloed_count;
199  Halo_n[d] = 0;
200  }
201  else
202  {
203  Halo_displacement[d] = receive_haloed_count;
204  const int size_ = it->second.size();
205  Halo_n[d] = size_;
206  // Resize the equations to be sent
207  Halo_eqns.resize(receive_haloed_count + size_);
208  for (int i = 0; i < size_; i++)
209  {
210  Halo_eqns[receive_haloed_count + i] = it->second[i];
211  }
212  receive_haloed_count += size_;
213  }
214  }
215  }
216 #endif
217  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Vector< int > Haloed_n
Definition: double_vector_with_halo.h:67
Vector< int > Halo_displacement
Definition: double_vector_with_halo.h:84
Vector< int > Halo_n
Definition: double_vector_with_halo.h:80
LinearAlgebraDistribution * Distribution_pt
Store the distribution that was used to setup the halo scheme.
Definition: double_vector_with_halo.h:88
std::map< unsigned, unsigned > Local_index
Definition: double_vector_with_halo.h:59
Vector< int > Haloed_displacement
Definition: double_vector_with_halo.h:71
Vector< unsigned > Haloed_eqns
Definition: double_vector_with_halo.h:63
Vector< unsigned > Halo_eqns
Definition: double_vector_with_halo.h:76

References oomph::LinearAlgebraDistribution::communicator_pt(), oomph::LinearAlgebraDistribution::distributed(), oomph::LinearAlgebraDistribution::first_row(), Halo_displacement, Halo_eqns, Halo_n, Haloed_displacement, Haloed_eqns, Haloed_n, i, Local_index, oomph::OomphCommunicator::my_rank(), n, oomph::OomphCommunicator::nproc(), and oomph::LinearAlgebraDistribution::rank_of_global_row().

Member Function Documentation

◆ distribution_pt()

LinearAlgebraDistribution*& oomph::DoubleVectorHaloScheme::distribution_pt ( )
inline

Return the pointer to the distirbution used to setup the halo information

107  {
108  return Distribution_pt;
109  }

References Distribution_pt.

Referenced by oomph::Problem::global_dof_pt().

◆ local_index()

unsigned oomph::DoubleVectorHaloScheme::local_index ( const unsigned global_eqn)
inline

Return the local index associated with the global equation.

119  {
120  // Does the entry exist in the map
121  std::map<unsigned, unsigned>::iterator it = Local_index.find(global_eqn);
122  // If it does return it
123  if (it != Local_index.end())
124  {
125  return it->second;
126  }
127  // Otherwise throw an error
128  else
129  {
130  std::ostringstream error_stream;
131  error_stream << "Global equation " << global_eqn << " "
132  << "has not been set as halo\n";
133  throw OomphLibError(
134  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
135  return 0;
136  }
137  }
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References Local_index, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

Referenced by oomph::Problem::global_dof_pt(), and oomph::DoubleVectorWithHaloEntries::global_value().

◆ n_halo_values()

unsigned oomph::DoubleVectorHaloScheme::n_halo_values ( ) const
inline

Return the number of halo values.

100  {
101  return Local_index.size();
102  }

References Local_index.

◆ setup_halo_dofs()

void oomph::DoubleVectorHaloScheme::setup_halo_dofs ( const std::map< unsigned, double * > &  halo_data_pt,
Vector< double * > &  halo_dof_pt 
)

Function that sets up a vector of pointers to halo data, index using the scheme in Local_index

Function that sets up a vector of pointers to halo data, index using the scheme in Local_index. The first arguement is a map of pointers to all halo data index by the global equation number

228  {
229  // How many entries are there in the map
230  unsigned n_halo = Local_index.size();
231  // Resize the vector
232  halo_dof_pt.resize(n_halo);
233 
234  // Loop over all the entries in the map
235  for (std::map<unsigned, unsigned>::iterator it = Local_index.begin();
236  it != Local_index.end();
237  ++it)
238  {
239  // Find the pointer in the halo_data_pt map
240  std::map<unsigned, double*>::const_iterator it2 =
241  halo_data_pt.find(it->first);
242  // Did we find it
243  if (it2 != halo_data_pt.end())
244  {
245  // Now set the entry
246  halo_dof_pt[it->second] = it2->second;
247  }
248  else
249  {
250  std::ostringstream error_stream;
251  error_stream << "Global equation " << it->first
252  << " reqired as halo is not stored in halo_data_pt\n";
253 
254  throw OomphLibError(
255  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
256  }
257  }
258  }

References Local_index, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

Friends And Related Function Documentation

◆ DoubleVectorWithHaloEntries

friend class DoubleVectorWithHaloEntries
friend

The DoubleVectorWithHaloEntries should be able to access the private data.

Member Data Documentation

◆ Distribution_pt

LinearAlgebraDistribution* oomph::DoubleVectorHaloScheme::Distribution_pt
private

Store the distribution that was used to setup the halo scheme.

Referenced by distribution_pt().

◆ Halo_displacement

Vector<int> oomph::DoubleVectorHaloScheme::Halo_displacement
private

◆ Halo_eqns

Vector<unsigned> oomph::DoubleVectorHaloScheme::Halo_eqns
private

Storage for all the entries that are to be received from other processors (received_from_proc0,received_from_proc1,...received_from_procn)

Referenced by DoubleVectorHaloScheme(), oomph::DoubleVectorWithHaloEntries::sum_all_halo_and_haloed_values(), and oomph::DoubleVectorWithHaloEntries::synchronise().

◆ Halo_n

Vector<int> oomph::DoubleVectorHaloScheme::Halo_n
private

Storage for the number of entries to be received from each other processor

Referenced by DoubleVectorHaloScheme(), oomph::DoubleVectorWithHaloEntries::sum_all_halo_and_haloed_values(), and oomph::DoubleVectorWithHaloEntries::synchronise().

◆ Haloed_displacement

Vector<int> oomph::DoubleVectorHaloScheme::Haloed_displacement
private

Storage for the offsets of the haloed entries for each processor in the packed Haloed_eqns array

Referenced by DoubleVectorHaloScheme(), oomph::DoubleVectorWithHaloEntries::sum_all_halo_and_haloed_values(), and oomph::DoubleVectorWithHaloEntries::synchronise().

◆ Haloed_eqns

Vector<unsigned> oomph::DoubleVectorHaloScheme::Haloed_eqns
private

The haloed entries that will be sent in a format compatible with MPI_Alltoallv i.e. (send_to_proc0,send_to_proc1 ... send_to_procn)

Referenced by DoubleVectorHaloScheme(), oomph::DoubleVectorWithHaloEntries::sum_all_halo_and_haloed_values(), and oomph::DoubleVectorWithHaloEntries::synchronise().

◆ Haloed_n

Vector<int> oomph::DoubleVectorHaloScheme::Haloed_n
private

Storage for the number of haloed entries to be sent to each processor

Referenced by DoubleVectorHaloScheme(), oomph::DoubleVectorWithHaloEntries::sum_all_halo_and_haloed_values(), and oomph::DoubleVectorWithHaloEntries::synchronise().

◆ Local_index

std::map<unsigned, unsigned> oomph::DoubleVectorHaloScheme::Local_index
private

Storage for the translation scheme from global unknown to local index in the additional storage vector.

Referenced by oomph::DoubleVectorWithHaloEntries::build_halo_scheme(), DoubleVectorHaloScheme(), local_index(), n_halo_values(), and setup_halo_dofs().


The documentation for this class was generated from the following files: