00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00228 if (n>0)
00229 s << bi.block_size(0);
00230
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
00317 template <typename MatrixType>
00318 const bool IsBlockMatrix<MatrixType>::value;
00319
00320
00321
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
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