include/deal.II/lac/block_indices.h

00001 //---------------------------------------------------------------------------
00002 //    @f$Id: block_indices.h 25345 2012-03-31 08:37:04Z bangerth @f$
00003 //
00004 //    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012 by the deal.II authors
00005 //
00006 //    This file is subject to QPL and may not be  distributed
00007 //    without copyright and license information. Please refer
00008 //    to the file deal.II/doc/license.html for the  text  and
00009 //    further information on this license.
00010 //
00011 //---------------------------------------------------------------------------
00012 #ifndef __deal2__block_indices_h
00013 #define __deal2__block_indices_h
00014 
00015 
00016 #include <deal.II/base/config.h>
00017 #include <deal.II/base/subscriptor.h>
00018 #include <deal.II/base/exceptions.h>
00019 #include <deal.II/base/logstream.h>
00020 #include <vector>
00021 
00022 DEAL_II_NAMESPACE_OPEN
00023 
00024 
00049 class BlockIndices : public Subscriptor
00050 {
00051   public:
00052 
00058     BlockIndices ();
00059 
00067     BlockIndices (const std::vector<unsigned int> &n);
00068 
00073     explicit BlockIndices(const unsigned int n_blocks, const unsigned int block_size = 0);
00074 
00080     void reinit (const unsigned int n_blocks,
00081                  const unsigned int n_elements_per_block);
00082 
00092     void reinit (const std::vector<unsigned int> &n);
00093 
00099     void push_back(const unsigned int size);
00100 
00105 
00109     unsigned int size () const;
00110 
00118     unsigned int total_size () const;
00119 
00123     unsigned int block_size (const unsigned int i) const;
00124 
00126 
00141 
00150     std::pair<unsigned int,unsigned int>
00151     global_to_local (const unsigned int i) const;
00152 
00157     unsigned int local_to_global (const unsigned int block,
00158                                   const unsigned int index) const;
00159 
00163     unsigned int block_start (const unsigned int i) const;
00165 
00169     BlockIndices & operator = (const BlockIndices &b);
00170 
00177     bool operator == (const BlockIndices &b) const;
00178 
00183     void swap (BlockIndices &b);
00184 
00190     std::size_t memory_consumption () const;
00191 
00192   private:
00201     unsigned int n_blocks;
00202 
00209     std::vector<unsigned int> start_indices;
00210 };
00211 
00212 
00221 inline
00222 LogStream&
00223 operator << (LogStream& s, const BlockIndices& bi)
00224 {
00225   const unsigned int n = bi.size();
00226   s << n << ":[";
00227                                    // Write first size without leading space
00228   if (n>0)
00229     s << bi.block_size(0);
00230                                    // Write all other sizes
00231   for (unsigned int i=1;i<n;++i)
00232     s << ' ' << bi.block_size(i);
00233   s << "]->" << bi.total_size();
00234   return s;
00235 }
00236 
00237 
00238 template <typename MatrixType> class BlockMatrixBase;
00239 template <typename SparsityType> class BlockSparsityPatternBase;
00240 template <typename number>     class BlockSparseMatrixEZ;
00241 
00259 template <typename MatrixType>
00260 struct IsBlockMatrix
00261 {
00262   private:
00263     struct yes_type { char c[1]; };
00264     struct no_type  { char c[2]; };
00265 
00273     template <typename T>
00274     static yes_type check_for_block_matrix (const BlockMatrixBase<T> *);
00275 
00282     template <typename T>
00283     static yes_type check_for_block_matrix (const BlockSparsityPatternBase<T> *);
00284 
00291     template <typename T>
00292     static yes_type check_for_block_matrix (const BlockSparseMatrixEZ<T> *);
00293 
00299     static no_type check_for_block_matrix (...);
00300 
00301   public:
00309     static const bool value = (sizeof(check_for_block_matrix
00310                                       ((MatrixType*)0))
00311                                ==
00312                                sizeof(yes_type));
00313 };
00314 
00315 
00316 // instantiation of the static member
00317 template <typename MatrixType>
00318 const bool IsBlockMatrix<MatrixType>::value;
00319 
00320 
00321 /* ---------------------- template and inline functions ------------------- */
00322 
00323 inline
00324 void
00325 BlockIndices::reinit (const unsigned int nb,
00326                       const unsigned int block_size)
00327 {
00328   n_blocks = nb;
00329   start_indices.resize(n_blocks+1);
00330   for (unsigned int i=0; i<=n_blocks; ++i)
00331     start_indices[i] = i * block_size;
00332 }
00333 
00334 
00335 
00336 inline
00337 void
00338 BlockIndices::reinit (const std::vector<unsigned int> &n)
00339 {
00340   if (start_indices.size() != n.size()+1)
00341     {
00342       n_blocks = n.size();
00343       start_indices.resize(n_blocks+1);
00344     }
00345   start_indices[0] = 0;
00346   for (unsigned int i=1; i<=n_blocks; ++i)
00347     start_indices[i] = start_indices[i-1] + n[i-1];
00348 }
00349 
00350 
00351 inline
00352 BlockIndices::BlockIndices ()
00353                 :
00354                 n_blocks(0),
00355                 start_indices(1, 0)
00356 {}
00357 
00358 
00359 
00360 inline
00361 BlockIndices::BlockIndices (
00362   const unsigned int n_blocks,
00363   const unsigned int block_size)
00364                 :
00365                 n_blocks(n_blocks),
00366                 start_indices(n_blocks+1)
00367 {
00368   for (unsigned int i=0; i<=n_blocks; ++i)
00369     start_indices[i] = i * block_size;
00370 }
00371 
00372 
00373 
00374 inline
00375 BlockIndices::BlockIndices (const std::vector<unsigned int> &n)
00376                 :
00377                 n_blocks(n.size()),
00378                 start_indices(n.size()+1)
00379 {
00380   reinit (n);
00381 }
00382 
00383 
00384 inline
00385 void
00386 BlockIndices::push_back(const unsigned int sz)
00387 {
00388   start_indices.push_back(start_indices[n_blocks]+sz);
00389   ++n_blocks;
00390   AssertDimension(start_indices.size(), n_blocks+1);
00391 }
00392 
00393 
00394 inline
00395 std::pair<unsigned int,unsigned int>
00396 BlockIndices::global_to_local (const unsigned int i) const
00397 {
00398   Assert (i<total_size(), ExcIndexRange(i, 0, total_size()));
00399 
00400   int block = n_blocks-1;
00401   while (i < start_indices[block])
00402     --block;
00403 
00404   return std::make_pair<unsigned int>(block, i-start_indices[block]);
00405 }
00406 
00407 
00408 inline
00409 unsigned int
00410 BlockIndices::local_to_global (const unsigned int block,
00411                                const unsigned int index) const
00412 {
00413   Assert (block < n_blocks, ExcIndexRange(block, 0, n_blocks));
00414   Assert (index < start_indices[block+1]-start_indices[block],
00415           ExcIndexRange (index, 0, start_indices[block+1]-start_indices[block]));
00416 
00417   return start_indices[block]+index;
00418 }
00419 
00420 
00421 inline
00422 unsigned int
00423 BlockIndices::size () const
00424 {
00425   return n_blocks;
00426 }
00427 
00428 
00429 
00430 inline
00431 unsigned int
00432 BlockIndices::total_size () const
00433 {
00434   if (n_blocks == 0) return 0;
00435   return start_indices[n_blocks];
00436 }
00437 
00438 
00439 
00440 inline
00441 unsigned int
00442 BlockIndices::block_size (const unsigned int block) const
00443 {
00444   Assert (block < n_blocks, ExcIndexRange(block, 0, n_blocks));
00445   return start_indices[block+1]-start_indices[block];
00446 }
00447 
00448 
00449 
00450 inline
00451 unsigned int
00452 BlockIndices::block_start (const unsigned int block) const
00453 {
00454   Assert (block < n_blocks, ExcIndexRange(block, 0, n_blocks));
00455   return start_indices[block];
00456 }
00457 
00458 
00459 
00460 inline
00461 BlockIndices &
00462 BlockIndices::operator = (const BlockIndices &b)
00463 {
00464   start_indices = b.start_indices;
00465   n_blocks = b.n_blocks;
00466   return *this;
00467 }
00468 
00469 
00470 
00471 inline
00472 bool
00473 BlockIndices::operator == (const BlockIndices &b) const
00474 {
00475   if (n_blocks != b.n_blocks)
00476     return false;
00477 
00478   for (unsigned int i=0; i<=n_blocks; ++i)
00479     if (start_indices[i] != b.start_indices[i])
00480       return false;
00481 
00482   return true;
00483 }
00484 
00485 
00486 
00487 inline
00488 void
00489 BlockIndices::swap (BlockIndices &b)
00490 {
00491   Assert (n_blocks == b.n_blocks,
00492           ExcDimensionMismatch(n_blocks, b.n_blocks));
00493 
00494   for (unsigned int i=0; i<=n_blocks; ++i)
00495     std::swap (start_indices[i], b.start_indices[i]);
00496 }
00497 
00498 
00499 
00500 inline
00501 std::size_t
00502 BlockIndices::memory_consumption () const
00503 {
00504   return (sizeof(*this) +
00505           start_indices.size() * sizeof(start_indices[0]));
00506 }
00507 
00508 
00509 
00510 /* ----------------- global functions ---------------------------- */
00511 
00512 
00521 inline
00522 void swap (BlockIndices &u, BlockIndices &v)
00523 {
00524   u.swap (v);
00525 }
00526 
00527 
00528 
00529 
00530 DEAL_II_NAMESPACE_CLOSE
00531 
00532 #endif
00533 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

deal.II documentation generated on Thu May 17 2012 20:04:39 by doxygen 1.7.3