double_vector_with_halo.h
Go to the documentation of this file.
1 // LIC// ====================================================================
2 // LIC// This file forms part of oomph-lib, the object-oriented,
3 // LIC// multi-physics finite-element library, available
4 // LIC// at http://www.oomph-lib.org.
5 // LIC//
6 // LIC// Copyright (C) 2006-2023 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 #ifndef OOMPH_DOUBLE_VECTOR_WITH_HALO_CLASS_HEADER
27 #define OOMPH_DOUBLE_VECTOR_WITH_HALO_CLASS_HEADER
28 
29 // Config header generated by autoconfig
30 #ifdef HAVE_CONFIG_H
31 #include <oomph-lib-config.h>
32 #endif
33 
34 #include <map>
35 #include "double_vector.h"
36 
37 namespace oomph
38 {
39  class DoubleVectorWithHaloEntries;
40 
41  //=====================================================================
42  /// A class that stores the halo/haloed entries required when
43  /// using a DoubleVectorWithHaloEntries.
44  /// This is a separate class so thay many different Vectors can share
45  /// the same object.
46  /// The constructor requires the distribution of the DoubleVector
47  /// (if you pass in a different distribution things will go badly wrong)
48  /// and a vector that specifies which GLOBAL eqn numbers are required
49  /// on each processor.
50  //=====================================================================
52  {
53  /// The DoubleVectorWithHaloEntries should be able to access the
54  /// private data.
56 
57  /// Storage for the translation scheme from global unknown
58  /// to local index in the additional storage vector.
59  std::map<unsigned, unsigned> Local_index;
60 
61  /// The haloed entries that will be sent in a format compatible
62  /// with MPI_Alltoallv i.e. (send_to_proc0,send_to_proc1 ... send_to_procn)
64 
65  /// Storage for the number of haloed entries to be sent to each
66  /// processor
68 
69  /// Storage for the offsets of the haloed entries for each processor
70  /// in the packed Haloed_eqns array
72 
73  /// Storage for all the entries that are to be received from
74  /// other processors
75  /// (received_from_proc0,received_from_proc1,...received_from_procn)
77 
78  /// Storage for the number of entries to be received from each
79  /// other processor
81 
82  /// Storage for the offsets of the processor data in the
83  /// receive buffer
85 
86 
87  /// Store the distribution that was used to setup the halo scheme
89 
90  public:
91  /// Constructor that sets up the required information communicating
92  /// between all processors. Requires two "all to all" communications.
93  /// Arguments are the distribution of the DoubleVector and a
94  /// Vector of global unknowns required on this processor.
96  const Vector<unsigned>& required_global_eqn);
97 
98  /// Return the number of halo values
99  inline unsigned n_halo_values() const
100  {
101  return Local_index.size();
102  }
103 
104  /// Return the pointer to the distirbution used to setup
105  /// the halo information
107  {
108  return Distribution_pt;
109  }
110 
111  /// Function that sets up a vector of pointers to halo
112  /// data, index using the scheme in Local_index
113  void setup_halo_dofs(const std::map<unsigned, double*>& halo_data_pt,
114  Vector<double*>& halo_dof_pt);
115 
116 
117  /// Return the local index associated with the global equation
118  inline unsigned local_index(const unsigned& global_eqn)
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  }
138  };
139 
140 
141  /// =====================================================================
142  /// An extension of DoubleVector that allows access to certain
143  /// global entries that are not stored locally. Synchronisation of these
144  /// values must be performed manually by calling the synchronise()
145  /// function. Synchronisation can only be from the haloed to the halo,
146  /// but the local halo entries can all be summed and stored in the
147  /// haloed value.
148  /// ======================================================================
150  {
151  /// Pointer to the lookup scheme that stores information about
152  /// on which processor the required information is haloed
154 
155  /// Vector of the halo values
157 
158  public:
159  /// Constructor for an uninitialized DoubleVectorWithHaloEntries
161 
162  /// Constructor. Assembles a DoubleVectorWithHaloEntries
163  /// with a prescribed
164  /// distribution. Additionally every entry can be set (with argument v -
165  /// defaults to 0).
167  const LinearAlgebraDistribution* const& dist_pt,
169  const double& v = 0.0)
170  : DoubleVector(dist_pt, v)
171  {
172  // construct the halo scheme
174  }
175 
176  /// Constructor. Assembles a DoubleVectorWithHaloEntries
177  /// with a prescribed
178  /// distribution. Additionally every entry can be set (with argument v -
179  /// defaults to 0).
181  const LinearAlgebraDistribution& dist,
183  const double& v = 0.0)
184  : DoubleVector(dist, v)
185  {
186  // construct the halo scheme
188  }
189 
190  /// Destructor
192 
193 
194  /// Copy constructor from any DoubleVector
196  : DoubleVector(new_vector)
197  {
198  // Build the appropriate halo scheme
199  this->build_halo_scheme(new_vector.halo_scheme_pt());
200  }
201 
202  /// Copy constructor from any DoubleVector
204  const DoubleVector& new_vector,
206  : DoubleVector(new_vector)
207  {
208  // Construct the halo scheme
210  }
211 
212  /// assignment operator
213  void operator=(const DoubleVectorWithHaloEntries& old_vector)
214  {
215  this->build(old_vector);
216  // Do some other stuff
217  this->build_halo_scheme(old_vector.halo_scheme_pt());
218  }
219 
220  /// Direct access to global entry
221  inline double& global_value(const unsigned& i)
222  {
223  // Only need to worry about the distributed case if
224  // we have compiled with MPI
225 #ifdef OOMPH_HAS_MPI
226  if (this->distributed())
227  {
228  const unsigned first_row_local = this->first_row();
229  const unsigned n_row_local = this->nrow_local();
230 
231  // If we are in range then just call the local value
232  if ((i >= first_row_local) && (i < first_row_local + n_row_local))
233  {
234  return (*this)[i - first_row_local];
235  }
236  // Otherwise the entry is not stored in the local processor
237  // and we must have haloed it
238  else
239  {
240 #ifdef PARANOID
241  if (Halo_scheme_pt == 0)
242  {
243  std::ostringstream error_stream;
244  error_stream
245  << "Halo data requested, but no halo scheme has been setup\n"
246  << "You should call this->build_halo_scheme(halo_scheme_pt).\n"
247  << "You may wish to setup the scheme for the Problem using \n"
248  << "Problem::setup_dof_halo_scheme()\n";
249 
250  throw OomphLibError(error_stream.str(),
251  OOMPH_CURRENT_FUNCTION,
252  OOMPH_EXCEPTION_LOCATION);
253  }
254 #endif
256  }
257  }
258  // If not distributed the global entry is
259  // the local entry
260  else
261 #endif
262  {
263  return (*this)[i];
264  }
265  }
266 
267  /// Direct access to the global entry (const version)
268  const double& global_value(const unsigned& i) const
269  {
270  // Only need to worry about the distributed case if
271  // we have compiled with MPI
272 #ifdef OOMPH_HAS_MPI
273  if (this->distributed())
274  {
275  const unsigned first_row_local = this->first_row();
276  const unsigned n_row_local = this->nrow_local();
277 
278  // If we are in range then just call the local value
279  if ((i >= first_row_local) && (i < first_row_local + n_row_local))
280  {
281  return (*this)[i - first_row_local];
282  }
283  // Otherwise the entry is not stored in the local processor
284  // and we must have haloed it
285  else
286  {
287 #ifdef PARANOID
288  if (Halo_scheme_pt == 0)
289  {
290  std::ostringstream error_stream;
291  error_stream
292  << "Halo data requested, but no halo scheme has been setup\n"
293  << "You should call this->build_halo_scheme(halo_scheme_pt).\n"
294  << "You may wish to setup the scheme for the Problem using \n"
295  << "Problem::setup_dof_halo_scheme()\n";
296 
297  throw OomphLibError(error_stream.str(),
298  OOMPH_CURRENT_FUNCTION,
299  OOMPH_EXCEPTION_LOCATION);
300  }
301 #endif
303  }
304  }
305  // If not distributed the global entry is
306  // the local entry
307  else
308 #endif
309  {
310  return (*this)[i];
311  }
312  }
313 
314 
315  /// Synchronise the halo data
316  void synchronise();
317 
318  /// Sum all the data, store in the master (haloed) data and then
319  /// synchronise
321 
322  /// Access function for halo scheme
324  {
325  return Halo_scheme_pt;
326  }
327 
328  /// Access function for halo scheme (const version)
330  {
331  return Halo_scheme_pt;
332  }
333 
334 
335  /// Construct the halo scheme and storage for the halo
336  /// data
338  };
339 
340 } // namespace oomph
341 #endif
cstr elem_len * i
Definition: cfortran.h:603
bool distributed() const
distribution is serial or distributed
unsigned nrow_local() const
access function for the num of local rows on this processor.
unsigned first_row() const
access function for the first row on this processor
A class that stores the halo/haloed entries required when using a DoubleVectorWithHaloEntries....
Vector< int > Haloed_n
Storage for the number of haloed entries to be sent to each processor.
LinearAlgebraDistribution *& distribution_pt()
Return the pointer to the distirbution used to setup the halo information.
Vector< int > Halo_displacement
Storage for the offsets of the processor data in the receive buffer.
Vector< int > Halo_n
Storage for the number of entries to be received from each other processor.
unsigned n_halo_values() const
Return the number of halo values.
LinearAlgebraDistribution * Distribution_pt
Store the distribution that was used to setup the halo scheme.
std::map< unsigned, unsigned > Local_index
Storage for the translation scheme from global unknown to local index in the additional storage vecto...
Vector< int > Haloed_displacement
Storage for the offsets of the haloed entries for each processor in the packed Haloed_eqns array.
void 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.
Vector< unsigned > Haloed_eqns
The haloed entries that will be sent in a format compatible with MPI_Alltoallv i.e....
DoubleVectorHaloScheme(LinearAlgebraDistribution *const &dist_pt, const Vector< unsigned > &required_global_eqn)
Constructor that sets up the required information communicating between all processors....
unsigned local_index(const unsigned &global_eqn)
Return the local index associated with the global equation.
Vector< unsigned > Halo_eqns
Storage for all the entries that are to be received from other processors (received_from_proc0,...
===================================================================== An extension of DoubleVector th...
DoubleVectorWithHaloEntries()
Constructor for an uninitialized DoubleVectorWithHaloEntries.
DoubleVectorWithHaloEntries(const LinearAlgebraDistribution *const &dist_pt, DoubleVectorHaloScheme *const &halo_scheme_pt=0, const double &v=0.0)
Constructor. Assembles a DoubleVectorWithHaloEntries with a prescribed distribution....
void build_halo_scheme(DoubleVectorHaloScheme *const &halo_scheme_pt)
Construct the halo scheme and storage for the halo data.
DoubleVectorWithHaloEntries(const LinearAlgebraDistribution &dist, DoubleVectorHaloScheme *const &halo_scheme_pt=0, const double &v=0.0)
Constructor. Assembles a DoubleVectorWithHaloEntries with a prescribed distribution....
DoubleVectorWithHaloEntries(const DoubleVector &new_vector, DoubleVectorHaloScheme *const &halo_scheme_pt=0)
Copy constructor from any DoubleVector.
DoubleVectorHaloScheme *const & halo_scheme_pt() const
Access function for halo scheme (const version)
DoubleVectorHaloScheme * Halo_scheme_pt
Pointer to the lookup scheme that stores information about on which processor the required informatio...
const double & global_value(const unsigned &i) const
Direct access to the global entry (const version)
void synchronise()
Synchronise the halo data.
void sum_all_halo_and_haloed_values()
Sum all the data, store in the master (haloed) data and then synchronise.
DoubleVectorHaloScheme *& halo_scheme_pt()
Access function for halo scheme.
double & global_value(const unsigned &i)
Direct access to global entry.
DoubleVectorWithHaloEntries(const DoubleVectorWithHaloEntries &new_vector)
Copy constructor from any DoubleVector.
void operator=(const DoubleVectorWithHaloEntries &old_vector)
assignment operator
Vector< double > Halo_value
Vector of the halo values.
A vector in the mathematical sense, initially developed for linear algebra type applications....
Definition: double_vector.h:58
void build(const DoubleVector &old_vector)
Just copys the argument DoubleVector.
Describes the distribution of a distributable linear algebra type object. Typically this is a contain...
An OomphLibError object which should be thrown when an run-time error is encountered....
//////////////////////////////////////////////////////////////////// ////////////////////////////////...