Nektar++
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 // Permission is hereby granted, free of charge, to any person obtaining a
12 // copy of this software and associated documentation files (the "Software"),
13 // to deal in the Software without restriction, including without limitation
14 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 // and/or sell copies of the Software, and to permit persons to whom the
16 // Software is furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included
19 // in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 // DEALINGS IN THE SOFTWARE.
28 //
29 // Description:
30 //
31 ///////////////////////////////////////////////////////////////////////////////
32 
33 #include <boost/core/ignore_unused.hpp>
34 
38 
39 namespace Nektar
40 {
41 template <typename DataType, typename InnerMatrixType>
43  MatrixStorage type)
44  : BaseType(0, 0, type), m_data(), m_rowSizes(), m_columnSizes(),
45  m_storageSize(), m_numberOfBlockRows(0), m_numberOfBlockColumns(0)
46 {
47 }
48 
49 template <typename DataType, typename InnerMatrixType>
51  unsigned int numberOfBlockRows, unsigned int numberOfBlockColumns,
52  unsigned int rowsPerBlock, unsigned int columnsPerBlock, MatrixStorage type)
53  : BaseType(numberOfBlockRows * rowsPerBlock,
54  numberOfBlockColumns * columnsPerBlock, type),
55  m_data(), m_rowSizes(numberOfBlockRows),
56  m_columnSizes(numberOfBlockColumns), m_storageSize(0),
57  m_numberOfBlockRows(numberOfBlockRows),
58  m_numberOfBlockColumns(numberOfBlockColumns)
59 {
60  m_storageSize = GetRequiredStorageSize();
62  m_storageSize, std::shared_ptr<InnerType>());
63  for (unsigned int i = 1; i <= numberOfBlockRows; ++i)
64  {
65  m_rowSizes[i - 1] = i * rowsPerBlock - 1;
66  }
67 
68  for (unsigned int i = 1; i <= numberOfBlockColumns; ++i)
69  {
70  m_columnSizes[i - 1] = i * columnsPerBlock - 1;
71  }
72 }
73 
74 template <typename DataType, typename InnerMatrixType>
76  unsigned int numberOfBlockRows, unsigned int numberOfBlockColumns,
77  const unsigned int *rowsPerBlock, const unsigned int *columnsPerBlock,
78  MatrixStorage type)
79  : BaseType(
80  std::accumulate(rowsPerBlock, rowsPerBlock + numberOfBlockRows, 0),
81  std::accumulate(columnsPerBlock,
82  columnsPerBlock + numberOfBlockColumns, 0),
83  type),
84  m_data(), m_rowSizes(numberOfBlockRows),
85  m_columnSizes(numberOfBlockColumns), m_storageSize(0),
86  m_numberOfBlockRows(numberOfBlockRows),
87  m_numberOfBlockColumns(numberOfBlockColumns)
88 {
89  m_storageSize = GetRequiredStorageSize();
91  m_storageSize, std::shared_ptr<InnerType>());
92  Initialize(rowsPerBlock, columnsPerBlock);
93 }
94 
95 template <typename DataType, typename InnerMatrixType>
97  unsigned int numberOfBlockRows, unsigned int numberOfBlockColumns,
98  const Array<OneD, const unsigned int> &rowsPerBlock,
99  const Array<OneD, const unsigned int> &columnsPerBlock, MatrixStorage type)
100  : BaseType(std::accumulate(rowsPerBlock.data(),
101  rowsPerBlock.data() + numberOfBlockRows, 0),
102  std::accumulate(columnsPerBlock.data(),
103  columnsPerBlock.data() + numberOfBlockColumns,
104  0),
105  type),
106  m_data(), m_rowSizes(numberOfBlockRows),
107  m_columnSizes(numberOfBlockColumns), m_storageSize(0),
108  m_numberOfBlockRows(numberOfBlockRows),
109  m_numberOfBlockColumns(numberOfBlockColumns)
110 {
111  m_storageSize = GetRequiredStorageSize();
113  m_storageSize, std::shared_ptr<InnerType>());
114  Initialize(rowsPerBlock.data(), columnsPerBlock.data());
115 }
116 
117 template <typename DataType, typename InnerMatrixType>
119  const Array<OneD, const unsigned int> &rowsPerBlock,
120  const Array<OneD, const unsigned int> &columnsPerBlock, MatrixStorage type)
121  : BaseType(
122  std::accumulate(rowsPerBlock.begin(), rowsPerBlock.end(), 0),
123  std::accumulate(columnsPerBlock.begin(), columnsPerBlock.end(), 0),
124  type),
125  m_data(), m_rowSizes(rowsPerBlock.size()),
126  m_columnSizes(columnsPerBlock.size()), m_storageSize(0),
127  m_numberOfBlockRows(rowsPerBlock.size()),
128  m_numberOfBlockColumns(columnsPerBlock.size())
129 {
130  m_storageSize = GetRequiredStorageSize();
132  m_storageSize, std::shared_ptr<InnerType>());
133  Initialize(rowsPerBlock.data(), columnsPerBlock.data());
134 }
135 
136 template <typename DataType, typename InnerMatrixType>
138  const NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag> &rhs)
139  : BaseType(rhs), m_data(rhs.m_data.size()), m_rowSizes(rhs.m_rowSizes),
140  m_columnSizes(rhs.m_columnSizes), m_storageSize(rhs.m_storageSize),
141  m_numberOfBlockRows(rhs.m_numberOfBlockRows),
142  m_numberOfBlockColumns(rhs.m_numberOfBlockColumns)
143 {
144  for (unsigned int i = 0; i < rhs.m_data.size(); ++i)
145  {
146  m_data[i] = InnerType::CreateWrapper(rhs.m_data[i]);
147  }
148 }
149 
150 template <typename DataType, typename InnerMatrixType>
151 unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>,
152  BlockMatrixTag>::GetRequiredStorageSize() const
153 {
154  return BaseType::GetRequiredStorageSize(this->GetStorageType(),
155  this->GetNumberOfBlockRows(),
156  this->GetNumberOfBlockColumns());
157 }
158 
159 template <typename DataType, typename InnerMatrixType>
161  BlockMatrixTag>::CalculateBlockIndex(unsigned int row,
162  unsigned int column)
163  const
164 {
165  return BaseType::CalculateIndex(this->GetStorageType(), row, column,
166  m_numberOfBlockRows, m_numberOfBlockColumns,
167  this->GetTransposeFlag());
168 }
169 
170 template <typename DataType, typename InnerMatrixType>
172  BlockMatrixTag>::InnerType *
174  unsigned int row, unsigned int column) const
175 {
176  ASSERTL2(
177  this->GetTransposeFlag() == 'N' ? row < m_numberOfBlockRows
178  : row < m_numberOfBlockColumns,
179  std::string("Row ") + std::to_string(row) +
180  std::string(" requested in a block matrix with a maximum of ") +
181  std::to_string(m_numberOfBlockRows) + std::string(" rows"));
182  ASSERTL2(
183  this->GetTransposeFlag() == 'N' ? column < m_numberOfBlockColumns
184  : column < m_numberOfBlockColumns,
185  std::string("Column ") + std::to_string(column) +
186  std::string(" requested in a block matrix with a maximum of ") +
187  std::to_string(m_numberOfBlockColumns) + std::string(" columns"));
188  int x = CalculateBlockIndex(row, column);
189  if (x == -1)
190  {
191  return 0;
192  }
193  else
194  {
195  return m_data[x].get();
196  }
197 }
198 
199 template <typename DataType, typename InnerMatrixType>
200 std::shared_ptr<const typename NekMatrix<NekMatrix<DataType, InnerMatrixType>,
201  BlockMatrixTag>::InnerType>
203  unsigned int row, unsigned int column) const
204 {
205  ASSERTL2(
206  this->GetTransposeFlag() == 'N' ? row < m_numberOfBlockRows
207  : row < m_numberOfBlockColumns,
208  std::string("Row ") + std::to_string(row) +
209  std::string(" requested in a block matrix with a maximum of ") +
210  std::to_string(m_numberOfBlockRows) + std::string(" rows"));
211  ASSERTL2(
212  this->GetTransposeFlag() == 'N' ? column < m_numberOfBlockColumns
213  : column < m_numberOfBlockRows,
214  std::string("Column ") + std::to_string(column) +
215  std::string(" requested in a block matrix with a maximum of ") +
216  std::to_string(m_numberOfBlockColumns) + std::string(" columns"));
217  int x = CalculateBlockIndex(row, column);
218  if (x < 0)
219  {
220  return std::shared_ptr<const InnerType>();
221  }
222  else
223  {
224  return m_data[x];
225  }
226 }
227 
228 template <typename DataType, typename InnerMatrixType>
229 std::shared_ptr<typename NekMatrix<NekMatrix<DataType, InnerMatrixType>,
230  BlockMatrixTag>::InnerType>
232  unsigned int row, unsigned int column)
233 {
234  ASSERTL2(
235  this->GetTransposeFlag() == 'N' ? row < m_numberOfBlockRows
236  : row < m_numberOfBlockColumns,
237  std::string("Row ") + std::to_string(row) +
238  std::string(" requested in a block matrix with a maximum of ") +
239  std::to_string(m_numberOfBlockRows) + std::string(" rows"));
240  ASSERTL2(
241  this->GetTransposeFlag() == 'N' ? column < m_numberOfBlockColumns
242  : column < m_numberOfBlockRows,
243  std::string("Column ") + std::to_string(column) +
244  std::string(" requested in a block matrix with a maximum of ") +
245  std::to_string(m_numberOfBlockColumns) + std::string(" columns"));
246  int x = CalculateBlockIndex(row, column);
247  if (x == -1)
248  {
249  return m_nullBlockPtr;
250  }
251  else
252  {
253  return m_data[x];
254  }
255 }
256 
257 template <typename DataType, typename InnerMatrixType>
258 void NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::SetBlock(
259  unsigned int row, unsigned int column, std::shared_ptr<InnerType> &m)
260 {
261  ASSERTL2(
262  this->GetTransposeFlag() == 'N' ? row < m_numberOfBlockRows
263  : row < m_numberOfBlockColumns,
264  std::string("Row ") + std::to_string(row) +
265  std::string(" requested in a block matrix with a maximum of ") +
266  std::to_string(m_numberOfBlockRows) + std::string(" rows"));
267  ASSERTL2(
268  this->GetTransposeFlag() == 'N' ? column < m_numberOfBlockColumns
269  : column < m_numberOfBlockRows,
270  std::string("Column ") + std::to_string(column) +
271  std::string(" requested in a block matrix with a maximum of ") +
272  std::to_string(m_numberOfBlockColumns) + std::string(" columns"));
273  m_data[CalculateBlockIndex(row, column)] = InnerType::CreateWrapper(m);
274 }
275 
276 template <typename DataType, typename InnerMatrixType>
278  BlockMatrixTag>::ConstGetValueType
280  unsigned int row, unsigned int col) const
281 {
282  ASSERTL2(row < this->GetRows(),
283  std::string("Row ") + std::to_string(row) +
284  std::string(" requested in a matrix with a maximum of ") +
285  std::to_string(this->GetRows()) + std::string(" rows"));
286  ASSERTL2(col < this->GetColumns(),
287  std::string("Column ") + std::to_string(col) +
288  std::string(" requested in a matrix with a maximum of ") +
289  std::to_string(this->GetColumns()) + std::string(" columns"));
290 
291  const Array<OneD, unsigned int> *rowSizes = &m_rowSizes;
292  const Array<OneD, unsigned int> *columnSizes = &m_columnSizes;
293 
294  if (this->GetTransposeFlag() == 'T')
295  {
296  std::swap(rowSizes, columnSizes);
297  }
298 
299  unsigned int blockRow =
300  std::lower_bound(rowSizes->begin(), rowSizes->end(), row) -
301  rowSizes->begin();
302  unsigned int blockColumn =
303  std::lower_bound(columnSizes->begin(), columnSizes->end(), col) -
304  columnSizes->begin();
305  const std::shared_ptr<const InnerType> block =
306  GetBlock(blockRow, blockColumn);
307 
308  unsigned int actualRow = row;
309  if (blockRow > 0)
310  {
311  actualRow = row - ((*rowSizes)[blockRow - 1]) - 1;
312  }
313 
314  unsigned int actualCol = col;
315  if (blockColumn > 0)
316  {
317  actualCol = col - ((*columnSizes)[blockColumn - 1]) - 1;
318  }
319 
320  if (block)
321  {
322  return (*block)(actualRow, actualCol);
323  }
324  else
325  {
326  return m_zeroElement;
327  }
328 }
329 
330 template <typename DataType, typename InnerMatrixType>
332  BlockMatrixTag>::GetStorageSize() const
333 {
334  return m_storageSize;
335 }
336 
337 template <typename DataType, typename InnerMatrixType>
339  BlockMatrixTag>::GetNumberOfBlockRows() const
340 {
341  if (this->GetTransposeFlag() == 'N')
342  {
343  return m_numberOfBlockRows;
344  }
345  else
346  {
347  return m_numberOfBlockColumns;
348  }
349 }
350 
351 template <typename DataType, typename InnerMatrixType>
353  BlockMatrixTag>::GetNumberOfBlockColumns() const
354 {
355  if (this->GetTransposeFlag() == 'N')
356  {
357  return m_numberOfBlockColumns;
358  }
359  else
360  {
361  return m_numberOfBlockRows;
362  }
363 }
364 
365 template <typename DataType, typename InnerMatrixType>
366 unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::
367  GetNumberOfRowsInBlockRow(unsigned int blockRow) const
368 {
369  if (this->GetTransposeFlag() == 'N')
370  {
371  return GetNumberOfElementsInBlock(blockRow, m_numberOfBlockRows,
372  m_rowSizes);
373  }
374  else
375  {
376  return GetNumberOfElementsInBlock(blockRow, m_numberOfBlockColumns,
377  m_columnSizes);
378  }
379 }
380 
381 template <typename DataType, typename InnerMatrixType>
382 unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::
383  GetNumberOfColumnsInBlockColumn(unsigned int blockCol) const
384 {
385  if (this->GetTransposeFlag() == 'T')
386  {
387  return GetNumberOfElementsInBlock(blockCol, m_numberOfBlockRows,
388  m_rowSizes);
389  }
390  else
391  {
392  return GetNumberOfElementsInBlock(blockCol, m_numberOfBlockColumns,
393  m_columnSizes);
394  }
395 }
396 
397 template <typename DataType, typename InnerMatrixType>
399  GetBlockSizes(Array<OneD, unsigned int> &rowSizes,
400  Array<OneD, unsigned int> &colSizes) const
401 {
402  if (this->GetTransposeFlag() == 'T')
403  {
404  rowSizes = m_columnSizes;
405  colSizes = m_rowSizes;
406  }
407  else
408  {
409  rowSizes = m_rowSizes;
410  colSizes = m_columnSizes;
411  }
412 }
413 
414 template <typename DataType, typename InnerMatrixType>
416  BlockMatrixTag>::iterator
418 {
419  return iterator(*this, 0, 0);
420 }
421 
422 template <typename DataType, typename InnerMatrixType>
424  BlockMatrixTag>::iterator
426 {
427  return iterator(*this);
428 }
429 
430 template <typename DataType, typename InnerMatrixType>
432  BlockMatrixTag>::const_iterator
433 NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::begin() const
434 {
435  return const_iterator(*this, 0, 0);
436 }
437 
438 template <typename DataType, typename InnerMatrixType>
440  BlockMatrixTag>::const_iterator
442 {
443  return const_iterator(*this);
444 }
445 
446 template <typename DataType, typename InnerMatrixType>
448  NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::
450  BlockMatrixTag> &rhs)
451 {
452  return ThisType(rhs);
453 }
454 
455 template <typename DataType, typename InnerMatrixType>
456 std::shared_ptr<NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>>
457 NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::CreateWrapper(
458  const std::shared_ptr<
459  NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>> &rhs)
460 {
461  return std::shared_ptr<ThisType>(new ThisType(*rhs));
462 }
463 
464 template <typename DataType, typename InnerMatrixType>
465 unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::
466  GetNumberOfElementsInBlock(unsigned int block, unsigned int totalBlocks,
467  const Array<OneD, unsigned int> &sizes)
468 {
469  boost::ignore_unused(totalBlocks);
470  ASSERTL2(block < totalBlocks,
471  std::string("Block Element ") + std::to_string(block) +
472  std::string(" requested in a matrix with a maximum of ") +
473  std::to_string(totalBlocks) + std::string(" blocks."));
474  if (block == 0)
475  {
476  return sizes[block] + 1;
477  }
478  else
479  {
480  return sizes[block] - sizes[block - 1];
481  }
482 }
483 
484 template <typename DataType, typename InnerMatrixType>
486  BlockMatrixTag>::Initialize(const unsigned int *rowsPerBlock,
487  const unsigned int *columnsPerBlock)
488 {
489  m_storageSize = this->GetRows() * this->GetColumns();
490  if (this->GetRows() > 0)
491  {
492  m_rowSizes[0] = rowsPerBlock[0] - 1;
493  for (unsigned int i = 1; i < m_numberOfBlockRows; ++i)
494  {
495  m_rowSizes[i] = rowsPerBlock[i] + m_rowSizes[i - 1];
496  }
497  }
498  if (this->GetColumns() > 0)
499  {
500  m_columnSizes[0] = columnsPerBlock[0] - 1;
501  for (unsigned int i = 1; i < m_numberOfBlockColumns; ++i)
502  {
503  m_columnSizes[i] = columnsPerBlock[i] + m_columnSizes[i - 1];
504  }
505  }
506 }
507 
508 template <typename DataType, typename InnerMatrixType>
509 typename boost::call_traits<
511  BlockMatrixTag>::NumberType>::value_type
513  unsigned int row, unsigned int column) const
514 {
515  return (*this)(row, column);
516 }
517 
518 template <typename DataType, typename InnerMatrixType>
520  BlockMatrixTag>::v_GetStorageSize() const
521 {
522  return this->GetStorageSize();
523 }
524 
525 template <typename DataType, typename InnerMatrixType>
527  BlockMatrixTag>::v_Transpose()
528 {
529  for (auto &ptr : m_data)
530  {
531  if (ptr.get() != 0)
532  {
533  ptr->Transpose();
534  }
535  }
536 }
537 
538 // template<typename DataType, typename InnerMatrixType>
539 // template<typename MatrixType>
540 // NekMatrix<NekMatrix<DataType, InnerMatrixType>,
541 // BlockMatrixTag>::iterator_base<MatrixType>::iterator_base(MatrixType& m,
542 // unsigned int curRow, unsigned int curCol) :
543 // m_matrix(m),
544 // m_curRow(curRow),
545 // m_curColumn(curCol)
546 // {
547 // }
548 
549 // template<typename DataType, typename InnerMatrixType>
550 // template<typename MatrixType>
551 // NekMatrix<NekMatrix<DataType, InnerMatrixType>,
552 // BlockMatrixTag>::iterator_base<MatrixType>::iterator_base(MatrixType& m) :
553 // m_matrix(m),
554 // m_curRow(std::numeric_limits<unsigned int>::max()),
555 // m_curColumn(std::numeric_limits<unsigned int>::max())
556 // {
557 // }
558 
559 // template<typename DataType, typename InnerMatrixType>
560 // template<typename MatrixType>
561 // NekMatrix<NekMatrix<DataType, InnerMatrixType>,
562 // BlockMatrixTag>::iterator_base<MatrixType>::iterator_base(const
563 // NekMatrix<NekMatrix<DataType, InnerMatrixType>,
564 // BlockMatrixTag>::iterator_base<MatrixType>& rhs) :
565 // m_matrix(rhs.m_matrix),
566 // m_curRow(rhs.m_curRow),
567 // m_curColumn(rhs.m_curColumn)
568 // {
569 // }
570 
571 // template<typename DataType, typename InnerMatrixType>
572 // template<typename MatrixType>
573 // void NekMatrix<NekMatrix<DataType, InnerMatrixType>,
574 // BlockMatrixTag>::iterator_base<MatrixType>::operator++()
575 // {
576 // if( m_curRow != std::numeric_limits<unsigned int>::max() )
577 // {
578 // boost::tie(m_curRow, m_curColumn) = StoragePolicy::Advance(
579 // m_matrix.GetRows(), m_matrix.GetColumns(), m_curRow,
580 // m_curColumn);
581 // }
582 // }
583 
584 // template<typename DataType, typename InnerMatrixType>
585 // template<typename MatrixType>
586 // typename NekMatrix<NekMatrix<DataType, InnerMatrixType>,
587 // BlockMatrixTag>::NumberType NekMatrix<NekMatrix<DataType,
588 // InnerMatrixType>, BlockMatrixTag>::iterator_base<MatrixType>::operator*()
589 // {
590 // return m_matrix(m_curRow, m_curColumn);
591 // }
592 
593 // template<typename DataType, typename InnerMatrixType>
594 // template<typename MatrixType>
595 // bool NekMatrix<NekMatrix<DataType, InnerMatrixType>,
596 // BlockMatrixTag>::iterator_base<MatrixType>::operator==(const
597 // NekMatrix<NekMatrix<DataType, InnerMatrixType>,
598 // BlockMatrixTag>::iterator_base<MatrixType>& rhs)
599 // {
600 // return m_curRow == rhs.m_curRow && m_curColumn == rhs.m_curColumn;
601 // }
602 
603 // template<typename DataType, typename InnerMatrixType>
604 // template<typename MatrixType>
605 // bool NekMatrix<NekMatrix<DataType, InnerMatrixType>,
606 // BlockMatrixTag>::iterator_base<MatrixType>::operator!=(const
607 // NekMatrix<NekMatrix<DataType, InnerMatrixType>,
608 // BlockMatrixTag>::iterator_base<MatrixType>& rhs)
609 // {
610 // return !(*this == rhs);
611 // }
612 
613 template LIB_UTILITIES_EXPORT class NekMatrix<
615 template LIB_UTILITIES_EXPORT class NekMatrix<
617  BlockMatrixTag>;
618 template LIB_UTILITIES_EXPORT class NekMatrix<
620  BlockMatrixTag>;
621 template LIB_UTILITIES_EXPORT class NekMatrix<
622  NekMatrix<
624  BlockMatrixTag>,
625  BlockMatrixTag>;
626 
627 template LIB_UTILITIES_EXPORT class NekMatrix<
629 template LIB_UTILITIES_EXPORT class NekMatrix<
631  BlockMatrixTag>;
632 template LIB_UTILITIES_EXPORT class NekMatrix<
634  BlockMatrixTag>;
635 template LIB_UTILITIES_EXPORT class NekMatrix<
636  NekMatrix<
638  BlockMatrixTag>,
639  BlockMatrixTag>;
640 } // namespace Nektar
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Definition: ErrorUtil.hpp:272
#define LIB_UTILITIES_EXPORT
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1