cell = container.begin_active(),
endc = container.end();
- // go through all active cells and look if the vertex is part of that cell
- //
- // in 1d, this is all we need to care about. in 2d/3d we also need to worry
- // that the vertex might be a hanging node on a face or edge of a cell; in
- // this case, we would want to add those cells as well on whose faces the
- // vertex is located but for which it is not a vertex itself.
- //
- // getting this right is a lot simpler in 2d than in 3d. in 2d, a hanging
- // node can only be in the middle of a face and we can query the neighboring
- // cell from the current cell. on the other hand, in 3d a hanging node
- // vertex can also be on an edge but there can be many other cells on
- // this edge and we can not access them from the cell we are currently
- // on.
- //
- // so, in the 3d case, if we run the algorithm as in 2d, we catch all
- // those cells for which the vertex we seek is on a *subface*, but we
- // miss the case of cells for which the vertex we seek is on a
- // sub-edge for which there is no corresponding sub-face (because the
- // immediate neighbor behind this face is not refined), see for example
- // the bits/find_cells_adjacent_to_vertex_6 testcase. thus, if we
- // haven't yet found the vertex for the current cell we also need to
- // look at the mid-points of edges
- //
- // as a final note, deciding whether a neighbor is actually coarses is
- // simple in the case of isotropic refinement (we just need to look at
- // the level of the current and the neighboring cell). however, this
- // isn't so simple if we have used anisotropic refinement since then
- // the level of a cell is not indicative of whether it is coarser or
- // not than the current cell. ultimately, we want to add all cells on
- // which the vertex is, independent of whether they are coarser or
- // finer and so in the 2d case below we simply add *any* *active* neighbor.
- // in the worst case, we add cells multiple times to the adjacent_cells
- // list, but std::set throws out those cells already entered
+ // go through all active cells and look if the vertex is part of that cell
+ //
+ // in 1d, this is all we need to care about. in 2d/3d we also need to worry
+ // that the vertex might be a hanging node on a face or edge of a cell; in
+ // this case, we would want to add those cells as well on whose faces the
+ // vertex is located but for which it is not a vertex itself.
+ //
+ // getting this right is a lot simpler in 2d than in 3d. in 2d, a hanging
+ // node can only be in the middle of a face and we can query the neighboring
+ // cell from the current cell. on the other hand, in 3d a hanging node
+ // vertex can also be on an edge but there can be many other cells on
+ // this edge and we can not access them from the cell we are currently
+ // on.
+ //
+ // so, in the 3d case, if we run the algorithm as in 2d, we catch all
+ // those cells for which the vertex we seek is on a *subface*, but we
+ // miss the case of cells for which the vertex we seek is on a
+ // sub-edge for which there is no corresponding sub-face (because the
+ // immediate neighbor behind this face is not refined), see for example
+ // the bits/find_cells_adjacent_to_vertex_6 testcase. thus, if we
+ // haven't yet found the vertex for the current cell we also need to
+ // look at the mid-points of edges
+ //
+ // as a final note, deciding whether a neighbor is actually coarses is
+ // simple in the case of isotropic refinement (we just need to look at
+ // the level of the current and the neighboring cell). however, this
+ // isn't so simple if we have used anisotropic refinement since then
+ // the level of a cell is not indicative of whether it is coarser or
+ // not than the current cell. ultimately, we want to add all cells on
+ // which the vertex is, independent of whether they are coarser or
+ // finer and so in the 2d case below we simply add *any* *active* neighbor.
+ // in the worst case, we add cells multiple times to the adjacent_cells
+ // list, but std::set throws out those cells already entered
for (; cell != endc; ++cell)
{
for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; v++)
if (cell->vertex_index(v) == vertex)
{
- // OK, we found a cell that contains
- // the given vertex. We add it
- // to the list.
+ // OK, we found a cell that contains
+ // the given vertex. We add it
+ // to the list.
adjacent_cells.insert(cell);
- // as explained above, in 2+d we need to check whether
- // this vertex is on a face behind which there is a
- // (possibly) coarser neighbor. if this is the case,
- // then we need to also add this neighbor
+ // as explained above, in 2+d we need to check whether
+ // this vertex is on a face behind which there is a
+ // (possibly) coarser neighbor. if this is the case,
+ // then we need to also add this neighbor
if (dim >= 2)
for (unsigned int vface = 0; vface < dim; vface++)
{
const unsigned int face =
- GeometryInfo<dim>::vertex_to_face[v][vface];
+ GeometryInfo<dim>::vertex_to_face[v][vface];
if (!cell->at_boundary(face)
&&
cell->neighbor(face)->active())
{
- // there is a (possibly) coarser cell behind a
- // face to which the vertex belongs. the
- // vertex we are looking at is then either a
- // vertex of that coarser neighbor, or it is a
- // hanging node on one of the faces of that
- // cell. in either case, it is adjacent to the
- // vertex, so add it to the list as well (if
- // the cell was already in the list then the
- // std::set makes sure that we get it only
- // once)
+ // there is a (possibly) coarser cell behind a
+ // face to which the vertex belongs. the
+ // vertex we are looking at is then either a
+ // vertex of that coarser neighbor, or it is a
+ // hanging node on one of the faces of that
+ // cell. in either case, it is adjacent to the
+ // vertex, so add it to the list as well (if
+ // the cell was already in the list then the
+ // std::set makes sure that we get it only
+ // once)
adjacent_cells.insert (cell->neighbor(face));
}
}
- // in any case, we have found a cell, so go to the next cell
+ // in any case, we have found a cell, so go to the next cell
goto next_cell;
}
- // in 3d also loop over the edges
+ // in 3d also loop over the edges
if (dim >= 3)
{
for (unsigned int e=0; e<GeometryInfo<dim>::lines_per_cell; ++e)
if (cell->line(e)->has_children())
- // the only place where this vertex could have been
- // hiding is on the mid-edge point of the edge we
- // are looking at
+ // the only place where this vertex could have been
+ // hiding is on the mid-edge point of the edge we
+ // are looking at
if (cell->line(e)->child(0)->vertex_index(1) == vertex)
{
adjacent_cells.insert(cell);
- // jump out of this tangle of nested loops
+ // jump out of this tangle of nested loops
goto next_cell;
}
}
- // in more than 3d we would probably have to do the same as
- // above also for even lower-dimensional objects
+ // in more than 3d we would probably have to do the same as
+ // above also for even lower-dimensional objects
Assert (dim <= 3, ExcNotImplemented());
- // move on to the next cell if we have found the
- // vertex on the current one
+ // move on to the next cell if we have found the
+ // vertex on the current one
next_cell:
;
}
- // if this was an active vertex then there needs to have been
- // at least one cell to which it is adjacent!
+ // if this was an active vertex then there needs to have been
+ // at least one cell to which it is adjacent!
Assert (adjacent_cells.size() > 0, ExcInternalError());
- // return the result as a vector, rather than the set we built above
+ // return the result as a vector, rather than the set we built above
return
- std::vector<typename Container<dim,spacedim>::active_cell_iterator>
- (adjacent_cells.begin(), adjacent_cells.end());
+ std::vector<typename Container<dim,spacedim>::active_cell_iterator>
+ (adjacent_cells.begin(), adjacent_cells.end());
}
namespace
{
- template <int dim, template<int, int> class Container, int spacedim>
- void find_active_cell_around_point_internal(const Container<dim,spacedim>& container,
- std::set<typename Container<dim,spacedim>::active_cell_iterator>& searched_cells,
- std::set<typename Container<dim,spacedim>::active_cell_iterator>& adjacent_cells)
+ template <int dim, template<int, int> class Container, int spacedim>
+ void find_active_cell_around_point_internal(const Container<dim,spacedim>& container,
+ std::set<typename Container<dim,spacedim>::active_cell_iterator>& searched_cells,
+ std::set<typename Container<dim,spacedim>::active_cell_iterator>& adjacent_cells)
+ {
+ typedef typename Container<dim,spacedim>::active_cell_iterator cell_iterator;
+
+ // update the searched cells
+ searched_cells.insert(adjacent_cells.begin(), adjacent_cells.end());
+ // now we to collect all neighbors
+ // of the cells in adjacent_cells we
+ // have not yet searched.
+ std::set<cell_iterator> adjacent_cells_new;
+
+ typename std::set<cell_iterator>::const_iterator
+ cell = adjacent_cells.begin(),
+ endc = adjacent_cells.end();
+ for(; cell != endc; ++cell)
{
- typedef typename Container<dim,spacedim>::active_cell_iterator cell_iterator;
-
- // update the searched cells
- searched_cells.insert(adjacent_cells.begin(), adjacent_cells.end());
- // now we to collect all neighbors
- // of the cells in adjacent_cells we
- // have not yet searched.
- std::set<cell_iterator> adjacent_cells_new;
-
- typename std::set<cell_iterator>::const_iterator
- cell = adjacent_cells.begin(),
- endc = adjacent_cells.end();
- for(; cell != endc; ++cell)
- {
- std::vector<cell_iterator> active_neighbors;
- get_active_neighbors<Container<dim, spacedim> >(*cell, active_neighbors);
- for (unsigned int i=0; i<active_neighbors.size(); ++i)
- if(searched_cells.find(active_neighbors[i]) == searched_cells.end())
- adjacent_cells_new.insert(active_neighbors[i]);
- }
- adjacent_cells.clear();
- adjacent_cells.insert(adjacent_cells_new.begin(), adjacent_cells_new.end());
- if (adjacent_cells.size() == 0)
- {
- // we haven't found any other cell that would be a
- // neighbor of a previously found cell, but we know
- // that we haven't checked all cells yet. that means
- // that the domain is disconnected. in that case,
- // choose the first previously untouched cell we
- // can find
- cell_iterator it = container.begin_active();
- for ( ; it!=container.end();++it)
- if(searched_cells.find(it) == searched_cells.end())
- {
- adjacent_cells.insert(it);
- break;
- }
- }
+ std::vector<cell_iterator> active_neighbors;
+ get_active_neighbors<Container<dim, spacedim> >(*cell, active_neighbors);
+ for (unsigned int i=0; i<active_neighbors.size(); ++i)
+ if(searched_cells.find(active_neighbors[i]) == searched_cells.end())
+ adjacent_cells_new.insert(active_neighbors[i]);
+ }
+ adjacent_cells.clear();
+ adjacent_cells.insert(adjacent_cells_new.begin(), adjacent_cells_new.end());
+ if (adjacent_cells.size() == 0)
+ {
+ // we haven't found any other cell that would be a
+ // neighbor of a previously found cell, but we know
+ // that we haven't checked all cells yet. that means
+ // that the domain is disconnected. in that case,
+ // choose the first previously untouched cell we
+ // can find
+ cell_iterator it = container.begin_active();
+ for ( ; it!=container.end();++it)
+ if(searched_cells.find(it) == searched_cells.end())
+ {
+ adjacent_cells.insert(it);
+ break;
+ }
}
+ }
}
template <int dim, template<int, int> class Container, int spacedim>
std::vector<cell_iterator> adjacent_cells_tmp =
find_cells_adjacent_to_vertex(container, vertex);
- // Make sure that we have found
- // at least one cell adjacent to vertex.
- Assert(adjacent_cells_tmp.size()>0, ExcInternalError());
-
- // Copy all the cells into a std::set
- std::set<cell_iterator> adjacent_cells(adjacent_cells_tmp.begin(), adjacent_cells_tmp.end());
- std::set<cell_iterator> searched_cells;
-
- // Determine the maximal number of cells
- // in the grid.
- // As long as we have not found
- // the cell and have not searched
- // every cell in the triangulation,
- // we keep on looking.
- const unsigned int n_cells =get_tria(container).n_cells();
- bool found = false;
- unsigned int cells_searched = 0;
- while (!found && cells_searched < n_cells)
+ // Make sure that we have found
+ // at least one cell adjacent to vertex.
+ Assert(adjacent_cells_tmp.size()>0, ExcInternalError());
+
+ // Copy all the cells into a std::set
+ std::set<cell_iterator> adjacent_cells(adjacent_cells_tmp.begin(), adjacent_cells_tmp.end());
+ std::set<cell_iterator> searched_cells;
+
+ // Determine the maximal number of cells
+ // in the grid.
+ // As long as we have not found
+ // the cell and have not searched
+ // every cell in the triangulation,
+ // we keep on looking.
+ const unsigned int n_cells =get_tria(container).n_cells();
+ bool found = false;
+ unsigned int cells_searched = 0;
+ while (!found && cells_searched < n_cells)
+ {
+ typename std::set<cell_iterator>::const_iterator
+ cell = adjacent_cells.begin(),
+ endc = adjacent_cells.end();
+ for(; cell != endc; ++cell)
{
- typename std::set<cell_iterator>::const_iterator
- cell = adjacent_cells.begin(),
- endc = adjacent_cells.end();
- for(; cell != endc; ++cell)
- {
- try
- {
- const Point<dim> p_cell = mapping.transform_real_to_unit_cell(*cell, p);
-
- // calculate the infinity norm of
- // the distance vector to the unit cell.
- const double dist = GeometryInfo<dim>::distance_to_unit_cell(p_cell);
-
- // We compare if the point is inside the
- // unit cell (or at least not too far
- // outside). If it is, it is also checked
- // that the cell has a more refined state
- if (dist < best_distance ||
- (dist == best_distance && (*cell)->level() > best_level))
- {
- found = true;
- best_distance = dist;
- best_level = (*cell)->level();
- best_cell = std::make_pair(*cell, p_cell);
- }
- }
- catch (typename MappingQ1<dim,spacedim>::ExcTransformationFailed &)
- {
- // ok, the transformation
- // failed presumably
- // because the point we
- // are looking for lies
- // outside the current
- // cell. this means that
- // the current cell can't
- // be the cell around the
- // point, so just ignore
- // this cell and move on
- // to the next
- }
- }
- //udpate the number of cells searched
- cells_searched += adjacent_cells.size();
- // if we have not found the cell in
- // question and have not yet searched every
- // cell, we expand our search to
- // all the not already searched neighbors of
- // the cells in adjacent_cells. This is
- // what find_active_cell_around_poin_internal
- // is for.
- if(!found && cells_searched < n_cells)
+ try
+ {
+ const Point<dim> p_cell = mapping.transform_real_to_unit_cell(*cell, p);
+
+ // calculate the infinity norm of
+ // the distance vector to the unit cell.
+ const double dist = GeometryInfo<dim>::distance_to_unit_cell(p_cell);
+
+ // We compare if the point is inside the
+ // unit cell (or at least not too far
+ // outside). If it is, it is also checked
+ // that the cell has a more refined state
+ if (dist < best_distance ||
+ (dist == best_distance && (*cell)->level() > best_level))
{
- find_active_cell_around_point_internal(container, searched_cells, adjacent_cells);
+ found = true;
+ best_distance = dist;
+ best_level = (*cell)->level();
+ best_cell = std::make_pair(*cell, p_cell);
}
+ }
+ catch (typename MappingQ1<dim,spacedim>::ExcTransformationFailed &)
+ {
+ // ok, the transformation
+ // failed presumably
+ // because the point we
+ // are looking for lies
+ // outside the current
+ // cell. this means that
+ // the current cell can't
+ // be the cell around the
+ // point, so just ignore
+ // this cell and move on
+ // to the next
+ }
+ }
+ //udpate the number of cells searched
+ cells_searched += adjacent_cells.size();
+ // if we have not found the cell in
+ // question and have not yet searched every
+ // cell, we expand our search to
+ // all the not already searched neighbors of
+ // the cells in adjacent_cells. This is
+ // what find_active_cell_around_poin_internal
+ // is for.
+ if(!found && cells_searched < n_cells)
+ {
+ find_active_cell_around_point_internal(container, searched_cells, adjacent_cells);
}
+ }
Assert (best_cell.first.state() == IteratorState::valid,
ExcPointNotFound<spacedim>(p));
// all adjacent cells
unsigned int vertex = find_closest_vertex(container, p);
- std::vector<cell_iterator> adjacent_cells_tmp =
- find_cells_adjacent_to_vertex(container, vertex);
-
- // Make sure that we have found
- // at least one cell adjacent to vertex.
- Assert(adjacent_cells_tmp.size()>0, ExcInternalError());
-
- // Copy all the cells into a std::set
- std::set<cell_iterator> adjacent_cells(adjacent_cells_tmp.begin(), adjacent_cells_tmp.end());
- std::set<cell_iterator> searched_cells;
-
- // Determine the maximal number of cells
- // in the grid.
- // As long as we have not found
- // the cell and have not searched
- // every cell in the triangulation,
- // we keep on looking.
- const unsigned int n_cells =get_tria(container).n_cells();
- bool found = false;
- unsigned int cells_searched = 0;
- while (!found && cells_searched < n_cells)
+ std::vector<cell_iterator> adjacent_cells_tmp =
+ find_cells_adjacent_to_vertex(container, vertex);
+
+ // Make sure that we have found
+ // at least one cell adjacent to vertex.
+ Assert(adjacent_cells_tmp.size()>0, ExcInternalError());
+
+ // Copy all the cells into a std::set
+ std::set<cell_iterator> adjacent_cells(adjacent_cells_tmp.begin(), adjacent_cells_tmp.end());
+ std::set<cell_iterator> searched_cells;
+
+ // Determine the maximal number of cells
+ // in the grid.
+ // As long as we have not found
+ // the cell and have not searched
+ // every cell in the triangulation,
+ // we keep on looking.
+ const unsigned int n_cells =get_tria(container).n_cells();
+ bool found = false;
+ unsigned int cells_searched = 0;
+ while (!found && cells_searched < n_cells)
{
typename std::set<cell_iterator>::const_iterator
- cell = adjacent_cells.begin(),
- endc = adjacent_cells.end();
- for(; cell != endc; ++cell)
+ cell = adjacent_cells.begin(),
+ endc = adjacent_cells.end();
+ for(; cell != endc; ++cell)
+ {
+ try
{
- try
- {
- const Point<dim> p_cell = mapping[(*cell)->active_fe_index()].transform_real_to_unit_cell(*cell, p);
-
-
- // calculate the infinity norm of
- // the distance vector to the unit cell.
- const double dist = GeometryInfo<dim>::distance_to_unit_cell(p_cell);
-
- // We compare if the point is inside the
- // unit cell (or at least not too far
- // outside). If it is, it is also checked
- // that the cell has a more refined state
- if (dist < best_distance ||
- (dist == best_distance && (*cell)->level() > best_level))
- {
- found = true;
- best_distance = dist;
- best_level = (*cell)->level();
- best_cell = std::make_pair(*cell, p_cell);
- }
- }
- catch (typename MappingQ1<dim,spacedim>::ExcTransformationFailed &)
- {
- // ok, the transformation
- // failed presumably
- // because the point we
- // are looking for lies
- // outside the current
- // cell. this means that
- // the current cell can't
- // be the cell around the
- // point, so just ignore
- // this cell and move on
- // to the next
- }
+ const Point<dim> p_cell = mapping[(*cell)->active_fe_index()].transform_real_to_unit_cell(*cell, p);
+
+
+ // calculate the infinity norm of
+ // the distance vector to the unit cell.
+ const double dist = GeometryInfo<dim>::distance_to_unit_cell(p_cell);
+
+ // We compare if the point is inside the
+ // unit cell (or at least not too far
+ // outside). If it is, it is also checked
+ // that the cell has a more refined state
+ if (dist < best_distance ||
+ (dist == best_distance && (*cell)->level() > best_level))
+ {
+ found = true;
+ best_distance = dist;
+ best_level = (*cell)->level();
+ best_cell = std::make_pair(*cell, p_cell);
+ }
}
- //udpate the number of cells searched
- cells_searched += adjacent_cells.size();
- // if we have not found the cell in
- // question and have not yet searched every
- // cell, we expand our search to
- // all the not already searched neighbors of
- // the cells in adjacent_cells.
- if(!found && cells_searched < n_cells)
+ catch (typename MappingQ1<dim,spacedim>::ExcTransformationFailed &)
{
- find_active_cell_around_point_internal(container, searched_cells, adjacent_cells);
+ // ok, the transformation
+ // failed presumably
+ // because the point we
+ // are looking for lies
+ // outside the current
+ // cell. this means that
+ // the current cell can't
+ // be the cell around the
+ // point, so just ignore
+ // this cell and move on
+ // to the next
}
+ }
+ //udpate the number of cells searched
+ cells_searched += adjacent_cells.size();
+ // if we have not found the cell in
+ // question and have not yet searched every
+ // cell, we expand our search to
+ // all the not already searched neighbors of
+ // the cells in adjacent_cells.
+ if(!found && cells_searched < n_cells)
+ {
+ find_active_cell_around_point_internal(container, searched_cells, adjacent_cells);
+ }
}
- }
+ }
Assert (best_cell.first.state() == IteratorState::valid,
ExcPointNotFound<spacedim>(p));
const CellIterator &cell2,
const int direction,
const dealii::Tensor<1,CellIterator::AccessorType::space_dimension>
- &offset)
+ &offset)
{
- // An orthogonal equality test for
- // cells:
- // Two cells are equal if the
- // corresponding vertices of the
- // boundary faces can be transformed
- // into each other parallel to the
- // given direction.
- // It is assumed that
- // cell1->face(2*direction) and
- // cell2->face(2*direction+1) are the
- // corresponding boundary faces.
- // The optional argument offset will
- // be added to each vertex of cell1
+ // An orthogonal equality test for
+ // cells:
+ // Two cells are equal if the
+ // corresponding vertices of the
+ // boundary faces can be transformed
+ // into each other parallel to the
+ // given direction.
+ // It is assumed that
+ // cell1->face(2*direction) and
+ // cell2->face(2*direction+1) are the
+ // corresponding boundary faces.
+ // The optional argument offset will
+ // be added to each vertex of cell1
static const int dim = CellIterator::AccessorType::dimension;
static const int space_dim = CellIterator::AccessorType::space_dimension;
Assert(dim == space_dim,
ExcNotImplemented());
- // ... otherwise we would need two
- // directions: One for selecting the
- // faces, thus living in dim,
- // the other direction for selecting the
- // direction for the orthogonal
- // projection, thus living in
- // space_dim.
+ // ... otherwise we would need two
+ // directions: One for selecting the
+ // faces, thus living in dim,
+ // the other direction for selecting the
+ // direction for the orthogonal
+ // projection, thus living in
+ // space_dim.
for (int i = 0; i < space_dim; ++i) {
- // Only compare
- // coordinate-components != direction:
+ // Only compare
+ // coordinate-components != direction:
if (i == direction)
continue;
for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face; ++v)
if (fabs ( cell1->face(2*direction)->vertex(v)(i)
- + offset[i]
- - cell2->face(2*direction+1)->vertex(v)(i))
- > 1.e-10)
+ + offset[i]
+ - cell2->face(2*direction+1)->vertex(v)(i))
+ > 1.e-10)
return false;
}
return true;
const types::boundary_id boundary_component,
int direction,
const dealii::Tensor<1,CellIterator::AccessorType::space_dimension>
- &offset)
+ &offset)
{
static const int space_dim = CellIterator::AccessorType::space_dimension;
Assert (0<=direction && direction<space_dim,
std::set<CellIterator> cells1;
std::set<CellIterator> cells2;
- // collect boundary cells, i.e. cells
- // with face(2*direction), resp.
- // face(2*direction+1) being on the
- // boundary and having the correct
- // color:
+ // collect boundary cells, i.e. cells
+ // with face(2*direction), resp.
+ // face(2*direction+1) being on the
+ // boundary and having the correct
+ // color:
CellIterator cell = begin;
for (; cell!= end; ++cell) {
if (cell->face(2*direction)->at_boundary() &&
std::map<CellIterator, CellIterator> matched_cells;
- // Match with a complexity of O(n^2).
- // This could be improved...
+ // Match with a complexity of O(n^2).
+ // This could be improved...
typedef typename std::set<CellIterator>::const_iterator SetIterator;
for (SetIterator it1 = cells1.begin(); it1 != cells1.end(); ++it1) {
for (SetIterator it2 = cells2.begin(); it2 != cells2.end(); ++it2) {
if (orthogonal_equality(*it1, *it2, direction, offset)) {
- // We have a match, so insert the
- // matching pairs and remove the matched
- // cell in cells2 to speed up the
- // matching:
+ // We have a match, so insert the
+ // matching pairs and remove the matched
+ // cell in cells2 to speed up the
+ // matching:
matched_cells[*it1] = *it2;
cells2.erase(it2);
break;
const types::boundary_id boundary_component,
int direction,
const dealii::Tensor<1,DH::space_dimension>
- &offset)
+ &offset)
{
return collect_periodic_cell_pairs<typename DH::cell_iterator>
- (dof_handler.begin_active(),
- dof_handler.end(),
- boundary_component,
- direction,
- offset);
+ (dof_handler.begin_active(),
+ dof_handler.end(),
+ boundary_component,
+ direction,
+ offset);
}