20 #ifndef LIBMESH_COUPLING_MATRIX_H
21 #define LIBMESH_COUPLING_MATRIX_H
24 #include "libmesh/libmesh_common.h"
36 class ConstCouplingAccessor;
37 class CouplingAccessor;
39 class ConstCouplingRow;
41 class ConstCouplingRowConstIterator;
59 CouplingMatrix (
const std::size_t n=0);
67 bool operator() (
const std::size_t i,
68 const std::size_t j)
const;
76 CouplingAccessor operator() (
const std::size_t i,
83 std::size_t size()
const;
89 void resize(
const std::size_t n);
107 CouplingMatrix & operator&= (
const CouplingMatrix & other);
110 friend class ConstCouplingAccessor;
111 friend class CouplingAccessor;
112 friend class ConstCouplingRow;
113 friend class ConstCouplingRowConstIterator;
123 typedef std::pair<std::size_t, std::size_t> range_type;
124 typedef std::vector<range_type> rc_type;
138 class ConstCouplingAccessor
146 ConstCouplingAccessor(std::size_t loc_in,
147 const CouplingMatrix & mat_in) :
148 _location(loc_in), _mat(mat_in)
150 libmesh_assert_less(_location, _mat.size() * _mat.size());
157 operator bool()
const
159 const std::size_t max_size = std::numeric_limits<std::size_t>::max();
162 CouplingMatrix::rc_type::const_iterator lb = std::upper_bound
163 (_mat._ranges.begin(), _mat._ranges.end(),
164 std::make_pair(_location, max_size));
165 if (lb!=_mat._ranges.begin())
168 lb=_mat._ranges.end();
171 if (lb == _mat._ranges.end())
174 const std::size_t lastloc = lb->second;
177 const std::size_t firstloc = lb->first;
178 libmesh_assert_less_equal(firstloc, lastloc);
179 libmesh_assert_less_equal(firstloc, _location);
181 CouplingMatrix::rc_type::const_iterator next = lb;
183 if (next != _mat._ranges.end())
186 libmesh_assert_greater(next->first, lastloc+1);
190 return (lastloc >= _location);
197 std::size_t _location;
201 const CouplingMatrix & _mat;
208 class CouplingAccessor :
public ConstCouplingAccessor
216 CouplingAccessor(std::size_t loc_in,
217 CouplingMatrix & mat_in) :
218 ConstCouplingAccessor(loc_in, mat_in), _my_mat(mat_in) {}
225 template <
typename T>
226 CouplingAccessor & operator = (T new_value)
229 const bool as_bool = new_value;
230 libmesh_assert_equal_to(new_value, as_bool);
241 CouplingAccessor & operator = (
bool new_value)
243 const std::size_t max_size = std::numeric_limits<std::size_t>::max();
246 CouplingMatrix::rc_type::iterator lb =
247 std::upper_bound (_my_mat._ranges.begin(), _my_mat._ranges.end(),
248 std::make_pair(_location, max_size));
249 if (lb!=_my_mat._ranges.begin())
252 lb=_my_mat._ranges.end();
255 if (lb == _my_mat._ranges.end())
257 if (new_value ==
true)
258 _my_mat._ranges.emplace
259 (_my_mat._ranges.begin(), _location, _location);
263 const std::size_t firstloc = lb->first;
264 const std::size_t lastloc = lb->second;
265 libmesh_assert_less_equal(firstloc, lastloc);
266 libmesh_assert_less_equal(firstloc, _location);
270 CouplingMatrix::rc_type::const_iterator next = lb;
272 if (next != _my_mat._ranges.end())
275 libmesh_assert_greater(next->first, lastloc+1);
281 if (new_value ==
false)
284 if (_location == firstloc)
286 if (_location == lastloc)
288 _my_mat._ranges.erase(lb);
292 libmesh_assert_less(lb->first, lastloc);
297 else if (_location == lastloc)
299 libmesh_assert_less(firstloc, lb->second);
303 else if (_location < lastloc)
305 libmesh_assert_less_equal(_location + 1, lastloc);
307 lb->first = _location + 1;
309 libmesh_assert_less_equal(firstloc, _location - 1);
311 _my_mat._ranges.emplace(lb, firstloc, _location - 1);
317 CouplingMatrix::rc_type::iterator next = lb;
319 const std::size_t nextloc =
320 (next == _my_mat._ranges.end()) ?
321 std::numeric_limits<std::size_t>::max() :
325 libmesh_assert_greater(nextloc, lastloc + 1);
328 if (_location > lastloc)
331 if (_location == lastloc + 1)
333 if (_location == nextloc - 1)
335 next->first = firstloc;
336 _my_mat._ranges.erase(lb);
345 if (_location == nextloc - 1)
348 _my_mat._ranges.emplace(next, _location, _location);
361 CouplingMatrix & _my_mat;
369 class ConstCouplingRow
378 ConstCouplingRow(std::size_t row_in,
379 const CouplingMatrix & mat_in) :
380 _row_i(row_in), _mat(mat_in),
381 _end_location(_row_i * _mat.size() + _mat.size() - 1)
383 libmesh_assert_less(_row_i, _mat.size());
386 _begin_location = _end_location;
388 const std::size_t max_size = std::numeric_limits<std::size_t>::max();
391 _begin_it = std::upper_bound
392 (_mat._ranges.begin(), _mat._ranges.end(),
393 std::make_pair(_begin_location, max_size));
394 if (_begin_it != _mat._ranges.begin())
397 _begin_it = _mat._ranges.end();
400 if (_begin_it == _mat._ranges.end())
401 _begin_location = max_size;
404 const std::size_t lastloc = _begin_it->second;
406 std::size_t zero_location = _row_i * _mat.size();
407 if (zero_location > lastloc)
409 _begin_location = max_size;
410 _begin_it = _mat._ranges.end();
414 while (_begin_it != _mat._ranges.begin())
416 CouplingMatrix::rc_type::const_iterator prev =
420 if (prev->second < zero_location)
425 if (_begin_it->first < zero_location)
426 _begin_location = zero_location;
428 _begin_location = _begin_it->first;
436 typedef ConstCouplingRowConstIterator const_iterator;
441 const_iterator begin()
const;
446 const_iterator end()
const;
455 bool operator== (
const ConstCouplingRow & other)
const
458 libmesh_assert(&_mat == &other._mat);
460 return ((_begin_location == other._begin_location) &&
461 (_begin_it == other._begin_it));
471 bool operator!= (
const ConstCouplingRow & other)
const
473 return !(*
this == other);
477 friend class ConstCouplingRowConstIterator;
480 const CouplingMatrix & _mat;
483 std::size_t _begin_location;
486 const std::size_t _end_location;
489 CouplingMatrix::rc_type::const_iterator _begin_it;
497 class ConstCouplingRowConstIterator
507 ConstCouplingRowConstIterator(
const ConstCouplingRow & row_in,
509 CouplingMatrix::rc_type::const_iterator it_in) :
515 if (_it != _row._mat._ranges.end())
517 libmesh_assert_less_equal(_it->first, _location);
518 libmesh_assert_less_equal(_location, _it->second);
522 libmesh_assert_equal_to
523 (_location, std::numeric_limits<size_t>::max());
535 libmesh_assert_not_equal_to
536 (_location, std::numeric_limits<std::size_t>::max());
537 return _location % _row._mat.size();
545 ConstCouplingRowConstIterator & operator++ ()
547 libmesh_assert_not_equal_to
548 (_location, std::numeric_limits<std::size_t>::max());
550 (_it != _row._mat._ranges.end());
552 if (_location >= _it->second)
557 if (_it == _row._mat._ranges.end())
558 _location = std::numeric_limits<std::size_t>::max();
561 _location = _it->first;
563 if (_location > _row._end_location)
564 _location = std::numeric_limits<std::size_t>::max();
568 else if (_location >= _row._end_location)
569 _location = std::numeric_limits<std::size_t>::max();
583 bool operator== (
const ConstCouplingRowConstIterator & other)
const
586 libmesh_assert(_row == other._row);
588 return (_location == other._location);
598 bool operator!= (
const ConstCouplingRowConstIterator & other)
const
600 return !(*
this == other);
605 std::size_t _location;
606 const ConstCouplingRow & _row;
608 CouplingMatrix::rc_type::const_iterator _it;
616 ConstCouplingRow::const_iterator ConstCouplingRow::begin()
const
618 return const_iterator (*
this, _begin_location, _begin_it);
622 ConstCouplingRow::const_iterator ConstCouplingRow::end()
const
624 return const_iterator
625 (*
this, std::numeric_limits<std::size_t>::max(),
634 CouplingMatrix::CouplingMatrix (
const std::size_t n) :
643 bool CouplingMatrix::operator() (
const std::size_t i,
644 const std::size_t j)
const
646 libmesh_assert_less (i, _size);
647 libmesh_assert_less (j, _size);
649 const std::size_t location = std::size_t(i)*_size + j;
651 return bool(ConstCouplingAccessor(location, *
this));
658 CouplingAccessor CouplingMatrix::operator() (
const std::size_t i,
661 const std::size_t location = std::size_t(i)*_size + j;
663 return CouplingAccessor(location, *
this);
669 std::size_t CouplingMatrix::size()
const
677 void CouplingMatrix::resize(
const std::size_t n)
687 void CouplingMatrix::clear()
695 bool CouplingMatrix::empty()
const
704 #endif // LIBMESH_COUPLING_MATRIX_H
bool operator==(const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &x, const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &y)
boostcopy::enable_if_c< ScalarTraits< Scalar >::value, TypeNTensor< N, typename CompareTypes< Scalar, T >::supertype > >::type operator*(const Scalar &, const TypeNTensor< N, T > &)
bool operator!=(const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &x, const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &y)