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