preconditioner_array.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 //Include guards
31 #ifndef OOMPH_PRECONDITION_ARRAY_HEADER
32 #define OOMPH_PRECONDITION_ARRAY_HEADER
33 
34 // Config header generated by autoconfig
35 #ifdef HAVE_CONFIG_H
36  #include <oomph-lib-config.h>
37 #endif
38 
39 // oomph-lib includes
40 #include "Vector.h"
41 #include "double_vector.h"
42 #include "matrices.h"
43 #include "preconditioner.h"
44 
45 
46 // Preconditioner array is only really possible and useful if we have MPI
47 // (and it uses a lot of MPI functions in the .cc file so changing that
48 // would be hard). So if we don't have MPI just define a dummy
49 // implementation that throws an error if you try to use it.
50 #ifndef OOMPH_HAS_MPI
51 namespace oomph
52 {
54  {
55  public:
58  const OomphCommunicator* comm_pt)
59  {
60  throw OomphLibError("PreconditionerArray requires MPI",
61  OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
62  }
63 
66  {
67  throw OomphLibError("PreconditionerArray requires MPI",
68  OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
69  }
70  };
71 }
72 
73 // Otherwise (if we have MPI do the real implementation)
74 #else
75 
76 #include "mpi.h"
77 
78 
79 namespace oomph
80 {
81 
82 //=============================================================================
83 /// \short PreconditionerArray -
84 /// NOTE - first implementation, a number of assumptions / simplifications
85 /// were made:
86 /// 1. Only works with CRDoubleMatrices
87 /// 2. The number of processors must be greater than the number of
88 /// preconditioners
89 /// 3. Currently only very crude load balancing - each preconditioner will
90 /// be setup and applied with the same number of processors (or as near to
91 /// as possible to the same number of processors)
92 /// 4. This class will, at the appropriate time, delete the all the
93 /// Preconditioners passed setup_preconditioners(...)
94 /// 5. (but) Deletion of matrices passed to setup_preconditioners(...) is NOT
95 /// performed by this class
96 /// 6. It is assumed that preconditioners do not require access to matrix
97 /// once setup(...) is called
98 /// 7. The matrix on the subset of processors will be the same type
99 /// (distributed or global) as the matrix passed to
100 /// setup_preconditioners(...)
101 /// 8. If the matrix is a distributed matrix - it will be assembled with
102 /// a uniform distribution on the subset of processors.
103 //=============================================================================
104  class PreconditionerArray
105  {
106 
107  public:
108 
109  /// Constructor (empty)
112  {
113  Method = 0;
114  Nprec = 0;
115  };
116 
117  /// Broken copy constructor
119  {
120  BrokenCopy::broken_copy("PreconditionerArray");
121  }
122 
123  /// Broken assignment operator
125  {
126  BrokenCopy::broken_assign("PreconditionerArray");
127  }
128 
129  /// Destructor (empty)
131  {
132  this->clean_up_memory();
133  }
134 
135  /// \short Setup the preconditioners. Sets up each preconditioner in the
136  /// array for the corresponding matrix in the vector matrix_pt.
137  /// The number of preconditioners in the array is taken to be the length of
138  /// prec_pt
139  /// The preconditioners that are not used on this processor are deleted.
141  Vector<Preconditioner*> prec_pt,
142  const OomphCommunicator* comm_pt);
143 
144  /// \short Applies each preconditioner to the corresponding vector in
145  /// r and z
148 
149  /// \short Clean up memory.
151  {
152  // delete the preconditioner pt
153  delete Preconditioner_pt;
154  Preconditioner_pt = 0;
155 
156  // delete the communicators
157  delete Global_communicator_pt;
159  delete Local_communicator_pt;
161 
162  // clear vectors
163  First_row_for_proc.clear();
164  Nrow_local_for_proc.clear();
165  First_row_from_proc.clear();
166  Nrow_local_from_proc.clear();
167  First_proc_for_prec.clear();
168  Nproc_for_prec.clear();
169 
170  // zero
171  Color = 0;
172 
173 #ifdef PARANOID
174  // delete PARANOID check distribution pts
175  for (unsigned i = 0;i < Nprec; i++)
176  {
177  delete Distribution_pt[i];
178  }
179  Distribution_pt.resize(0);
180 #endif
181  }
182 
183  // access function to Method
184  unsigned& method() { return Method; }
185 
186  private:
187 
188  /// \short helper method for computing the MPI_Isend and MPI_Irecv tags
189  int compute_tag(const int& nproc, const int& source, const int& dest,
190  const int& type)
191  {
192  return source + (nproc * dest) + (nproc * nproc * type);
193  }
194 
195  /// \short the number of preconditioner in the array
196  unsigned Nprec;
197 
198  /// The pointer to the local preconditioner on this processor
200 
201  /// \short The first_row component of the distribution of the processors
202  /// over the preconditioners
204 
205  /// \short The nrow_local component of the distribution of the processors
206  /// over the preconditioners
208 
209  /// \short Storage (indexed [i][j]) for the first row that will be sent
210  /// from this processor to processor j for preconditioner i
212 
213  /// \short Storage (indexed [i][j]) for the nrow_local that will be sent
214  /// from this processor to processor j for preconditioner i
216 
217  /// \short Storage (indexed [i][j]) for the first row that will be received
218  /// by this processor from processor j for preconditioner i
220 
221  /// \short Storage (indexed [i][j]) for the nrow_local that will be
222  /// received by this processor from processor j for preconditioner i
224 
225  /// the Color of this processor (or the preconditioner number)
226  unsigned Color;
227 
228  /// pointer to the global communicator for this preconditioner array
230 
231  /// Vector of communicators for the preconditioners
233 
234 #ifdef PARANOID
235  // Vector of distribution of each preconditioner - for PARANOID checks only
237 #endif
238 
239  /// \short the communication method in the setup_preconditioners(...) method
240  /// 1. Non-blocking Send with Blocking Recv
241  /// 2. MPI_Datatypes with Non-blocking sends and receives
242  unsigned Method;
243 
244  };//PreconditionerArray
245 }
246 
247 // End of "if we have MPI"
248 #endif
249 
250 // End of include guard
251 #endif
PreconditionerArray(const PreconditionerArray &)
Broken copy constructor.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
unsigned Method
the communication method in the setup_preconditioners(...) method
Vector< unsigned > Nproc_for_prec
The nrow_local component of the distribution of the processors over the preconditioners.
cstr elem_len * i
Definition: cfortran.h:607
unsigned Color
the Color of this processor (or the preconditioner number)
int compute_tag(const int &nproc, const int &source, const int &dest, const int &type)
helper method for computing the MPI_Isend and MPI_Irecv tags
Preconditioner * Preconditioner_pt
The pointer to the local preconditioner on this processor.
PreconditionerArray - NOTE - first implementation, a number of assumptions / simplifications were mad...
void setup_preconditioners(Vector< CRDoubleMatrix *> matrix_pt, Vector< Preconditioner *> prec_pt, const OomphCommunicator *comm_pt)
Vector< Vector< unsigned > > First_row_for_proc
Storage (indexed [i][j]) for the first row that will be sent from this processor to processor j for p...
OomphCommunicator * Local_communicator_pt
Vector of communicators for the preconditioners.
Vector< LinearAlgebraDistribution * > Distribution_pt
PreconditionerArray()
Constructor (empty)
Vector< unsigned > First_proc_for_prec
The first_row component of the distribution of the processors over the preconditioners.
OomphCommunicator * Global_communicator_pt
pointer to the global communicator for this preconditioner array
void clean_up_memory()
Clean up memory.
~PreconditionerArray()
Destructor (empty)
void operator=(const PreconditionerArray &)
Broken assignment operator.
Preconditioner base class. Gives an interface to call all other preconditioners through and stores th...
Vector< Vector< unsigned > > Nrow_local_for_proc
Storage (indexed [i][j]) for the nrow_local that will be sent from this processor to processor j for ...
Vector< Vector< unsigned > > First_row_from_proc
Storage (indexed [i][j]) for the first row that will be received by this processor from processor j f...
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
Vector< Vector< unsigned > > Nrow_local_from_proc
Storage (indexed [i][j]) for the nrow_local that will be received by this processor from processor j ...
void solve_preconditioners(const Vector< DoubleVector > &r, Vector< DoubleVector > &z)
Applies each preconditioner to the corresponding vector in r and z.
unsigned Nprec
the number of preconditioner in the array
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
Definition: communicator.h:57