]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Re-organize block vectors.
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 2 May 2000 16:38:41 +0000 (16:38 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 2 May 2000 16:38:41 +0000 (16:38 +0000)
git-svn-id: https://svn.dealii.org/trunk@2783 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/doc/news/2000/c-3-0.html
deal.II/lac/include/lac/block_indices.h [new file with mode: 0644]
deal.II/lac/include/lac/block_vector.h
deal.II/lac/include/lac/block_vector.templates.h

index b38c17af0f7aefa32f755ba51f1061880df02fdb..bd633bd874b85d52dc1fb4222de0d4a4e06e46bd 100644 (file)
        vector and without copying around data. Their run-time is
        therefore independent of the length of the vectors.
        </p>
+
+  <li> <p>
+       New: <code class="class">BlockIndices</code>: Class that
+       manages the conversion of global indices into a block
+       vector/matrix/... to the indices local to each of the blocks. 
+       </p>  
 </ol>
 
 
diff --git a/deal.II/lac/include/lac/block_indices.h b/deal.II/lac/include/lac/block_indices.h
new file mode 100644 (file)
index 0000000..dba295c
--- /dev/null
@@ -0,0 +1,207 @@
+//----------------------------  block_indices.h  ---------------------------
+//    $Id$
+//    Version: $Name$
+//
+//    Copyright (C) 2000 by the deal.II authors
+//
+//    This file is subject to QPL and may not be  distributed
+//    without copyright and license information. Please refer
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//----------------------------  block_indices.h  ---------------------------
+#ifndef __deal2__block_indices_h
+#define __deal2__block_indices_h
+
+
+#include <vector>
+
+
+/**
+ * Class that manages the conversion of global indices into a block
+ * vector or matrix to the local indices within this block. This is
+ * required when you address a global element in a block vector and
+ * want to know which element within which block this is. It is also
+ * useful if a matrix is composed of several blocks, where you have to
+ * translate global row and column indices to local ones.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+template <int n_blocks>
+class BlockIndices
+{
+  public:
+
+                                    /**
+                                     * Defaulut constructor. Set all
+                                     * indices denoting the start of
+                                     * the blocks to zero.
+                                     */
+    BlockIndices ();
+
+                                    /**
+                                     * Constructor. Initialize the
+                                     * number of indices within each
+                                     * block from the given
+                                     * argument. The size of the
+                                     * vector shall be equal to
+                                     * #n_blocks#.
+                                     */
+    BlockIndices (const vector<unsigned int> &n);
+    
+                                    /**
+                                     * Reset the number of indices
+                                     * within each block from the
+                                     * given argument. The size of
+                                     * the vector shall be equal to
+                                     * #n_blocks#.
+                                     */
+    void reinit (const vector<unsigned int> &n);
+    
+                                    /**
+                                     * Return the block and the
+                                     * index within that block
+                                     * for the global index #i#. The
+                                     * first element of the pair is
+                                     * the block, the second the
+                                     * index within that.
+                                     */
+    pair<unsigned int,unsigned int> global_to_local (const unsigned int i) const;
+
+                                    /**
+                                     * Return the total number of
+                                     * indices accumulated over all
+                                     * blocks.
+                                     */
+    unsigned int total_size () const;
+
+                                    /**
+                                     * Copy operator.
+                                     */
+    BlockIndices<n_blocks> & operator = (const BlockIndices<n_blocks> &b);
+
+                                    /**
+                                     * Swap the contents of these two
+                                     * objects.
+                                     */
+    void swap (BlockIndices<n_blocks> &b);
+    
+  private:
+                                     /**
+                                     * Global starting index of each
+                                     * vector. The last and redundant
+                                     * value is the total number of
+                                     * entries.
+                                     */
+    unsigned int start_indices[n_blocks+1];
+};
+
+
+
+/* ---------------------- template and inline functions ------------------- */
+
+template <int n_blocks>
+inline
+BlockIndices<n_blocks>::BlockIndices ()
+{
+  for (unsigned int i=0; i<=n_blocks; ++i)
+    start_indices[i] = 0;
+};
+
+
+
+template <int n_blocks>
+inline
+BlockIndices<n_blocks>::BlockIndices (const vector<unsigned int> &n)
+{
+  reinit (n);
+};
+
+
+
+template <int n_blocks>
+inline
+void
+BlockIndices<n_blocks>::reinit (const vector<unsigned int> &n)
+{
+  Assert(n.size()==n_blocks,
+        ExcDimensionMismatch(n.size(), n_blocks));
+
+  start_indices[0] = 0;
+  for (unsigned int i=1; i<=n_blocks; ++i)
+    start_indices[i] = start_indices[i-1] + n[i];
+};
+
+
+
+template <int n_blocks>
+inline
+pair<unsigned int,unsigned int>
+BlockIndices<n_blocks>::find (const unsigned int i) const
+{
+  Assert (i<total_size(), ExcIndexRange(i, 0, total_size()));
+
+  int block = n_blocks-1;
+  while (i < start_indices[block])
+    --block;
+
+  return make_pair<unsigned int>(block, i-start_indices[block]);
+};
+
+
+
+template <int n_blocks>
+inline
+unsigned int
+BlockIndices<n_blocks>::total_size () const
+{
+  return start_indices[n_blocks];
+};
+
+
+
+template <int n_blocks>
+inline
+BlockIndices<n_blocks> &
+BlockIndices<n_blocks>::operator = (const BlockIndices<n_blocks> &b)
+{
+  for (unsigned int i=0; i<=n_blocks; ++i)
+    start_indices[i] = b.start_indices[i];
+  return *this;
+};
+
+
+
+template <int n_blocks>
+inline
+void
+BlockIndices<n_blocks>::swap (BlockIndices<n_blocks> &b)
+{
+  for (unsigned int i=0; i<=n_blocks; ++i)
+    std::swap (start_indices[i], b.start_indices[i]);
+};
+
+
+
+/* ----------------- global functions ---------------------------- */
+
+
+/**
+ * Global function #swap# which overloads the default implementation
+ * of the C++ standard library which uses a temporary object. The
+ * function simply exchanges the data of the two objects.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+template <int n_blocks>
+inline
+void swap (BlockIndices<n_blocks> &u,
+          BlockIndices<n_blocks> &v)
+{
+  u.swap (v);
+};
+
+
+
+
+#endif
index 30d81f8bbfd858a6f0d49983638e0c311ba64f7a..d7e55fd8feb2064e0ce755c03495015feef63838 100644 (file)
 
 
 #include <lac/vector.h>
+#include <lac/block_indices.h>
 #include <base/exceptions.h>
 #include <cstdio>
 #include <vector>
 
+
 /**
  * Several vectors of data. 
  *
  * The BlockVector is a collection of normal LAC-#Vector#s. Each of
  * the vectors inside can have a different size.
  *
- * The functionality of #BlockVector# includes everything, a #Vector#
+ * The functionality of #BlockVector# includes everything a #Vector#
  * can do, plus the access to a single #Vector# inside the
  * #BlockVector# by #block(i)#.
  *
@@ -69,7 +71,7 @@ class BlockVector
                                      * Constructor. Set dimension to #n# and
                                      * initialize all elements with zero.
                                      */
-    BlockVector (const vector<unsigned int>n);
+    BlockVector (const vector<unsigned int> &n);
 
                                      /**
                                      * Destructor. Clears memory
@@ -93,8 +95,8 @@ class BlockVector
                                      * On #fast==false#, the vector is filled by
                                      * zeros.
                                      */ 
-    void reinit (const vector<unsigned int>N,
-                const bool         fast=false);
+    void reinit (const vector<unsigned int> &N,
+                const bool                  fast=false);
     
                                     /**
                                      * Change the dimension to that of the
@@ -106,7 +108,7 @@ class BlockVector
                                      * #reinit (V.size(), fast)#.
                                      */
     void reinit (const BlockVector<n_blocks,Number> &V,
-                const bool            fast=false);
+                const bool                          fast=false);
     
                                     /**
                                      * Set all entries to zero. Equivalent to
@@ -145,12 +147,12 @@ class BlockVector
                                     /**
                                      * Access to a single block.
                                      */
-    Vector<Number>& block(unsigned int i);
+    Vector<Number>& block (const unsigned int i);
     
                                     /**
                                      * Read-only access to a single block.
                                      */
-    const Vector<Number>& block(unsigned int i) const;
+    const Vector<Number>& block (const unsigned int i) const;
     
                                     /**
                                      * $U(0-N) = s$: fill all components.
@@ -456,12 +458,13 @@ class BlockVector
                                      */
     Vector<Number> components[n_blocks];
 
-                                     /**
-                                     * Global starting index of each vector.
-                                     * The last andredundant value is the total
-                                     * number of entries.
+                                    /**
+                                     * Object managing the
+                                     * transformation between global
+                                     * indices and indices within the
+                                     * different blocks.
                                      */
-    unsigned int start[n_blocks+1];
+    BlockIndices<n_blocks> block_indices;
 };
 
 
@@ -472,7 +475,7 @@ template <int n_blocks, typename Number>
 inline
 unsigned int BlockVector<n_blocks,Number>::size () const
 {
-  return start[n_blocks];
+  return block_indices.total_size();
 }
 
 
@@ -508,12 +511,9 @@ template <int n_blocks, typename Number>
 inline
 Number BlockVector<n_blocks,Number>::operator() (const unsigned int i) const
 {
-  //  Assert (i<start[n_blocks], ExcInvalidIndex(i,dim));
-
-  int j=n_blocks-1;
-    while ((start[j]>i) && (j!=0)) --j;
-
-  return components[j](i-start[j]);
+  const pair<unsigned int,unsigned int> local_index
+    = block_indices.global_to_local (i);
+  return components[local_index.first](local_index.second);
 }
 
 
@@ -521,13 +521,12 @@ template <int n_blocks, typename Number>
 inline
 Number& BlockVector<n_blocks,Number>::operator() (const unsigned int i)
 {
-  //  Assert (i<dim, ExcInvalidIndex(i,dim));
+  const pair<unsigned int,unsigned int> local_index
+    = block_indices.global_to_local (i);
+  return components[local_index.first](local_index.second);
+}
 
-  int j=n_blocks-1;
-    while ((start[j]>i) && (j!=0)) --j;
 
-  return components[j](i-start[j]);
-}
 
 template <int n_blocks, typename Number>
 inline
@@ -559,7 +558,8 @@ BlockVector<n_blocks,Number>::block(unsigned int i) const
  */
 template <int n_blocks, typename Number>
 inline
-void swap (BlockVector<n_blocks,Number> &u, BlockVector<n_blocks,Number> &v)
+void swap (BlockVector<n_blocks,Number> &u,
+          BlockVector<n_blocks,Number> &v)
 {
   u.swap (v);
 };
index e7c262d854c9d67d370a99bda609ed1d943bc34c..164ff2d602f83bac231e59d95c7d6b4f94242c91 100644 (file)
@@ -26,19 +26,16 @@ static inline Number sqr (const Number x)
 };
 
 
+
 template <int n_blocks, typename Number>
 BlockVector<n_blocks,Number>::BlockVector ()
-{
-  for (unsigned int i=0;i<=n_blocks;++i)
-    start[n_blocks] = 0;
-}
+{}
+
 
 
 template <int n_blocks, typename Number>
-BlockVector<n_blocks,Number>::BlockVector (const vector<unsigned int>n)
+BlockVector<n_blocks,Number>::BlockVector (const vector<unsigned int> &n)
 {
-  Assert(n.size()==n_blocks, ExcDimensionMismatch(n.size(), n_blocks));
-
   reinit (n, false);
 }
 
@@ -46,12 +43,9 @@ BlockVector<n_blocks,Number>::BlockVector (const vector<unsigned int>& n)
 template <int n_blocks, typename Number>
 BlockVector<n_blocks,Number>::BlockVector (const BlockVector<n_blocks,Number>& v)
 {
-  for (unsigned int i=0;i<n_blocks;++i)
-    {
-      start[i] = v.start[i];
-      components[i] = v.components[i];
-    }
-  start[n_blocks] = v.start[n_blocks];
+  block_indices = v.block_indices;
+  for (unsigned int i=0; i<n_blocks; ++i)
+    components[i] = v.components[i];
 }
 
 
@@ -74,41 +68,29 @@ BlockVector<n_blocks,Number>::BlockVector (const BlockVector<n_blocks,Number>& v
 
 
 template <int n_blocks, typename Number>
-void BlockVector<n_blocks,Number>::reinit (const vector<unsigned int>n,
-                                           const bool fast)
+void BlockVector<n_blocks,Number>::reinit (const vector<unsigned int> &n,
+                                          const bool                  fast)
 {
-  Assert (n.size() == n_blocks,
-         ExcDimensionsDontMatch(n.size(), n_blocks));
-  
-  unsigned int j=0;
-  start[0] = j;
+  block_indices.reinit (n);
   for (unsigned int i=0; i<n_blocks; ++i)
-    {
-      components[i].reinit(n[i], fast);
-      j += n[i];
-      start[i+1] = j;
-    }
+    components[i].reinit(n[i], fast);
 }
 
 
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::reinit (const BlockVector<n_blocks,Number>& v,
-                                           const bool fast)
+                                          const bool fast)
 {
+  block_indices = v.block_indices;
   for (unsigned int i=0;i<n_blocks;++i)
-    {
-      components[i].reinit(v.components[i], fast);
-      start[i] = v.start[i];
-    }
-  start[n_blocks] = v.start[n_blocks];
+    components[i].reinit(v.components[i], fast);
 }
 
 
 
 template <int n_blocks, typename Number>
 BlockVector<n_blocks,Number>::~BlockVector ()
-{
-}
+{}
 
 
 
@@ -116,11 +98,8 @@ template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::swap (BlockVector<n_blocks,Number> &v)
 {
   for (unsigned int i=0; i<n_blocks; ++i)
-    {
-      swap (components[i], v.components[i]);
-      swap (start[i],      v.start[i]);
-    };
-  swap (start[n_blocks], v.start[n_blocks]);
+    ::swap (components[i], v.components[i]);
+  ::swap (block_indices, v.block_indices);
 };
 
 
@@ -217,7 +196,8 @@ Number BlockVector<n_blocks,Number>::linfty_norm () const
 
 
 template <int n_blocks, typename Number>
-BlockVector<n_blocks,Number>& BlockVector<n_blocks,Number>::operator += (const BlockVector<n_blocks,Number>& v)
+BlockVector<n_blocks,Number>&
+BlockVector<n_blocks,Number>::operator += (const BlockVector<n_blocks,Number>& v)
 {
   add (v);
   return *this;
@@ -225,11 +205,12 @@ BlockVector<n_blocks,Number>& BlockVector<n_blocks,Number>::operator += (const B
 
 
 template <int n_blocks, typename Number>
-BlockVector<n_blocks,Number>& BlockVector<n_blocks,Number>::operator -= (const BlockVector<n_blocks,Number>& v)
+BlockVector<n_blocks,Number>&
+BlockVector<n_blocks,Number>::operator -= (const BlockVector<n_blocks,Number>& v)
 {
   for (unsigned int i=0;i<n_blocks;++i)
     {
-       components[i] -= v.components[i];
+      components[i] -= v.components[i];
     }
   return *this;
 }
@@ -257,7 +238,7 @@ void BlockVector<n_blocks,Number>::add (const BlockVector<n_blocks,Number>& v)
 
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::add (const Number a,
-                                        const BlockVector<n_blocks,Number>& v)
+                                       const BlockVector<n_blocks,Number>& v)
 {
   for (unsigned int i=0;i<n_blocks;++i)
     {
@@ -268,9 +249,9 @@ void BlockVector<n_blocks,Number>::add (const Number a,
 
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::add (const Number a,
-                                        const BlockVector<n_blocks,Number>& v,
-                                        const Number b,
-                                        const BlockVector<n_blocks,Number>& w)
+                                       const BlockVector<n_blocks,Number>& v,
+                                       const Number b,
+                                       const BlockVector<n_blocks,Number>& w)
 {
   for (unsigned int i=0;i<n_blocks;++i)
     {
@@ -281,7 +262,7 @@ void BlockVector<n_blocks,Number>::add (const Number a,
 
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::sadd (const Number x,
-                                         const BlockVector<n_blocks,Number>& v)
+                                        const BlockVector<n_blocks,Number>& v)
 {
   for (unsigned int i=0;i<n_blocks;++i)
     {
@@ -292,7 +273,7 @@ void BlockVector<n_blocks,Number>::sadd (const Number x,
 
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::sadd (const Number x, const Number a,
-                                         const BlockVector<n_blocks,Number>& v)
+                                        const BlockVector<n_blocks,Number>& v)
 {
   for (unsigned int i=0;i<n_blocks;++i)
     {
@@ -303,9 +284,9 @@ void BlockVector<n_blocks,Number>::sadd (const Number x, const Number a,
 
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::sadd (const Number x, const Number a,
-                                         const BlockVector<n_blocks,Number>& v,
-                                         const Number b,
-                                         const BlockVector<n_blocks,Number>& w)
+                                        const BlockVector<n_blocks,Number>& v,
+                                        const Number b,
+                                        const BlockVector<n_blocks,Number>& w)
 {
   for (unsigned int i=0;i<n_blocks;++i)
     {
@@ -316,11 +297,11 @@ void BlockVector<n_blocks,Number>::sadd (const Number x, const Number a,
 
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::sadd (const Number x, const Number a,
-                                         const BlockVector<n_blocks,Number>& v,
-                                         const Number b,
-                                         const BlockVector<n_blocks,Number>& w,
-                                         const Number c,
-                                         const BlockVector<n_blocks,Number>& y)
+                                        const BlockVector<n_blocks,Number>& v,
+                                        const Number b,
+                                        const BlockVector<n_blocks,Number>& w,
+                                        const Number c,
+                                        const BlockVector<n_blocks,Number>& y)
 {
   for (unsigned int i=0;i<n_blocks;++i)
     {
@@ -342,9 +323,9 @@ void BlockVector<n_blocks,Number>::scale (const Number factor)
 
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::equ (const Number a,
-                                        const BlockVector<n_blocks,Number>& v,
-                                        const Number b,
-                                        const BlockVector<n_blocks,Number>& w)
+                                       const BlockVector<n_blocks,Number>& v,
+                                       const Number b,
+                                       const BlockVector<n_blocks,Number>& w)
 {
   for (unsigned int i=0;i<n_blocks;++i)
     {
@@ -355,7 +336,7 @@ void BlockVector<n_blocks,Number>::equ (const Number a,
 
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::equ (const Number a,
-                                        const BlockVector<n_blocks,Number>& v)
+                                       const BlockVector<n_blocks,Number>& v)
 {
   for (unsigned int i=0;i<n_blocks;++i)
     {
@@ -402,9 +383,9 @@ BlockVector<n_blocks,Number>::operator = (const BlockVector<n_blocks, Number2>&
 
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::print (ostream &out,
-                           unsigned int precision,
-                           bool scientific,
-                           bool across) const
+                                         unsigned int precision,
+                                         bool scientific,
+                                         bool across) const
 {
   for (unsigned int i=0;i<n_blocks;++i)
     {

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.