Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BlockMatrix.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // For more information, please see: http://www.nektar.info
4 //
5 // The MIT License
6 //
7 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
8 // Department of Aeronautics, Imperial College London (UK), and Scientific
9 // Computing and Imaging Institute, University of Utah (USA).
10 //
11 // License for the specific language governing rights and limitations under
12 // Permission is hereby granted, free of charge, to any person obtaining a
13 // copy of this software and associated documentation files (the "Software"),
14 // to deal in the Software without restriction, including without limitation
15 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 // and/or sell copies of the Software, and to permit persons to whom the
17 // Software is furnished to do so, subject to the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be included
20 // in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 // DEALINGS IN THE SOFTWARE.
29 //
30 // Description:
31 //
32 ///////////////////////////////////////////////////////////////////////////////
33 
37 
38 
39 namespace Nektar
40 {
41  template<typename DataType, typename InnerMatrixType>
42  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::NekMatrix(MatrixStorage type) :
43  BaseType(0,0),
44  m_data(),
45  m_rowSizes(),
46  m_columnSizes(),
47  m_storageSize(),
48  m_numberOfBlockRows(0),
49  m_numberOfBlockColumns(0),
50  m_storageType(type)
51  {
52  }
53 
54  template<typename DataType, typename InnerMatrixType>
55  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::NekMatrix(unsigned int numberOfBlockRows, unsigned int numberOfBlockColumns,
56  unsigned int rowsPerBlock, unsigned int columnsPerBlock,
57  MatrixStorage type) :
58  BaseType(numberOfBlockRows*rowsPerBlock, numberOfBlockColumns*columnsPerBlock),
59  m_data(),
60  m_rowSizes(numberOfBlockRows),
61  m_columnSizes(numberOfBlockColumns),
62  m_storageSize(0),
63  m_numberOfBlockRows(numberOfBlockRows),
64  m_numberOfBlockColumns(numberOfBlockColumns),
65  m_storageType(type)
66  {
67  m_storageSize = GetRequiredStorageSize();
68  m_data = Array<OneD, boost::shared_ptr<InnerType> >(m_storageSize, boost::shared_ptr<InnerType>());
69  for(unsigned int i = 1; i <= numberOfBlockRows; ++i)
70  {
71  m_rowSizes[i-1] = i*rowsPerBlock-1;
72  }
73 
74  for(unsigned int i = 1; i <= numberOfBlockColumns; ++i)
75  {
76  m_columnSizes[i-1] = i*columnsPerBlock-1;
77  }
78  }
79 
80  template<typename DataType, typename InnerMatrixType>
81  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::NekMatrix(unsigned int numberOfBlockRows, unsigned int numberOfBlockColumns,
82  const unsigned int* rowsPerBlock, const unsigned int* columnsPerBlock,
83  MatrixStorage type) :
84  BaseType(std::accumulate(rowsPerBlock, rowsPerBlock + numberOfBlockRows, 0),
85  std::accumulate(columnsPerBlock, columnsPerBlock + numberOfBlockColumns, 0)),
86  m_data(),
87  m_rowSizes(numberOfBlockRows),
88  m_columnSizes(numberOfBlockColumns),
89  m_storageSize(0),
90  m_numberOfBlockRows(numberOfBlockRows),
91  m_numberOfBlockColumns(numberOfBlockColumns),
92  m_storageType(type)
93  {
94  m_storageSize = GetRequiredStorageSize();
95  m_data = Array<OneD, boost::shared_ptr<InnerType> >(m_storageSize, boost::shared_ptr<InnerType>());
96  Initialize(rowsPerBlock, columnsPerBlock);
97  }
98 
99  template<typename DataType, typename InnerMatrixType>
100  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::NekMatrix(unsigned int numberOfBlockRows, unsigned int numberOfBlockColumns,
101  const Array<OneD, const unsigned int>& rowsPerBlock, const Array<OneD, const unsigned int>& columnsPerBlock,
102  MatrixStorage type) :
103  BaseType(std::accumulate(rowsPerBlock.data(), rowsPerBlock.data() + numberOfBlockRows, 0),
104  std::accumulate(columnsPerBlock.data(), columnsPerBlock.data() + numberOfBlockColumns, 0)),
105  m_data(),
106  m_rowSizes(numberOfBlockRows),
107  m_columnSizes(numberOfBlockColumns),
108  m_storageSize(0),
109  m_numberOfBlockRows(numberOfBlockRows),
110  m_numberOfBlockColumns(numberOfBlockColumns),
111  m_storageType(type)
112  {
113  m_storageSize = GetRequiredStorageSize();
114  m_data = Array<OneD, boost::shared_ptr<InnerType> >(m_storageSize, boost::shared_ptr<InnerType>());
115  Initialize(rowsPerBlock.data(), columnsPerBlock.data());
116  }
117 
118  template<typename DataType, typename InnerMatrixType>
119  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::NekMatrix(const Array<OneD, const unsigned int>& rowsPerBlock,
120  const Array<OneD, const unsigned int>& columnsPerBlock,
121  MatrixStorage type) :
122  BaseType(std::accumulate(rowsPerBlock.begin(), rowsPerBlock.end(), 0),
123  std::accumulate(columnsPerBlock.begin(), columnsPerBlock.end(), 0)),
124  m_data(),
125  m_rowSizes(rowsPerBlock.num_elements()),
126  m_columnSizes(columnsPerBlock.num_elements()),
127  m_storageSize(0),
128  m_numberOfBlockRows(rowsPerBlock.num_elements()),
129  m_numberOfBlockColumns(columnsPerBlock.num_elements()),
130  m_storageType(type)
131  {
132  m_storageSize = GetRequiredStorageSize();
133  m_data = Array<OneD, boost::shared_ptr<InnerType> >(m_storageSize, boost::shared_ptr<InnerType>());
134  Initialize(rowsPerBlock.data(), columnsPerBlock.data());
135  }
136 
137  template<typename DataType, typename InnerMatrixType>
138  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::NekMatrix(const NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>& rhs) :
139  BaseType(rhs),
140  m_data(rhs.m_data.num_elements()),
141  m_rowSizes(rhs.m_rowSizes),
142  m_columnSizes(rhs.m_columnSizes),
143  m_storageSize(rhs.m_storageSize),
144  m_numberOfBlockRows(rhs.m_numberOfBlockRows),
145  m_numberOfBlockColumns(rhs.m_numberOfBlockColumns),
146  m_storageType(rhs.m_storageType)
147  {
148  for(unsigned int i = 0; i < rhs.m_data.num_elements(); ++i)
149  {
150  m_data[i] = InnerType::CreateWrapper(rhs.m_data[i]);
151  }
152  }
153 
154  template<typename DataType, typename InnerMatrixType>
155  unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetRequiredStorageSize() const
156  {
157  return BaseType::GetRequiredStorageSize(this->GetStorageType(), this->GetNumberOfBlockRows(),
158  this->GetNumberOfBlockColumns());
159  }
160 
161  template<typename DataType, typename InnerMatrixType>
162  unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::CalculateBlockIndex(unsigned int row, unsigned int column) const
163  {
164  unsigned int blockRows = GetNumberOfBlockRows();
165  unsigned int blockCols = GetNumberOfBlockColumns();
166 
167  if( this->GetTransposeFlag() == 'T' )
168  {
169  std::swap(blockRows, blockCols);
170  }
171 
172  return BaseType::CalculateIndex(this->GetStorageType(),
173  row, column, blockRows, blockCols, this->GetTransposeFlag());
174  }
175 
176  template<typename DataType, typename InnerMatrixType>
177  const typename NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::InnerType*
178  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetBlockPtr(unsigned int row, unsigned int column) const
179  {
180  ASSERTL2(row < m_numberOfBlockRows, std::string("Row ") + boost::lexical_cast<std::string>(row) +
181  std::string(" requested in a block matrix with a maximum of ") + boost::lexical_cast<std::string>(m_numberOfBlockRows) +
182  std::string(" rows"));
183  ASSERTL2(column < m_numberOfBlockColumns, std::string("Column ") + boost::lexical_cast<std::string>(column) +
184  std::string(" requested in a block matrix with a maximum of ") + boost::lexical_cast<std::string>(m_numberOfBlockColumns) +
185  std::string(" columns"));
186  int x = CalculateBlockIndex(row,column);
187  if (x == -1)
188  {
189  return 0;
190  }
191  else
192  {
193  return m_data[x].get();
194  }
195  }
196 
197  template<typename DataType, typename InnerMatrixType>
198  boost::shared_ptr<const typename NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::InnerType>
199  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetBlock(unsigned int row, unsigned int column) const
200  {
201  ASSERTL2(row < m_numberOfBlockRows, std::string("Row ") + boost::lexical_cast<std::string>(row) +
202  std::string(" requested in a block matrix with a maximum of ") + boost::lexical_cast<std::string>(m_numberOfBlockRows) +
203  std::string(" rows"));
204  ASSERTL2(column < m_numberOfBlockColumns, std::string("Column ") + boost::lexical_cast<std::string>(column) +
205  std::string(" requested in a block matrix with a maximum of ") + boost::lexical_cast<std::string>(m_numberOfBlockColumns) +
206  std::string(" columns"));
207  int x = CalculateBlockIndex(row,column);
208  if (x < 0)
209  {
210  return boost::shared_ptr<const InnerType>();
211  }
212  else
213  {
214  return m_data[x];
215  }
216  }
217 
218  template<typename DataType, typename InnerMatrixType>
219  boost::shared_ptr<typename NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::InnerType>&
220  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetBlock(unsigned int row, unsigned int column)
221  {
222  ASSERTL2(row < m_numberOfBlockRows, std::string("Row ") + boost::lexical_cast<std::string>(row) +
223  std::string(" requested in a block matrix with a maximum of ") + boost::lexical_cast<std::string>(m_numberOfBlockRows) +
224  std::string(" rows"));
225  ASSERTL2(column < m_numberOfBlockColumns, std::string("Column ") + boost::lexical_cast<std::string>(column) +
226  std::string(" requested in a block matrix with a maximum of ") + boost::lexical_cast<std::string>(m_numberOfBlockColumns) +
227  std::string(" columns"));
228  int x = CalculateBlockIndex(row,column);
229  if (x == -1)
230  {
231  return m_nullBlockPtr;
232  }
233  else
234  {
235  return m_data[x];
236  }
237  }
238 
239  template<typename DataType, typename InnerMatrixType>
240  void NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::SetBlock(unsigned int row, unsigned int column, boost::shared_ptr<InnerType>& m)
241  {
242  ASSERTL2(row < m_numberOfBlockRows, std::string("Row ") + boost::lexical_cast<std::string>(row) +
243  std::string(" requested in a block matrix with a maximum of ") + boost::lexical_cast<std::string>(m_numberOfBlockRows) +
244  std::string(" rows"));
245  ASSERTL2(column < m_numberOfBlockColumns, std::string("Column ") + boost::lexical_cast<std::string>(column) +
246  std::string(" requested in a block matrix with a maximum of ") + boost::lexical_cast<std::string>(m_numberOfBlockColumns) +
247  std::string(" columns"));
248  m_data[CalculateBlockIndex(row, column)] = InnerType::CreateWrapper(m);
249  }
250 
251 
252 
253  template<typename DataType, typename InnerMatrixType>
254  typename NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::ConstGetValueType
255  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::operator()(unsigned int row, unsigned int col) const
256  {
257  ASSERTL2(row < this->GetRows(), std::string("Row ") + boost::lexical_cast<std::string>(row) +
258  std::string(" requested in a matrix with a maximum of ") + boost::lexical_cast<std::string>(this->GetRows()) +
259  std::string(" rows"));
260  ASSERTL2(col < this->GetColumns(), std::string("Column ") + boost::lexical_cast<std::string>(col) +
261  std::string(" requested in a matrix with a maximum of ") + boost::lexical_cast<std::string>(this->GetColumns()) +
262  std::string(" columns"));
263 
264 
265  const Array<OneD, unsigned int>* rowSizes = &m_rowSizes;
266  const Array<OneD, unsigned int>* columnSizes = &m_columnSizes;
267 
268  if( this->GetTransposeFlag() == 'T' )
269  {
270  std::swap(rowSizes, columnSizes);
271  }
272 
273  unsigned int blockRow = std::lower_bound(rowSizes->begin(), rowSizes->end(), row) - rowSizes->begin();
274  unsigned int blockColumn = std::lower_bound(columnSizes->begin(), columnSizes->end(), col) - columnSizes->begin();
275  const boost::shared_ptr<const InnerType> block = GetBlock(blockRow, blockColumn);
276 
277  unsigned int actualRow = row;
278  if( blockRow > 0 )
279  {
280  actualRow = row-((*rowSizes)[blockRow-1])-1;
281  }
282 
283  unsigned int actualCol = col;
284  if( blockColumn > 0 )
285  {
286  actualCol = col-((*columnSizes)[blockColumn-1])-1;
287  }
288 
289 
290  if( block )
291  {
292  return (*block)(actualRow, actualCol);
293  }
294  else
295  {
296  return m_zeroElement;
297  }
298  }
299 
300  template<typename DataType, typename InnerMatrixType>
301  unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetStorageSize() const
302  {
303  return m_storageSize;
304  }
305 
306  template<typename DataType, typename InnerMatrixType>
307  MatrixStorage NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetType() const
308  {
309  return m_storageType;
310  }
311 
312  template<typename DataType, typename InnerMatrixType>
313  unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetNumberOfBlockRows() const
314  {
315  if( this->GetTransposeFlag() == 'N' )
316  {
317  return m_numberOfBlockRows;
318  }
319  else
320  {
321  return m_numberOfBlockColumns;
322  }
323  }
324 
325  template<typename DataType, typename InnerMatrixType>
326  unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetNumberOfBlockColumns() const
327  {
328  if( this->GetTransposeFlag() == 'N' )
329  {
330  return m_numberOfBlockColumns;
331  }
332  else
333  {
334  return m_numberOfBlockRows;
335  }
336  }
337 
338  template<typename DataType, typename InnerMatrixType>
339  unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetNumberOfRowsInBlockRow(unsigned int blockRow) const
340  {
341  if( this->GetTransposeFlag() == 'N' )
342  {
343  return GetNumberOfElementsInBlock(blockRow, m_numberOfBlockRows, m_rowSizes);
344  }
345  else
346  {
347  return GetNumberOfElementsInBlock(blockRow, m_numberOfBlockColumns, m_columnSizes);
348  }
349  }
350 
351  template<typename DataType, typename InnerMatrixType>
352  unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetNumberOfColumnsInBlockColumn(unsigned int blockCol) const
353  {
354  if( this->GetTransposeFlag() == 'T' )
355  {
356  return GetNumberOfElementsInBlock(blockCol, m_numberOfBlockRows, m_rowSizes);
357  }
358  else
359  {
360  return GetNumberOfElementsInBlock(blockCol, m_numberOfBlockColumns, m_columnSizes);
361  }
362  }
363 
364  template<typename DataType, typename InnerMatrixType>
365  typename NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::begin() { return iterator(*this, 0, 0); }
366 
367  template<typename DataType, typename InnerMatrixType>
368  typename NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::end() { return iterator(*this); }
369 
370  template<typename DataType, typename InnerMatrixType>
371  typename NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::const_iterator NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::begin() const { return const_iterator(*this, 0, 0); }
372 
373  template<typename DataType, typename InnerMatrixType>
374  typename NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::const_iterator NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::end() const { return const_iterator(*this); }
375 
376 
377  template<typename DataType, typename InnerMatrixType>
378  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag> NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::CreateWrapper(const NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>& rhs)
379  {
380  return ThisType(rhs);
381  }
382 
383  template<typename DataType, typename InnerMatrixType>
384  boost::shared_ptr<NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag> > NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::CreateWrapper(const boost::shared_ptr<NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag> >& rhs)
385  {
386  return boost::shared_ptr<ThisType>(new ThisType(*rhs));
387  }
388 
389 
390  template<typename DataType, typename InnerMatrixType>
391  unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::GetNumberOfElementsInBlock(unsigned int block, unsigned int totalBlocks, const Array<OneD, unsigned int>& sizes)
392  {
393  ASSERTL2(block < totalBlocks, std::string("Block Element ") + boost::lexical_cast<std::string>(block) +
394  std::string(" requested in a matrix with a maximum of ") + boost::lexical_cast<std::string>(totalBlocks) +
395  std::string(" blocks."));
396  if( block == 0 )
397  {
398  return sizes[block]+1;
399  }
400  else
401  {
402  return sizes[block] - sizes[block-1];
403  }
404  }
405 
406  template<typename DataType, typename InnerMatrixType>
407  void NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::Initialize(const unsigned int* rowsPerBlock, const unsigned int* columnsPerBlock)
408  {
409  m_storageSize = this->GetRows()*this->GetColumns();
410  if (this->GetRows() > 0)
411  {
412  m_rowSizes[0] = rowsPerBlock[0] - 1;
413  for(unsigned int i = 1; i < m_numberOfBlockRows; ++i)
414  {
415  m_rowSizes[i] = rowsPerBlock[i] + m_rowSizes[i-1];
416  }
417  }
418  if (this->GetColumns() > 0)
419  {
420  m_columnSizes[0] = columnsPerBlock[0] - 1;
421  for(unsigned int i = 1; i < m_numberOfBlockColumns; ++i)
422  {
423  m_columnSizes[i] = columnsPerBlock[i] + m_columnSizes[i-1];
424  }
425  }
426  }
427 
428  template<typename DataType, typename InnerMatrixType>
429  typename boost::call_traits<typename NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::NumberType>::value_type
430  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::v_GetValue(unsigned int row, unsigned int column) const
431  {
432  return (*this)(row, column);
433  }
434 
435  template<typename DataType, typename InnerMatrixType>
436  unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::v_GetStorageSize() const
437  {
438  return this->GetStorageSize();
439  }
440 
441  template<typename DataType, typename InnerMatrixType>
442  MatrixStorage NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::v_GetStorageType() const
443  {
444  return this->GetType();
445  }
446 
447  template<typename DataType, typename InnerMatrixType>
448  void NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::v_Transpose()
449  {
450  BOOST_FOREACH(boost::shared_ptr<InnerType> ptr, m_data)
451  {
452  if( ptr.get() != 0 )
453  {
454  ptr->Transpose();
455  }
456  }
457  }
458 
459 
460 // template<typename DataType, typename InnerMatrixType>
461 // template<typename MatrixType>
462 // NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>::iterator_base(MatrixType& m, unsigned int curRow, unsigned int curCol) :
463 // m_matrix(m),
464 // m_curRow(curRow),
465 // m_curColumn(curCol)
466 // {
467 // }
468 
469 // template<typename DataType, typename InnerMatrixType>
470 // template<typename MatrixType>
471 // NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>::iterator_base(MatrixType& m) :
472 // m_matrix(m),
473 // m_curRow(std::numeric_limits<unsigned int>::max()),
474 // m_curColumn(std::numeric_limits<unsigned int>::max())
475 // {
476 // }
477 
478 // template<typename DataType, typename InnerMatrixType>
479 // template<typename MatrixType>
480 // NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>::iterator_base(const NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>& rhs) :
481 // m_matrix(rhs.m_matrix),
482 // m_curRow(rhs.m_curRow),
483 // m_curColumn(rhs.m_curColumn)
484 // {
485 // }
486 
487 // template<typename DataType, typename InnerMatrixType>
488 // template<typename MatrixType>
489 // void NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>::operator++()
490 // {
491 // if( m_curRow != std::numeric_limits<unsigned int>::max() )
492 // {
493 // boost::tie(m_curRow, m_curColumn) = StoragePolicy::Advance(
494 // m_matrix.GetRows(), m_matrix.GetColumns(), m_curRow, m_curColumn);
495 // }
496 // }
497 
498 // template<typename DataType, typename InnerMatrixType>
499 // template<typename MatrixType>
500 // typename NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::NumberType
501 // NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>::operator*()
502 // {
503 // return m_matrix(m_curRow, m_curColumn);
504 // }
505 
506 // template<typename DataType, typename InnerMatrixType>
507 // template<typename MatrixType>
508 // bool NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>::operator==(const NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>& rhs)
509 // {
510 // return m_curRow == rhs.m_curRow && m_curColumn == rhs.m_curColumn;
511 // }
512 
513 // template<typename DataType, typename InnerMatrixType>
514 // template<typename MatrixType>
515 // bool NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>::operator!=(const NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>& rhs)
516 // {
517 // return !(*this == rhs);
518 // }
519 
520 
521  template LIB_UTILITIES_EXPORT class NekMatrix< NekMatrix<NekDouble, StandardMatrixTag>, BlockMatrixTag>;
522  template LIB_UTILITIES_EXPORT class NekMatrix<NekMatrix< NekMatrix<NekDouble, StandardMatrixTag>, BlockMatrixTag>, BlockMatrixTag>;
523  template LIB_UTILITIES_EXPORT class NekMatrix<NekMatrix< NekMatrix<NekDouble, StandardMatrixTag>, ScaledMatrixTag>, BlockMatrixTag>;
524  template LIB_UTILITIES_EXPORT class NekMatrix<NekMatrix<NekMatrix< NekMatrix<NekDouble, StandardMatrixTag>, ScaledMatrixTag>, BlockMatrixTag>, BlockMatrixTag>;
525 }
526