*/
std::auto_ptr<const CellIteratorBase> present_cell;
+ /**
+ * A signal connection we use to ensure we get informed whenever the
+ * triangulation changes. We need to know about that because it
+ * invalidates all cell iterators and, as part of that, the
+ * 'present_cell' iterator we keep around between subsequent
+ * calls to reinit() in order to compute the cell similarity.
+ */
+ boost::signals2::connection tria_listener;
+
+ /**
+ * A function that is connected to the triangulation in
+ * order to reset the stored 'present_cell' iterator to an invalid
+ * one whenever the triangulation is changed and the iterator consequently
+ * becomes invalid.
+ */
+ void invalidate_present_cell ();
+
+ /**
+ * This function is called by the various reinit() functions in derived
+ * classes. Given the cell indicated by the argument, test whether
+ * we have to throw away the previously stored present_cell argument
+ * because it would require us to compare cells from different
+ * triangulations. In checking all this, also make sure that we have
+ * tria_listener connected to the triangulation to which we will set
+ * present_cell right after calling this function.
+ */
+ void maybe_invalidate_previous_present_cell (const typename Triangulation<dim,spacedim>::active_cell_iterator &cell);
+
/**
* Storage for the mapping object.
*/
mapping_data=0;
delete tmp1;
}
+
+ tria_listener.disconnect ();
}
}
+template <int dim, int spacedim>
+void
+FEValuesBase< dim, spacedim >::invalidate_present_cell ()
+{
+ // if there is no present cell, then we shouldn't be
+ // connected via a signal to a triangulation
+ Assert (present_cell.get() != 0, ExcInternalError());
+ present_cell.reset ();
+}
+
+
+template <int dim, int spacedim>
+void
+FEValuesBase< dim, spacedim >::
+maybe_invalidate_previous_present_cell (const typename Triangulation<dim,spacedim>::active_cell_iterator &cell)
+{
+ if (present_cell.get() != 0)
+ {
+ if (&cell->get_triangulation() !=
+ &static_cast<const typename Triangulation<dim,spacedim>::cell_iterator>(*present_cell)
+ ->get_triangulation())
+ {
+ // the triangulations for the previous cell and the current cell
+ // do not match. disconnect from the previous triangulation and
+ // connect to the current one; also invalidate the previous
+ // cell because we shouldn't be comparing cells from different
+ // triangulations
+ tria_listener.disconnect ();
+ invalidate_present_cell();
+ tria_listener =
+ cell->get_triangulation().signals.post_refinement.connect
+ (std_cxx1x::bind (&FEValuesBase<dim,spacedim>::invalidate_present_cell,
+ std_cxx1x::ref(static_cast<FEValuesBase<dim,spacedim>&>(*this))));
+ }
+ }
+ else
+ {
+ // if this FEValues has never been set to any cell at all, then
+ // at least subscribe to the triangulation to get notified of
+ // changes
+ tria_listener =
+ cell->get_triangulation().signals.post_refinement.connect
+ (std_cxx1x::bind (&FEValuesBase<dim,spacedim>::invalidate_present_cell,
+ std_cxx1x::ref(static_cast<FEValuesBase<dim,spacedim>&>(*this))));
+ }
+}
+
template <int dim, int spacedim>
inline
{
// case that there has not been any cell
// before
- if (&*this->present_cell == 0)
+ if (this->present_cell.get() == 0)
cell_similarity = CellSimilarity::none;
else
// in MappingQ, data can have been
static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
typename FEVB::ExcFEDontMatch());
+ this->maybe_invalidate_previous_present_cell (cell);
check_cell_similarity(cell);
// set new cell. auto_ptr will take
static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
typename FEVB::ExcFEDontMatch());
+ this->maybe_invalidate_previous_present_cell (cell);
check_cell_similarity(cell);
// set new cell. auto_ptr will take
// static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
// typename FEValuesBase<dim,spacedim>::ExcFEDontMatch());
+ this->maybe_invalidate_previous_present_cell (cell);
check_cell_similarity(cell);
// set new cell. auto_ptr will take
{
// no FE in this cell, so no assertion
// necessary here
+ this->maybe_invalidate_previous_present_cell (cell);
check_cell_similarity(cell);
// set new cell. auto_ptr will take
// destroyed and also that this
// object gets destroyed in the
// destruction of this class
+ this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename DoFHandler<dim,spacedim>::cell_iterator> (cell));
// destroyed and also that this
// object gets destroyed in the
// destruction of this class
+ this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename hp::DoFHandler<dim,spacedim>::cell_iterator> (cell));
// destroyed and also that this
// object gets destroyed in the
// destruction of this class
+ this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename MGDoFHandler<dim,spacedim>::cell_iterator> (cell));
// destroyed and also that this
// object gets destroyed in the
// destruction of this class
+ this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));
// destroyed and also that this
// object gets destroyed in the
// destruction of this class
+ this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename DoFHandler<dim,spacedim>::cell_iterator> (cell));
// destroyed and also that this
// object gets destroyed in the
// destruction of this class
+ this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename hp::DoFHandler<dim,spacedim>::cell_iterator> (cell));
// destroyed and also that this
// object gets destroyed in the
// destruction of this class
+ this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename MGDoFHandler<dim,spacedim>::cell_iterator> (cell));
// destroyed and also that this
// object gets destroyed in the
// destruction of this class
+ this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));