Example #1
0
//-----------------------------------------------------------------------------
void STLMatrix::init(const TensorLayout& tensor_layout)
{
  // Check that sparsity pattern has correct storage (row vs column storage)
  if (_primary_dim != tensor_layout.primary_dim)
  {
    dolfin_error("STLMatrix.cpp",
                 "initialization of STL matrix",
                 "Primary storage dim of matrix and tensot layout must be the same");
  }

  //primary_dim = sparsity_pattern.primary_dim();
  std::size_t primary_codim = 1;
  if (_primary_dim == 1)
    primary_codim = 0;

  _local_range = tensor_layout.local_range(_primary_dim);
  num_codim_entities = tensor_layout.size(primary_codim);

  const std::size_t num_primary_entiries = _local_range.second - _local_range.first;

  _values.resize(num_primary_entiries);

  // FIXME: Add function to sparsity pattern to get nnz per row to
  //        to reserve space for vectors
  //if (tensor_layout.sparsity_pattern()
  //{
  //  Reserve space here
  //}
}
Example #2
0
//----------------------------------------------------------------------------
void EigenMatrix::init(const TensorLayout& tensor_layout)
{
  resize(tensor_layout.size(0), tensor_layout.size(1));

  // Get sparsity pattern
  dolfin_assert(tensor_layout.sparsity_pattern());
  auto sparsity_pattern = tensor_layout.sparsity_pattern();
  dolfin_assert(sparsity_pattern);

  // Reserve space for non-zeroes and get non-zero pattern
  std::vector<std::size_t> num_nonzeros_per_row;
  sparsity_pattern->num_nonzeros_diagonal(num_nonzeros_per_row);
  _matA.reserve(num_nonzeros_per_row);

  const std::vector<std::vector<std::size_t>> pattern
    = sparsity_pattern->diagonal_pattern(SparsityPattern::Type::sorted);

  if (!eigen_matrix_type::IsRowMajor)
    warning ("Entering sparsity for RowMajor matrix - performance may be affected");

  // Add entries for RowMajor matrix
  for (std::size_t i = 0; i != pattern.size(); ++i)
  {
    for (auto j : pattern[i])
      _matA.insert(i, j) = 0.0;
  }
}
Example #3
0
//-----------------------------------------------------------------------------
GraphOrdering::GraphOrdering(const TensorLayout& tensor_layout)
      : _tensor_layout(tensor_layout)
{
  if (tensor_layout.rank() != 2)
  {
    dolfin_error("GraphOrdering.cpp",
                 "create matrix re-ordering",
                 "Zoltan object for sparsity pattern re-ordering can only be used for rank 2 tensors");
  }

  if (!tensor_layout.sparsity_pattern())
  {
    dolfin_error("GraphOrdering.cpp",
                 "create matrix re-ordering",
                 "TensorLayout object must a have sparsity pattern");
  }

  if (tensor_layout.size(0) != tensor_layout.size(1))
  {
    dolfin_error("GraphOrdering.cpp",
                 "create matrix re-ordering",
                 "Zoltan object for sparsity pattern re-ordering can only be used for square matrices");
  }
}
Example #4
0
//-----------------------------------------------------------------------------
void TpetraMatrix::init(const TensorLayout& tensor_layout)
{
  if (!_matA.is_null())
    error("TpetraMatrix may not be initialized more than once.");

  // Get global dimensions and local range
  dolfin_assert(tensor_layout.rank() == 2);
  const std::size_t M = tensor_layout.size(0);
  const std::size_t N = tensor_layout.size(1);
  const std::pair<std::size_t, std::size_t> row_range
    = tensor_layout.local_range(0);
  const std::size_t m = row_range.second - row_range.first;

  // Get sparsity pattern
  dolfin_assert(tensor_layout.sparsity_pattern());
  std::shared_ptr<const GenericSparsityPattern> sparsity_pattern
    = tensor_layout.sparsity_pattern();

  // Initialize matrix
  // Insist on square Matrix for now
  dolfin_assert(M == N);

  // Set up MPI Comm
  Teuchos::RCP<const Teuchos::Comm<int>>
    _comm(new Teuchos::MpiComm<int>(sparsity_pattern->mpi_comm()));

  // Save the local row and column mapping, so we can use add_local
  // and set_local later with off-process entries
  std::vector<dolfin::la_index> global_indices0
    (tensor_layout.local_to_global_map[0].begin(),
     tensor_layout.local_to_global_map[0].end());
  Teuchos::ArrayView<dolfin::la_index> _global_indices0(global_indices0);
  _row_map = Teuchos::rcp
    (new map_type(Teuchos::OrdinalTraits<dolfin::la_index>::invalid(),
                  _global_indices0, 0, _comm));

  std::vector<dolfin::la_index> global_indices1
    (tensor_layout.local_to_global_map[1].begin(),
     tensor_layout.local_to_global_map[1].end());
  Teuchos::ArrayView<dolfin::la_index> _global_indices1(global_indices1);
  _col_map = Teuchos::rcp
    (new map_type(Teuchos::OrdinalTraits<dolfin::la_index>::invalid(),
                  _global_indices1, 0, _comm));

  // Make a Tpetra::CrsGraph of the sparsity_pattern
  typedef Tpetra::CrsGraph<> graph_type;
  std::vector<std::vector<std::size_t>> pattern_diag
    = sparsity_pattern->diagonal_pattern(GenericSparsityPattern::unsorted);
  std::vector<std::vector<std::size_t>> pattern_off
    = sparsity_pattern->off_diagonal_pattern(GenericSparsityPattern::unsorted);

  dolfin_assert(pattern_diag.size() == pattern_off.size());
  dolfin_assert(m == pattern_diag.size());

  // Get number of non-zeros per row to allocate storage
  std::vector<std::size_t> entries_per_row(m);
  sparsity_pattern->num_local_nonzeros(entries_per_row);
  Teuchos::ArrayRCP<std::size_t> _nnz(entries_per_row.data(), 0,
                                      entries_per_row.size(), false);

  // Create a non-overlapping "row" map for the graph
  // The column map will be auto-generated from the entries.
  Teuchos::ArrayView<dolfin::la_index>
    _global_indices_subset(global_indices0.data(), m);
  Teuchos::RCP<const map_type> graph_row_map
    (new map_type(Teuchos::OrdinalTraits<dolfin::la_index>::invalid(),
                  _global_indices_subset, 0, _comm));

  Teuchos::RCP<graph_type> crs_graph
    (new graph_type(graph_row_map, _nnz, Tpetra::StaticProfile));

  for (std::size_t i = 0; i != m; ++i)
  {
    std::vector<dolfin::la_index> indices(pattern_diag[i].begin(),
                                          pattern_diag[i].end());
    indices.insert(indices.end(), pattern_off[i].begin(),
                   pattern_off[i].end());

    Teuchos::ArrayView<dolfin::la_index> _indices(indices);
    crs_graph->insertGlobalIndices(tensor_layout.local_to_global_map[0][i],
                                _indices);
  }

  crs_graph->fillComplete();
  _matA = Teuchos::rcp(new matrix_type(crs_graph));
}
Example #5
0
//-----------------------------------------------------------------------------
void TpetraMatrix::init(const TensorLayout& tensor_layout)
{
  if (!_matA.is_null())
  {
    dolfin_error("TpetraMatrix.h",
                 "initialize matrix",
                 "Matrix cannot be initialised more than once");
  }

  // Get global dimensions and local range
  dolfin_assert(tensor_layout.rank() == 2);

  const std::pair<std::size_t, std::size_t> row_range
    = tensor_layout.local_range(0);
  const std::size_t m = row_range.second - row_range.first;

  const std::pair<std::size_t, std::size_t> col_range
    = tensor_layout.local_range(1);
  const std::size_t n = col_range.second - col_range.first;

  // Get sparsity pattern
  auto sparsity_pattern = tensor_layout.sparsity_pattern();
  dolfin_assert(sparsity_pattern);

  // Initialize matrix

  // Set up MPI Comm
  Teuchos::RCP<const Teuchos::Comm<int>>
    _comm(new Teuchos::MpiComm<int>(sparsity_pattern->mpi_comm()));

  // Save the local row and column mapping, so we can use add_local
  // later with off-process entries

  // Overlapping RowMap
  index_map[0] = tensor_layout.index_map(0);

  std::vector<dolfin::la_index> global_indices0(m);
  for (std::size_t i = 0; i < m; ++i)
  {
    global_indices0[i]
      = tensor_layout.index_map(0)->local_to_global(i);
  }

  // Non-overlapping RangeMap
  Teuchos::ArrayView<dolfin::la_index>
    _global_indices0(global_indices0.data(), m);
  Teuchos::RCP<const map_type> range_map
    (new map_type(Teuchos::OrdinalTraits<dolfin::la_index>::invalid(),
                  _global_indices0, 0, _comm));

  // Overlapping ColMap
  index_map[1] = tensor_layout.index_map(1);

  std::vector<dolfin::la_index> global_indices1(n);
  {
    for (std::size_t i = 0; i < n; ++i)
      global_indices1[i]
        = tensor_layout.index_map(1)->local_to_global(i);
  }

  // Non-overlapping DomainMap
  Teuchos::ArrayView<dolfin::la_index>
    _global_indices1(global_indices1.data(), n);
  Teuchos::RCP<const map_type> domain_map
    (new map_type(Teuchos::OrdinalTraits<dolfin::la_index>::invalid(),
                  _global_indices1, 0, _comm));

  std::vector<std::vector<std::size_t>> pattern_diag
    = sparsity_pattern->diagonal_pattern(SparsityPattern::unsorted);
  std::vector<std::vector<std::size_t>> pattern_off
    = sparsity_pattern->off_diagonal_pattern(SparsityPattern::unsorted);
  const bool has_off_diag = pattern_off.size() > 0;

  dolfin_assert(pattern_diag.size() == pattern_off.size() || !has_off_diag);
  dolfin_assert(m == pattern_diag.size());

  // Get number of non-zeros per row to allocate storage
  std::vector<std::size_t> entries_per_row(m);
  sparsity_pattern->num_local_nonzeros(entries_per_row);
  Teuchos::ArrayRCP<std::size_t> _nnz(entries_per_row.data(), 0,
                                      entries_per_row.size(), false);

  // Create a non-overlapping "row" map for the graph
  // The column map will be auto-generated from the entries.

  Teuchos::RCP<graph_type> crs_graph
    (new graph_type(range_map, _nnz, Tpetra::StaticProfile));

  for (std::size_t i = 0; i != m; ++i)
  {
    std::vector<dolfin::la_index> indices(pattern_diag[i].begin(),
                                          pattern_diag[i].end());
    if (has_off_diag)
    {
      indices.insert(indices.end(), pattern_off[i].begin(),
                     pattern_off[i].end());
    }

    Teuchos::ArrayView<dolfin::la_index> _indices(indices);
    crs_graph->insertGlobalIndices
      ((dolfin::la_index)tensor_layout.index_map(0)->local_to_global(i), _indices);
  }

  crs_graph->fillComplete(domain_map, range_map);

  _matA = Teuchos::rcp(new matrix_type(crs_graph));
}