map_matrix.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-2022 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_MAP_MATRIX_HEADER
27 #define OOMPH_MAP_MATRIX_HEADER
28 
29 
30 // Config header generated by autoconfig
31 #ifdef HAVE_CONFIG_H
32 #include <oomph-lib-config.h>
33 #endif
34 
35 
36 #ifdef OOMPH_HAS_MPI
37 #include "mpi.h"
38 #endif
39 
40 #include <map>
41 
42 // oomph-lib headers
43 #include "Vector.h"
44 #include "oomph_utilities.h"
45 
46 namespace oomph
47 {
48  //================================================================
106  //================================================================
107  template<class KEY_TYPE_ROW, class KEY_TYPE_COL, class VALUE_TYPE>
109  {
110  public:
113 
115  void operator=(const MapMatrixMixed&) = delete;
116 
118  typedef std::map<KEY_TYPE_COL, VALUE_TYPE> InnerMapMixed;
119 
121  typedef typename InnerMapMixed::iterator InnerMixedIt;
122 
124  typedef typename InnerMapMixed::const_iterator ConstInnerMixedIt;
125 
127  typedef std::map<KEY_TYPE_ROW, std::map<KEY_TYPE_COL, VALUE_TYPE>*>
129 
131  typedef typename OuterMapMixed::iterator OuterMixedIt;
132 
134  typedef typename OuterMapMixed::const_iterator ConstOuterMixedIt;
135 
136 
140  {
141  // Step through the row pointers
142  for (ConstOuterMixedIt it = map_mat.Row_pt.begin();
143  it != map_mat.Row_pt.end();
144  it++)
145  {
146  // Is the row pointer nonzero, i.e. are there any entries in this row?
147  if (it->second != 0)
148  {
149  // Identify the map that holds the entries in this row:
150  InnerMapMixed inner_map = *(it->second);
151 
152  // Loop over entries in the row
153  for (ConstInnerMixedIt it2 = inner_map.begin();
154  it2 != inner_map.end();
155  it2++)
156  {
157  // If the entry is nonzero: Copy
158  if (it2->second != 0)
159  {
160  // key1, key2, value
161  (*this)(it->first, it2->first) = it2->second;
162  }
163  }
164  }
165  }
166  }
167 
168 
170  void copy_column(const KEY_TYPE_COL& j,
171  std::map<KEY_TYPE_ROW, VALUE_TYPE>& copied_map)
172  {
173  // Step through the row pointers
174  for (OuterMixedIt it = Row_pt.begin(); it != Row_pt.end(); it++)
175  {
176  // Is the row pointer nonzero, i.e. are there any entries in this row?
177  if (it->second != 0)
178  {
179  // Identify the map that holds the entries in this row:
180  InnerMapMixed inner_map = *(it->second);
181  // If the desired column of the inner map is non-zero
182  if (inner_map[j] != 0)
183  {
184  // Set the value of the copied map to be the desired column of the
185  // inner map
186  copied_map[it->first] = inner_map[j];
187  }
188  }
189  }
190  }
191 
192 
194  virtual ~MapMatrixMixed()
195  {
196  // Step through the pointers to row maps
197  for (OuterMixedIt it = Row_pt.begin(); it != Row_pt.end(); it++)
198  {
199  // Is the row pointer nonzero, i.e. are there any entries in this row?
200  if (it->second != 0)
201  {
202  // it->second is the stored object
203  delete it->second;
204  }
205  }
206  }
207 
209  void clear()
210  {
211  // Step through the pointers to row maps
212  for (OuterMixedIt it = Row_pt.begin(); it != Row_pt.end(); it++)
213  {
214  // Is the row pointer nonzero, i.e. are there any entries in this row?
215  if (it->second != 0)
216  {
217  // it->second is the stored object: a map which can be cleared!
218  it->second->clear();
219  }
220  }
221  }
222 
223 
227  VALUE_TYPE& operator()(const KEY_TYPE_ROW& i, const KEY_TYPE_COL& j)
228  {
229  return *entry_pt(i, j);
230  }
231 
236  VALUE_TYPE get(const KEY_TYPE_ROW& i, const KEY_TYPE_COL& j) const
237  {
238  if (Row_pt.count(i) > 0)
239  {
240  // Get the pointer to the row and check the j key
241  InnerMapMixed* inner_map_mixed_pt = Row_pt.find(i)->second;
242  if (inner_map_mixed_pt->count(j) > 0)
243  {
244  return inner_map_mixed_pt->find(j)->second;
245  }
246  else
247  {
248  return VALUE_TYPE(0);
249  }
250  }
251  else
252  {
253  // The key does not exist, return VALUE_TYPE(0)
254  return VALUE_TYPE(0);
255  }
256  }
257 
258 
262  void output(std::ostream& outfile)
263  {
264  // NOTE:
265  //------
266  // map.first = key
267  // map.second = value
268 
269  // Step through the row pointers
270  for (OuterMixedIt it = Row_pt.begin(); it != Row_pt.end(); it++)
271  {
272  // Is the row pointer nonzero, i.e. are there any entries in this row?
273  if (it->second != 0)
274  {
275  // Identify the map that holds the entries in this row:
276  InnerMapMixed inner_map = *(it->second);
277 
278  // Loop over entries in the row
279  for (InnerMixedIt it2 = inner_map.begin(); it2 != inner_map.end();
280  it2++)
281  {
282  // If the entry is nonzero: Doc
283  if (it2->second != 0)
284  {
285  // Output key1, key2, value
286  outfile << it->first << " " << it2->first << " " << it2->second
287  << std::endl;
288  }
289  }
290  }
291  }
292  }
293 
295  unsigned long nnz()
296  {
297  // Initialise counter for # of nonzero entries
298  unsigned long count = 0;
299 
300  // Step through the row pointers
301  for (OuterMixedIt it = Row_pt.begin(); it != Row_pt.end(); it++)
302  {
303  // Is the row pointer nonzero, i.e. are there any entries in this row?
304  if (it->second != 0)
305  {
306  // Identify the map that holds the entries in this row:
307  InnerMapMixed inner_map = *(it->second);
308 
309  // Loop over entries in the row
310  for (InnerMixedIt it2 = inner_map.begin(); it2 != inner_map.end();
311  it2++)
312  {
313  // If the entry is nonzero: Increment counter
314  if (it2->second != 0)
315  {
316  count++;
317  }
318  }
319  }
320  }
321  return count;
322  }
323 
325  unsigned long nnz() const
326  {
327  // Initialise counter for # of nonzero entries
328  unsigned long count = 0;
329 
330  // Step through the row pointers
331  for (ConstOuterMixedIt it = Row_pt.begin(); it != Row_pt.end(); it++)
332  {
333  // Is the row pointer nonzero, i.e. are there any entries in this row?
334  if (it->second != 0)
335  {
336  // Identify the map that holds the entries in this row:
337  InnerMapMixed inner_map = *(it->second);
338 
339  // Loop over entries in the row
340  for (ConstInnerMixedIt it2 = inner_map.begin();
341  it2 != inner_map.end();
342  it2++)
343  {
344  // If the entry is nonzero: Increment counter
345  if (it2->second != 0)
346  {
347  count++;
348  }
349  }
350  }
351  }
352  return count;
353  }
354 
355 
357  unsigned long size()
358  {
359  // Initialise counter for # of nonzero entries
360  unsigned long count = 0;
361 
362  // Step through the row pointers
363  for (OuterMixedIt it = Row_pt.begin(); it != Row_pt.end(); it++)
364  {
365  // Is the row pointer nonzero, i.e. are there any entries in this row?
366  if (it->second != 0)
367  {
368  // Identify the map that holds the entries in this row:
369  InnerMapMixed inner_map = *(it->second);
370 
371  // Loop over all (!) entries in the row (incl. zero ones!)
372  for (InnerMixedIt it2 = inner_map.begin(); it2 != inner_map.end();
373  it2++)
374  {
375  count++;
376  }
377  }
378  }
379  return count;
380  }
381 
383  unsigned long size() const
384  {
385  // Initialise counter for # of nonzero entries
386  unsigned long count = 0;
387 
388  // Step through the row pointers
389  for (ConstOuterMixedIt it = Row_pt.begin(); it != Row_pt.end(); it++)
390  {
391  // Is the row pointer nonzero, i.e. are there any entries in this row?
392  if (it->second != 0)
393  {
394  // Identify the map that holds the entries in this row:
395  InnerMapMixed inner_map = *(it->second);
396 
397  // Loop over all (!) entries in the row (incl. zero ones!)
398  for (ConstInnerMixedIt it2 = inner_map.begin();
399  it2 != inner_map.end();
400  it2++)
401  {
402  count++;
403  }
404  }
405  }
406  return count;
407  }
408 
409 
410  protected:
412  VALUE_TYPE* entry_pt(const KEY_TYPE_ROW& i, const KEY_TYPE_COL& j)
413  {
414  // There's not a single entry in this row: Entry must be zero.
415  if (Row_pt[i] == 0)
416  {
417  // Create row and entry in row and set the value to zero
418  Row_pt[i] = new std::map<KEY_TYPE_COL, VALUE_TYPE>;
419  (*Row_pt[i])[j] = VALUE_TYPE(0);
420  return &(*Row_pt[i])[j];
421  }
422  // Simply return pointer to existing entry
423  else
424  {
425  return &(*Row_pt[i])[j];
426  }
427  }
428 
429 
432  std::map<KEY_TYPE_ROW, std::map<KEY_TYPE_COL, VALUE_TYPE>*> Row_pt;
433  };
434 
435 
439 
440 
441  //================================================================
505  //================================================================
506  template<class KEY_TYPE, class VALUE_TYPE>
507  class MapMatrix : public MapMatrixMixed<KEY_TYPE, KEY_TYPE, VALUE_TYPE>
508  {
509  public:
512 
514  typedef std::map<KEY_TYPE, VALUE_TYPE> InnerMap;
515 
517  typedef typename InnerMap::iterator InnerIt;
518 
520  typedef typename InnerMap::const_iterator ConstInnerIt;
521 
523  typedef std::map<KEY_TYPE, std::map<KEY_TYPE, VALUE_TYPE>*> OuterMap;
524 
526  typedef typename OuterMap::iterator OuterIt;
527 
529  typedef typename OuterMap::const_iterator ConstOuterIt;
530 
533  {
534  // Step through the row pointers
535  for (ConstOuterIt it = map_mat.Row_pt.begin(); it != map_mat.Row_pt.end();
536  it++)
537  {
538  // Is the row pointer nonzero, i.e. are there any entries in this row?
539  if (it->second != 0)
540  {
541  // Identify the map that holds the entries in this row:
542  InnerMap inner_map = *(it->second);
543 
544  // Loop over entries in the row
545  for (ConstInnerIt it2 = inner_map.begin(); it2 != inner_map.end();
546  it2++)
547  {
548  // If the entry is nonzero: Copy
549  if (it2->second != 0)
550  {
551  (*this)(it->first, it2->first) = it2->second;
552  }
553  }
554  }
555  }
556  }
557 
559  void operator=(const MapMatrix&) = delete;
560  };
561 
562 } // namespace oomph
563 
564 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Definition: map_matrix.h:109
InnerMapMixed::const_iterator ConstInnerMixedIt
Typedef to keep the code more readable const version.
Definition: map_matrix.h:124
void operator=(const MapMatrixMixed &)=delete
Broken assignment operator.
unsigned long nnz()
Work out number of non-‘zero’ entries.
Definition: map_matrix.h:295
void copy_column(const KEY_TYPE_COL &j, std::map< KEY_TYPE_ROW, VALUE_TYPE > &copied_map)
Copy a single column into its own map.
Definition: map_matrix.h:170
MapMatrixMixed()
Default (empty) constructor.
Definition: map_matrix.h:112
unsigned long nnz() const
Work out number of non-‘zero’ entries, const version.
Definition: map_matrix.h:325
std::map< KEY_TYPE_COL, VALUE_TYPE > InnerMapMixed
Typedef to keep the code more readable.
Definition: map_matrix.h:118
virtual ~MapMatrixMixed()
Destructor.
Definition: map_matrix.h:194
InnerMapMixed::iterator InnerMixedIt
Typedef to keep the code more readable.
Definition: map_matrix.h:121
VALUE_TYPE * entry_pt(const KEY_TYPE_ROW &i, const KEY_TYPE_COL &j)
Return pointer to entry.
Definition: map_matrix.h:412
void output(std::ostream &outfile)
Definition: map_matrix.h:262
OuterMapMixed::const_iterator ConstOuterMixedIt
Typedef to keep the code more readable const version.
Definition: map_matrix.h:134
void clear()
Wipe all entries.
Definition: map_matrix.h:209
std::map< KEY_TYPE_ROW, std::map< KEY_TYPE_COL, VALUE_TYPE > * > Row_pt
Definition: map_matrix.h:432
VALUE_TYPE & operator()(const KEY_TYPE_ROW &i, const KEY_TYPE_COL &j)
Definition: map_matrix.h:227
unsigned long size() const
Work out total number of entries const version.
Definition: map_matrix.h:383
MapMatrixMixed(const MapMatrixMixed< KEY_TYPE_ROW, KEY_TYPE_COL, VALUE_TYPE > &map_mat)
Copy constructor.
Definition: map_matrix.h:138
OuterMapMixed::iterator OuterMixedIt
Typedef to keep the code more readable.
Definition: map_matrix.h:131
VALUE_TYPE get(const KEY_TYPE_ROW &i, const KEY_TYPE_COL &j) const
Definition: map_matrix.h:236
unsigned long size()
Work out total number of entries.
Definition: map_matrix.h:357
std::map< KEY_TYPE_ROW, std::map< KEY_TYPE_COL, VALUE_TYPE > * > OuterMapMixed
Typedef to keep the code more readable.
Definition: map_matrix.h:128
Definition: map_matrix.h:508
std::map< KEY_TYPE, std::map< KEY_TYPE, VALUE_TYPE > * > OuterMap
Typedef to keep the code more readable.
Definition: map_matrix.h:523
InnerMap::iterator InnerIt
Typedef to keep the code more readable.
Definition: map_matrix.h:517
MapMatrix()
Default (empty) constructor.
Definition: map_matrix.h:511
OuterMap::const_iterator ConstOuterIt
Typedef to keep the code more readable.
Definition: map_matrix.h:529
OuterMap::iterator OuterIt
Typedef to keep the code more readable.
Definition: map_matrix.h:526
InnerMap::const_iterator ConstInnerIt
Typedef to keep the code more readable.
Definition: map_matrix.h:520
MapMatrix(const MapMatrix< KEY_TYPE, VALUE_TYPE > &map_mat)
Copy constructor.
Definition: map_matrix.h:532
void operator=(const MapMatrix &)=delete
Broken assignment operator.
std::map< KEY_TYPE, VALUE_TYPE > InnerMap
Typedef to keep the code more readable.
Definition: map_matrix.h:511
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2