#ifndef CELLS_H #define CELLS_H #include #include #include #include #include #include using namespace dealii; template struct CellInfo { // what needs to be given to evaluator typename DoFHandler::active_cell_iterator cell; // usefull for locator Point lower; // Point upper; // double h; }; template class CellLocator { public: using CellIterator = typename DoFHandler::active_cell_iterator; void rebuild(const DoFHandler &dof_handler, const Triangulation &triangulation); CellIterator locate(const Point &p) const; private: std::vector> cells; }; template void CellLocator::rebuild(const DoFHandler &dof_handler, const Triangulation &triangulation) { cells.clear(); cells.reserve(triangulation.n_active_cells()); for (const auto &cell : dof_handler.active_cell_iterators()) { CellInfo info; info.cell = cell; info.lower = cell->vertex(0); // info.upper = cell->vertex(GeometryInfo::vertices_per_cell - 1); // info.h = info.upper[0] - info.lower[0]; cells.push_back(info); } } template typename DoFHandler::active_cell_iterator CellLocator::locate(const Point &p) const { static_assert(dim == 1, "Current CellLocator implementation only supports 1D."); AssertThrow(!cells.empty(), ExcMessage("CellLocator::rebuild() has not been called.")); const double x = p[0]; // const double x_min = cells.front().lower[0]; // const double x_max = cells.back().uppper[0]; // const double L = x_max - x_min; // binary search loop auto it = std::upper_bound(cells.begin(), cells.end(), x, [](double value, const CellInfo &cell) { return value < cell.lower[0]; }); if (it == cells.begin()) it = cells.begin(); else --it; return it->cell; } #endif // !CELLS_H