<commit_before>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "../general/array.hpp"
#include "../general/globals.hpp"
#include "matrix.hpp"
#include "sparsemat.hpp"
#include "blockvector.hpp"
#include "blockmatrix.hpp"

namespace mfem
{

BlockMatrix::BlockMatrix(const Array<int> & offsets):
   AbstractSparseMatrix(offsets.Last()),
   owns_blocks(false),
   nRowBlocks(offsets.Size()-1),
   nColBlocks(offsets.Size()-1),
   row_offsets(const_cast< Array<int>& >(offsets).GetData(), offsets.Size()),
   col_offsets(const_cast< Array<int>& >(offsets).GetData(), offsets.Size()),
   Aij(nRowBlocks, nColBlocks)
{
   Aij = (SparseMatrix *)NULL;
}

BlockMatrix::BlockMatrix(const Array<int> & row_offsets_,
                         const Array<int> & col_offsets_):
   AbstractSparseMatrix(row_offsets_.Last(), col_offsets_.Last()),
   owns_blocks(false),
   nRowBlocks(row_offsets_.Size()-1),
   nColBlocks(col_offsets_.Size()-1),
   row_offsets(const_cast< Array<int>& >(row_offsets_).GetData(),
               row_offsets_.Size()),
   col_offsets(const_cast< Array<int>& >(col_offsets_).GetData(),
               col_offsets_.Size()),
   Aij(nRowBlocks, nColBlocks)
{
   Aij = (SparseMatrix *)NULL;
}


BlockMatrix::~BlockMatrix()
{
   if (owns_blocks)
   {
      for (SparseMatrix ** it = Aij.GetRow(0);
           it != Aij.GetRow(0)+(Aij.NumRows()*Aij.NumCols()); ++it)
      {
         delete *it;
      }
   }
}

void BlockMatrix::SetBlock(int i, int j, SparseMatrix * mat)
{
#ifdef MFEM_DEBUG
   if (nRowBlocks <= i || nColBlocks <= j)
   {
      mfem_error("BlockMatrix::SetBlock #0");
   }

   if (mat->Height() != row_offsets[i+1] - row_offsets[i])
   {
      mfem_error("BlockMatrix::SetBlock #1");
   }

   if (mat->Width() != col_offsets[j+1] - col_offsets[j])
   {
      mfem_error("BlockMatrix::SetBlock #2");
   }
#endif
   Aij(i,j) = mat;
}

SparseMatrix & BlockMatrix::GetBlock(int i, int j)
{
#ifdef MFEM_DEBUG
   if (nRowBlocks <= i || nColBlocks <= j)
   {
      mfem_error("BlockMatrix::Block #0");
   }

   if (IsZeroBlock(i,j))
   {
      mfem_error("BlockMatrix::Block #1");
   }
#endif
   return *Aij(i,j);
}

const SparseMatrix & BlockMatrix::GetBlock(int i, int j) const
{
#ifdef MFEM_DEBUG
   if (nRowBlocks <= i || nColBlocks <= j)
   {
      mfem_error("BlockMatrix::Block const #0");
   }

   if (IsZeroBlock(i,j))
   {
      mfem_error("BlockMatrix::Block const #1");
   }
#endif

   return *Aij(i,j);
}


int BlockMatrix::NumNonZeroElems() const
{
   int nnz_elem = 0;
   for (int jcol = 0; jcol != nColBlocks; ++jcol)
   {
      for (int irow = 0; irow != nRowBlocks; ++irow)
      {
         if (Aij(irow,jcol))
         {
            nnz_elem+= Aij(irow,jcol)->NumNonZeroElems();
         }
      }
   }
   return nnz_elem;
}


double& BlockMatrix::Elem (int i, int j)
{
   int iloc, iblock;
   int jloc, jblock;

   findGlobalRow(i, iblock, iloc);
   findGlobalCol(j, jblock, jloc);

   if (IsZeroBlock(iblock, jblock))
   {
      mfem_error("BlockMatrix::Elem");
   }

   return Aij(iblock, jblock)->Elem(iloc, jloc);
}

const double& BlockMatrix::Elem (int i, int j) const
{
   int iloc, iblock;
   int jloc, jblock;

   findGlobalRow(i, iblock, iloc);
   findGlobalCol(j, jblock, jloc);

   if (IsZeroBlock(iblock, jblock))
   {
      mfem_error("BlockMatrix::Elem");
   }

   return Aij(iblock, jblock)->Elem(iloc, jloc);
}

int BlockMatrix::RowSize(const int i) const
{
   int rowsize = 0;

   int iblock, iloc;
   findGlobalRow(i, iblock, iloc);

   for (int jblock = 0; jblock < nColBlocks; ++jblock)
   {
      if (Aij(iblock,jblock) != NULL)
      {
         rowsize += Aij(iblock,jblock)->RowSize(iloc);
      }
   }

   return rowsize;
}

int BlockMatrix::GetRow(const int row, Array<int> &cols, Vector &srow) const
{
   int iblock, iloc, rowsize;
   findGlobalRow(row, iblock, iloc);
   rowsize = RowSize(row);
   cols.SetSize(rowsize);
   srow.SetSize(rowsize);<commit_msg>Force using const version to prevent error when accessing undefined terms<commit_after>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "../general/array.hpp"
#include "../general/globals.hpp"
#include "matrix.hpp"
#include "sparsemat.hpp"
#include "blockvector.hpp"
#include "blockmatrix.hpp"

namespace mfem
{

BlockMatrix::BlockMatrix(const Array<int> & offsets):
   AbstractSparseMatrix(offsets.Last()),
   owns_blocks(false),
   nRowBlocks(offsets.Size()-1),
   nColBlocks(offsets.Size()-1),
   row_offsets(const_cast< Array<int>& >(offsets).GetData(), offsets.Size()),
   col_offsets(const_cast< Array<int>& >(offsets).GetData(), offsets.Size()),
   Aij(nRowBlocks, nColBlocks)
{
   Aij = (SparseMatrix *)NULL;
}

BlockMatrix::BlockMatrix(const Array<int> & row_offsets_,
                         const Array<int> & col_offsets_):
   AbstractSparseMatrix(row_offsets_.Last(), col_offsets_.Last()),
   owns_blocks(false),
   nRowBlocks(row_offsets_.Size()-1),
   nColBlocks(col_offsets_.Size()-1),
   row_offsets(const_cast< Array<int>& >(row_offsets_).GetData(),
               row_offsets_.Size()),
   col_offsets(const_cast< Array<int>& >(col_offsets_).GetData(),
               col_offsets_.Size()),
   Aij(nRowBlocks, nColBlocks)
{
   Aij = (SparseMatrix *)NULL;
}


BlockMatrix::~BlockMatrix()
{
   if (owns_blocks)
   {
      for (SparseMatrix ** it = Aij.GetRow(0);
           it != Aij.GetRow(0)+(Aij.NumRows()*Aij.NumCols()); ++it)
      {
         delete *it;
      }
   }
}

void BlockMatrix::SetBlock(int i, int j, SparseMatrix * mat)
{
#ifdef MFEM_DEBUG
   if (nRowBlocks <= i || nColBlocks <= j)
   {
      mfem_error("BlockMatrix::SetBlock #0");
   }

   if (mat->Height() != row_offsets[i+1] - row_offsets[i])
   {
      mfem_error("BlockMatrix::SetBlock #1");
   }

   if (mat->Width() != col_offsets[j+1] - col_offsets[j])
   {
      mfem_error("BlockMatrix::SetBlock #2");
   }
#endif
   Aij(i,j) = mat;
}

SparseMatrix & BlockMatrix::GetBlock(int i, int j)
{
#ifdef MFEM_DEBUG
   if (nRowBlocks <= i || nColBlocks <= j)
   {
      mfem_error("BlockMatrix::Block #0");
   }

   if (IsZeroBlock(i,j))
   {
      mfem_error("BlockMatrix::Block #1");
   }
#endif
   return *Aij(i,j);
}

const SparseMatrix & BlockMatrix::GetBlock(int i, int j) const
{
#ifdef MFEM_DEBUG
   if (nRowBlocks <= i || nColBlocks <= j)
   {
      mfem_error("BlockMatrix::Block const #0");
   }

   if (IsZeroBlock(i,j))
   {
      mfem_error("BlockMatrix::Block const #1");
   }
#endif

   return *Aij(i,j);
}


int BlockMatrix::NumNonZeroElems() const
{
   int nnz_elem = 0;
   for (int jcol = 0; jcol != nColBlocks; ++jcol)
   {
      for (int irow = 0; irow != nRowBlocks; ++irow)
      {
         if (Aij(irow,jcol))
         {
            nnz_elem+= Aij(irow,jcol)->NumNonZeroElems();
         }
      }
   }
   return nnz_elem;
}


double& BlockMatrix::Elem (int i, int j)
{
   int iloc, iblock;
   int jloc, jblock;

   findGlobalRow(i, iblock, iloc);
   findGlobalCol(j, jblock, jloc);

   if (IsZeroBlock(iblock, jblock))
   {
      mfem_error("BlockMatrix::Elem");
   }

   return Aij(iblock, jblock)->Elem(iloc, jloc);
}

const double& BlockMatrix::Elem (int i, int j) const
{
   int iloc, iblock;
   int jloc, jblock;

   findGlobalRow(i, iblock, iloc);
   findGlobalCol(j, jblock, jloc);

   if (IsZeroBlock(iblock, jblock))
   {
      mfem_error("BlockMatrix::Elem");
   }
   const SparseMatrix& AijSM = *Aij(iblock, jblock);
   return AijSM.Elem(iloc, jloc);
}

int BlockMatrix::RowSize(const int i) const
{
   int rowsize = 0;

   int iblock, iloc;
   findGlobalRow(i, iblock, iloc);

   for (int jblock = 0; jblock < nColBlocks; ++jblock)
   {
      if (Aij(iblock,jblock) != NULL)
      {
         rowsize += Aij(iblock,jblock)->RowSize(iloc);
      }
   }

   return rowsize;
}

int BlockMatrix::GetRow(const int row, Array<int> &cols, Vector &srow) const
{
   int iblock, iloc, rowsize;
   findGlobalRow(row, iblock, iloc);
   rowsize = RowSize(row);
   cols.SetSize(rowsize);
   srow.SetSize(rowsize);
{'fraction_non_alphanumeric': 0.15118233777877396, 'fraction_numerical': 0.00784489521461392, 'mean_word_length': 3.340466926070039, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 38, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3181886', 'n_tokens_mistral': 3339, 'n_tokens_neox': 3250, 'n_words': 707}