to take an optional custom mask for vertices.
/*@{*/
/**
- * Find and return the number of the used vertex in a given mesh that is
- * located closest to a given point.
+ * Find and return the number of the used vertex (or marked vertex) in a
+ * given mesh that is located closest to a given point.
*
* @param mesh A variable of a type that satisfies the requirements of the
* @ref ConceptMeshType "MeshType concept".
* @param p The point for which we want to find the closest vertex.
+ * @param marked_vertices An array of bools indicating which
+ * vertices of @p mesh will be considered within the search
+ * as the potentially closest vertex. On receiving a non-empty
+ * @p marked_vertices, the function will
+ * only search among @p marked_vertices for the closest vertex.
+ * The size of this array should be equal to the value returned by
+ * Triangulation::n_vertices() for the triangulation underlying the given mesh
+ * (as opposed to the value returned by Triangulation::n_used_vertices()).
* @return The index of the closest vertex found.
*
+ *
* @author Ralf B. Schulz, 2006
*/
template <int dim, template <int, int> class MeshType, int spacedim>
unsigned int
find_closest_vertex (const MeshType<dim, spacedim> &mesh,
- const Point<spacedim> &p);
+ const Point<spacedim> &p,
+ const std::vector<bool> &marked_vertices = std::vector<bool>());
/**
* Find and return a vector of iterators to active cells that surround a
* @param mesh A variable of a type that satisfies the requirements of the
* @ref ConceptMeshType "MeshType concept".
* @param p The point for which we want to find the surrounding cell.
+ * @param marked_vertices An array of bools indicating whether an
+ * entry in the vertex array should be considered
+ * (and the others must be ignored) as the potentially
+ * closest vertex to the specified point. On specifying a non-default
+ * @p marked_vertices, find_closest_vertex() would
+ * only search among @p marked_vertices for the closest vertex.
+ * The size of this array should be equal to n_vertices() of the
+ * triangulation (as opposed to n_used_vertices() ).
* @return An iterator into the mesh that points to the surrounding cell.
*
* @note If the point requested does not lie in any of the cells of the mesh
typename dealii::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type
#endif
find_active_cell_around_point (const MeshType<dim,spacedim> &mesh,
- const Point<spacedim> &p);
+ const Point<spacedim> &p,
+ const std::vector<bool> &marked_vertices = std::vector<bool>());
/**
* Find and return an iterator to the active cell that surrounds a given
* @param mesh A variable of a type that satisfies the requirements of the
* @ref ConceptMeshType "MeshType concept".
* @param p The point for which we want to find the surrounding cell.
+ * @param marked_vertices An array of bools indicating whether an
+ * entry in the vertex array should be considered
+ * (and the others must be ignored) as the potentially
+ * closest vertex to the specified point. On specifying a non-default
+ * @p marked_vertices, find_closest_vertex() would
+ * only search among @p marked_vertices for the closest vertex.
+ * The size of this array should be equal to n_vertices() of the
+ * triangulation (as opposed to n_used_vertices() ).
* @return An pair of an iterators into the mesh that points to the
* surrounding cell, and of the coordinates of that point inside the cell in
* the reference coordinates of that cell. This local position might be
* the unit cell, using GeometryInfo::project_to_unit_cell(). This is not
* automatically performed by the algorithm.
*
+ * @note When @p marked_vertices is specified the function should always be
+ * called inside a try block to catch the exception that the function might
+ * throw in the case it couldn't find an active cell surrounding the point.
+ * The motivation of using @p marked_vertices is to cut down the search space
+ * of vertices if one has a priori knowledge of a collection of vertices that
+ * the point of interest may be close to. For instance, in the case when a
+ * parallel::shared::Triangulation is employed and we are looking for a point
+ * that we know is inside the locally owned part of the mesh, then it would
+ * make sense to pass an array for @p marked_vertices that flags only the
+ * vertices of all locally owned active cells. If, however, the function
+ * throws an exception, then that would imply that the point lies outside
+ * locally owned active cells.
+ *
* @note If the point requested does not lie in any of the cells of the mesh
* given, then this function throws an exception of type
* GridTools::ExcPointNotFound. You can catch this exception and decide what
#endif
find_active_cell_around_point (const Mapping<dim,spacedim> &mapping,
const MeshType<dim,spacedim> &mesh,
- const Point<spacedim> &p);
+ const Point<spacedim> &p,
+ const std::vector<bool> &marked_vertices = std::vector<bool>());
/**
* A version of the previous function where we use that mapping on a given
}
-
template <int dim, template <int, int> class MeshType, int spacedim>
unsigned int
find_closest_vertex (const MeshType<dim,spacedim> &mesh,
- const Point<spacedim> &p)
+ const Point<spacedim> &p,
+ const std::vector<bool> &marked_vertices)
{
// first get the underlying
// triangulation from the
const Triangulation<dim, spacedim> &tria = mesh.get_triangulation();
const std::vector< Point<spacedim> > &vertices = tria.get_vertices();
- const std::vector< bool > &used = tria.get_used_vertices();
+
+ Assert ( tria.get_vertices().size() == marked_vertices.size() || marked_vertices.size() ==0,
+ ExcDimensionMismatch(tria.get_vertices().size(), marked_vertices.size()));
+
+ // If p is an element of marked_vertices,
+ // and q is that of used_Vertices,
+ // the vector marked_vertices does NOT
+ // contain unused vertices if p implies q.
+ // I.e., if p is true q must be true
+ // (if p is false, q could be false or true).
+ // p implies q logic is encapsulated in ~p|q.
+ Assert( marked_vertices.size()==0
+ ||
+ std::equal( marked_vertices.begin(),
+ marked_vertices.end(),
+ tria.get_used_vertices().begin(),
+ [](bool p, bool q)
+ {
+ return !p || q;
+ }),
+ ExcMessage("marked_vertices should be a subset of used vertices in the triangulation "
+ "but marked_vertices contains one or more vertices that are not used vertices!") );
+
+ // In addition, if a vector bools
+ // is specified (marked_vertices)
+ // marking all the vertices which
+ // could be the potentially closest
+ // vertex to the point, use it instead
+ // of used vertices
+ const std::vector<bool> &used =
+ (marked_vertices.size()==0) ? tria.get_used_vertices() : marked_vertices;
// At the beginning, the first
// used vertex is the closest one
typename dealii::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type
#endif
find_active_cell_around_point (const MeshType<dim,spacedim> &mesh,
- const Point<spacedim> &p)
+ const Point<spacedim> &p,
+ const std::vector<bool> &marked_vertices)
{
return
find_active_cell_around_point<dim,MeshType,spacedim>
(StaticMappingQ1<dim,spacedim>::mapping,
- mesh, p).first;
+ mesh, p, marked_vertices).first;
}
#endif
find_active_cell_around_point (const Mapping<dim,spacedim> &mapping,
const MeshType<dim,spacedim> &mesh,
- const Point<spacedim> &p)
+ const Point<spacedim> &p,
+ const std::vector<bool> &marked_vertices)
{
typedef typename dealii::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type active_cell_iterator;
// all adjacent cells
std::vector<active_cell_iterator> adjacent_cells_tmp
= find_cells_adjacent_to_vertex(mesh,
- find_closest_vertex(mesh, p));
+ find_closest_vertex(mesh, p, marked_vertices));
// Make sure that we have found
// at least one cell adjacent to vertex.
// update the number of cells searched
cells_searched += adjacent_cells.size();
+ // if the user provided a custom mask for vertices,
+ // terminate the search without trying to expand the search
+ // to all cells of the triangulation, as done below.
+ if (marked_vertices.size() > 0)
+ cells_searched = n_active_cells;
+
// if we have not found the cell in
// question and have not yet searched every
// cell, we expand our search to
template
unsigned int
find_closest_vertex (const X &,
- const Point<deal_II_space_dimension> &);
+ const Point<deal_II_space_dimension> &,
+ const std::vector<bool> &);
template
std::vector<dealii::internal::ActiveCellIterator<deal_II_dimension, deal_II_space_dimension, X>::type>
template
dealii::internal::ActiveCellIterator<deal_II_dimension, deal_II_space_dimension, X>::type
- find_active_cell_around_point (const X &, const Point<deal_II_space_dimension> &p);
+ find_active_cell_around_point (const X &, const Point<deal_II_space_dimension> &, const std::vector<bool> &);
template
std::pair<dealii::internal::ActiveCellIterator<deal_II_dimension, deal_II_space_dimension, X>::type, Point<deal_II_dimension> >
find_active_cell_around_point (const Mapping<deal_II_dimension, deal_II_space_dimension> &,
const X &,
- const Point<deal_II_space_dimension> &);
+ const Point<deal_II_space_dimension> &,
+ const std::vector<bool> &);
template
std::vector<dealii::internal::ActiveCellIterator<deal_II_dimension, deal_II_space_dimension, X>::type>