]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Start ParalutionWrappers for sparse matrix.
authorturcksin <turcksin@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 5 Dec 2013 22:22:18 +0000 (22:22 +0000)
committerturcksin <turcksin@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 5 Dec 2013 22:22:18 +0000 (22:22 +0000)
git-svn-id: https://svn.dealii.org/branches/branch_paralution@31902 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/include/deal.II/lac/paralution_sparse_matrix.h [new file with mode: 0644]
deal.II/include/deal.II/lac/paralution_vector.h
deal.II/include/deal.II/lac/sparse_matrix.h
deal.II/include/deal.II/lac/trilinos_sparse_matrix.h
deal.II/source/lac/CMakeLists.txt
deal.II/source/lac/paralution_sparse_matrix.cc [new file with mode: 0644]

diff --git a/deal.II/include/deal.II/lac/paralution_sparse_matrix.h b/deal.II/include/deal.II/lac/paralution_sparse_matrix.h
new file mode 100644 (file)
index 0000000..a856acd
--- /dev/null
@@ -0,0 +1,381 @@
+// ---------------------------------------------------------------------
+// $Id: paralution_sparse_matrix.h 30040 2013-07-18 17:06:48Z maier $
+//
+// Copyright (C) 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+#ifndef __deal2__paralution_matrix_h
+#define __deal2__paralution_matrix_h
+
+#include <deal.II/base/config.h>
+
+#ifdef DEAL_II_WITH_PARALUTION
+
+#include <deal.II/base/exceptions.h>
+#include <deal.II/base/subscriptor.h>
+#include <deal.II/lac/sparse_matrix.h>
+#include <algorithm>
+
+#include "paralution.hpp"
+#include "base/local_matrix.hpp"
+
+DEAL_II_NAMESPACE_OPEN
+
+/**
+ * @addtogroup ParalutionWrappers
+ *@{
+ */
+namespace ParalutionWrappers
+{
+  /**
+   * This class implements a wrapper to use the Paralution sparse matrix class
+   * LocalMatrix. This class is designed for use in either serial
+   * implementation or as a localized copy on each processors.
+   *
+   * The interface of this class is modeled after the existing SparseMatrix
+   * class in deal.II. It has almost the same member functions, and is often
+   * exchangeable. However, Paralution LocalMatix only supports float and double.
+   *
+   * @ingroup ParalutionWrappers
+   * @ingroup Matrix1
+   * @author Bruno Turcksin, 2013
+   */
+  template <typename Number>
+  class SparseMatrix : public Subscriptor
+  {
+  public :
+    /**
+     * Declare type for container size.
+     */
+    typedef types::global_dof_index size_type;
+
+    /**
+     * @name 1: Constructors and initialization
+     */
+    //@{
+    /**
+     * Constructor; initializes the matrix to be empty, without any
+     * structure, i.e. the matrix is not usable at all. This constructor is
+     * therefore only useful for matrices which are members of a class. All
+     * other matrices should be created at a point in the data flow where
+     * all necessary information is available.
+     *
+     * You have to initialize the matrix before usage with reinit(const
+     * SparsityPattern &sparsity_pattern).
+     */
+    SparseMatrix();
+
+    /**
+     * Copy constructor. This constructor is only allowed to be called if
+     * the matrix to be copied is empty. This is for the same reason as for
+     * the SparsityPattern, see there fore the details.
+     *
+     * If you really want to copy a whole matrix, you can do so by using the
+     * copy_from() function.
+     */
+    //TODO
+    //SparseMarix(const SparseMatrix &sparse_matrix);
+
+    /**
+     * Constructo. Takes the given matrix sparsity structure to represent
+     * the sparsity pattern of this matrix. You can change the sparsity
+     * pattern later on by calling the reinit(const SparsityPattern&)
+     * function.
+     *
+     * The constructor is marked explicit so as to disallow that someone
+     * passes a sparsity pattern in place of a spaese matrix to some
+     * function, where an empty matrix would be generated then.
+     */
+    explicit SparseMatrix(const SparsityPattern &sparsity_pattern);
+
+    /**
+     * Destructor. Free all memory, but do not release the memory of the
+     * sparsity structure.
+     */
+    ~SparseMatrix();
+
+    /**
+     * Reinitialize the sparse matrix with the given sparsity pattern. The
+     * latter tells the matrix how many nonzero elements there need to be
+     * reserved.
+     *
+     * The elements of the matrix are set to zero by this function.
+     */
+    void reinit(SparsityPattern const &sparsity_pattern);
+
+    /**
+     * Release all memory and return to a state just like after having
+     * called the default constructor. It also forgets the sparsity pattern
+     * it was previously tied to.
+     */
+    virtual void clear();
+
+    /**
+     * This function convert the underlying SparseMatrix to
+     * Paralution::LocalMatrix. This function frees the SparseMatrix.
+     */
+    void convert_to_paralution_csr();
+    //@}
+    /**
+     * @name 2: Information on the matrix
+     */
+    //@{
+    /**
+     * Return the dimension of the image space. To remember: the matrix is
+     * of dimension $m \times n$. This function works only after
+     * convert_to_paralution_csr has been called.
+     */
+    //TODO make the function work all the time
+    size_type m() const;
+
+    /**
+     * Return the dimension of the range space. To remember: the matrix is
+     * of dimension $m \times n$.
+     */
+    //TODO make the function work all the time
+    size_type n() const;
+    //@}
+    /**
+     * @name 3: Modifying entries
+     */
+    //@{
+    /**
+     * Add <tt>value</tt> to the element (<i>i,j</i>). Throws an error if
+     * the entry does not exist or if <tt>value</tt> is not a finite number.
+     * Still it is allowed to store zerp values in non-existent fields.
+     *
+     * This function only works on the host.
+     */
+    void add(const size_type i,
+             const size_type j,
+             const Number value);
+
+    /**
+     * Add all elements given in a FullMatrix into sparse matrix locations
+     * given by <tt>indices</tt>. In other words, this function adds the
+     * elements in <tt>full_matrix</tt> to the respective entries in calling
+     * matrix, using the local-to-global indexing specified by
+     * <tt>indices</tt> for both the rows and the columns of the matrix.
+     * This function assumes a quadratic sparse matrix and a quadratic
+     * full_matrix, the usual situation in FE calculations.
+     *
+     * The optional parameter <tt>elide_zero_values</tt> can be used to
+     * specify whether zero values should be added anyway or these should be
+     * filtered away and only non-zero data is added. The defaul value is
+     * <tt>true</tt>, i.e., zero values won't be added into the matrix.
+     *
+     * This function only works on the host.
+     */
+    template <typename Number2>
+    void add(const std::vector<size_type> &indices,
+             const FullMatrix<Number2> &full_matrix,
+             const bool elide_zero_values = true);
+
+    /**
+     * Same function as before, but now including the possibility to use
+     * rectaangular full_matrices and different local-to-global indexing on
+     * rows and columns, respectively.
+     *
+     * This function only works on the host.
+     */
+    template <typename Number2>
+    void add (const std::vector<size_type> &row_indices,
+              const std::vector<size_type> &col_indices,
+              const FullMatrix<Number2>    &full_matrix,
+              const bool                    elide_zero_values = true);
+
+    /**
+     * Set several elements in the specified row of the matrix with column
+     * indices as given by <tt>col_indices</tt> to the respective value.
+     *
+     * The optional parameter <tt>elide_zero_values</tt> can be used to
+     * specify whether zero values should be added anyway or these should be
+     * filtered away and only non-zero data is added. The default value is
+     * <tt>true</tt>, i.e., zero values won't be added into the matrix.
+     *
+     * This function only works on the host.
+     */
+    template <typename Number2>
+    void add (const size_type               row,
+              const std::vector<size_type> &col_indices,
+              const std::vector<Number2>   &values,
+              const bool                    elide_zero_values = true);
+
+    /**
+     * Add an array of values given by <tt>values</tt> in the given global
+     * matrix row at columns specified by col_indices in the sparse_matrix.
+     *
+     * The optional parameter <tt>elide_zero_values</tt> can be used to
+     * specify whether zero values should be added anyway or these should be
+     * filtered away and only non-zero data is added. The default value is
+     * <tt>true></tt>, i.e., zero values won't be added into the matrix.
+     *
+     * This function only works on the host.
+     */
+    template <typename Number2>
+    void add (const size_type  row,
+              const size_type  n_cols,
+              const size_type *col_indices,
+              const Number2   *values,
+              const bool       elide_zero_values = true,
+              const bool       col_indices_are_sorted = false);
+
+    //@}
+    /**
+     * @name 4: Access to underlying Paralution data
+     */
+    /**
+     * Return a constant reference to the underlying Paralution LocalMatrix
+     * data.
+     */
+    paralution::LocalMatrix<Number> const &paralution_matrix() const;
+
+    /**
+     * Return a reference to the underlying Paralution LocalMatrix data.
+     */
+    paralution::LocalMatrix<Number>& paralution_matrix();
+    //@}
+
+  private :
+    /**
+     * Underlying Paralution LocalMatrix<Number>.
+     */
+    paralution::LocalMatrix<Number> local_matrix;
+
+    /**
+     * Temporary SparseMatrix used to build the Paralution LocalMatrix.
+     */
+    ::dealii::SparseMatrix<Number> sparse_matrix;
+  };
+
+
+
+// ------------------- inline functions --------------
+
+  template <typename Number>
+  inline SparseMatrix<Number>::SparseMatrix() {}
+
+
+
+  template <typename Number>
+  inline SparseMatrix<Number>::SparseMatrix(SparsityPattern const &sparsity_pattern)
+  {
+    reinit(sparsity_pattern);
+  }
+
+
+
+  template <typename Number>
+  inline SparseMatrix<Number>::~SparseMatrix()
+  {
+    local_matrix.clear();
+  }
+
+
+
+  template <typename Number>
+  inline void SparseMatrix<Number>::reinit(SparsityPattern const &sparsity_pattern)
+  {
+    local_matrix.clear();
+    sparse_matrix.reinit(sparsity_pattern);
+  }
+
+
+
+  template <typename Number>
+  inline typename SparseMatrix<Number>::size_type SparseMatrix<Number>::m() const
+  {
+    return local_matrix.get_nrows();
+  }
+
+
+
+  template <typename Number>
+  inline typename SparseMatrix<Number>::size_type SparseMatrix<Number>::n() const
+  {
+    return local_matrix.get_ncols();
+  }
+
+
+
+  template <typename Number>
+  inline void SparseMatrix<Number>::add(const size_type i,
+                                        const size_type j,
+                                        const Number    value)
+  {
+    sparse_matrix.add(i,j,value);
+  }
+
+
+
+  template <typename Number>
+  template <typename Number2>
+  inline void SparseMatrix<Number>::add(const std::vector<size_type> &indices,
+                                        const FullMatrix<Number2>    &full_matrix,
+                                        const bool                    elide_zero_values)
+  {
+    sparse_matrix.add(indices,full_matrix,elide_zero_values);
+  }
+
+
+
+  template <typename Number>
+  template <typename Number2>
+  inline void SparseMatrix<Number>::add(const size_type               row,
+                                        const std::vector<size_type> &col_indices,
+                                        const std::vector<Number2>   &values,
+                                        const bool                    elide_zero_values)
+  {
+    sparse_matrix.add(row,col_indices,values,elide_zero_values);
+  }
+
+  template <typename Number>
+  template <typename Number2>
+  inline void SparseMatrix<Number>::add(const size_type  row,
+                                        const size_type  n_cols,
+                                        const size_type *col_indices,
+                                        const Number2   *values,
+                                        const bool       elide_zero_values,
+                                        const bool       col_indices_are_sorted)
+  {
+    sparse_matrix.add(row,n_cols,col_indices,values,elide_zero_values,col_indices_are_sorted);
+  }
+
+
+
+  template <typename Number>
+  inline paralution::LocalMatrix<Number> const &SparseMatrix<Number>::paralution_matrix() const
+  {
+    return local_matrix;
+  }
+
+
+
+  template <typename Number>
+  inline paralution::LocalMatrix<Number>& SparseMatrix<Number>::paralution_matrix()
+  {
+    return local_matrix;
+  }
+}
+
+
+/*@}*/
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif // DEAL_II_WITH_PARALUTION
+
+/*----------------------------   paralution_sparse_matrix.h     ---------------------------*/
+
+#endif
+/*----------------------------   paralution_sparse_matrix.h     ---------------------------*/
index 7813163971f403f0ee05f63f72422be0fa9178a0..d0537b166d885a1c9edd1e892fcc06055b65050a 100644 (file)
@@ -40,7 +40,7 @@ namespace ParalutionWrappers
    * of vector is designed for use in either serial implementation or as a
    * localized copy on each processor. The implementation of this class is
    * based on the Paralution vector class LocalVector. The only requirement
-   * for this class to work is that Trilinos is installed with the same
+   * for this class to work is that Paralution is installed with the same
    * compiler as is used for compilation of deal.II.
    *
    * The interface of this class is modeled after the existing Vector class in
index 6f9519ae27cb1b2240fee81be3d1812abf91804a..6b4373df6b862e106047a078114409980113950f 100644 (file)
@@ -549,7 +549,7 @@ public:
   };
 
   /**
-   * @name Constructors and initalization
+   * @name Constructors and initialization
    */
 //@{
   /**
index 15c8731d6cfd11c8cb7a083ad5b2a07739699c95..82bf9eaedc667747f06f12eca2e8d5ed0703d73f 100644 (file)
@@ -496,7 +496,7 @@ namespace TrilinosWrappers
    *
    * The interface of this class is modeled after the existing
    * SparseMatrix class in deal.II. It has almost the same member
-   * functions, and is often exchangable. However, since Trilinos only
+   * functions, and is often exchangeable. However, since Trilinos only
    * supports a single scalar type (double), it is not templated, and only
    * works with doubles.
    *
index ebdcde19dee0fa1434a7df67d6d3e15ccf07a71f..f5dddee3a7d283c07ae6595d358c9d0b252513a3 100644 (file)
@@ -33,6 +33,7 @@ SET(_src
   matrix_lib.cc
   matrix_out.cc
   parallel_vector.cc
+  paralution_sparse_matrix.cc
   petsc_block_sparse_matrix.cc
   petsc_full_matrix.cc
   petsc_matrix_base.cc
diff --git a/deal.II/source/lac/paralution_sparse_matrix.cc b/deal.II/source/lac/paralution_sparse_matrix.cc
new file mode 100644 (file)
index 0000000..46cadb9
--- /dev/null
@@ -0,0 +1,92 @@
+// ---------------------------------------------------------------------
+// $Id: paralution_sparse_matrix.cc 31567 2013-11-06 18:01:36Z turcksin $
+//
+// Copyright (C) 2013 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+#include <deal.II/lac/paralution_sparse_matrix.h>
+
+#ifdef DEAL_II_WITH_PARALUTION
+
+DEAL_II_NAMESPACE_OPEN
+
+namespace ParalutionWrappers
+{
+  template <typename Number>
+  void SparseMatrix<Number>::convert_to_paralution_csr()
+  {
+    local_matrix.AllocateCSR("deal_ii_local_matrix",sparse_matrix.n_nonzero_elements(),
+                             sparse_matrix.m(),sparse_matrix.n());
+
+    //TODO: replace deprecated functions
+    std::vector<Number> val;
+    val.reserve(sparse_matrix.n_nonzero_elements());
+    typename ::dealii::SparseMatrix<Number>::iterator it = sparse_matrix.begin();
+    typename ::dealii::SparseMatrix<Number>::iterator end_it = sparse_matrix.end();
+    for (; it!=end_it; ++it)
+      val.push_back(it->value());
+
+    const size_type *colnums_ptr = sparse_matrix.get_sparsity_pattern().get_column_numbers();
+    const std::size_t *rowstart_ptr = sparse_matrix.get_sparsity_pattern().get_rowstart_indices();
+    std::vector<int> colnums(colnums_ptr,colnums_ptr+sparse_matrix.n_nonzero_elements());
+    std::vector<int> rowstart(rowstart_ptr,rowstart_ptr+sparse_matrix.m()+1);
+
+
+    // do the copying around of entries so that the diagonal entry is in the
+    // right place. note that this is easy to detect: since all entries apart
+    // from the diagonal entry are sorted, we know that the diagonal entry is
+    // in the wrong place if and only if its column index is larger than the
+    // column index of the second entry in a row
+    //
+    // ignore rows with only one or no entry
+    for (size_type row=0; row<sparse_matrix.m(); ++row)
+      {
+        // we may have to move some elements that are left of the diagonal
+        // but presently after the diagonal entry to the left, whereas the
+        // diagonal entry has to move to the right. we could first figure out
+        // where to move everything to, but for simplicity we just make a
+        // series of swaps instead (this is kind of a single run of
+        // bubble-sort, which gives us the desired result since the array is
+        // already "almost" sorted)
+        //
+        // in the first loop, the condition in the while-header also checks
+        // that the row has at least two entries and that the diagonal entry
+        // is really in the wrong place
+        int cursor = rowstart[row];
+        while ((cursor < rowstart[row+1]-1) &&
+               (colnums[cursor] > colnums[cursor+1]))
+          {
+            std::swap (colnums[cursor], colnums[cursor+1]);
+            std::swap (val[cursor], val[cursor+1]);
+            ++cursor;
+          }
+      }
+
+    local_matrix.CopyFromCSR(&rowstart[0],&colnums[0],&val[0]);
+
+    // Free the memory used by sparse_matrix.
+    sparse_matrix.clear();
+  }
+}
+
+// Explicit instantiations
+namespace ParalutionWrappers
+{
+  template void SparseMatrix<float>::convert_to_paralution_csr();
+
+  template void SparseMatrix<double>::convert_to_paralution_csr();
+}
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif // DEAL_II_WITH_PARALUTION

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.