|
template <int dim, int spacedim, typename Scalar> |
|
void |
|
count_quadrature_points_internal( |
|
const int qp_data_idx, |
|
PatchMap<dim, spacedim> &patch_map, |
|
const Mapping<dim, spacedim> &position_mapping, |
|
const std::vector<unsigned char> &quadrature_indices, |
|
const std::vector<Quadrature<dim>> &quadratures) |
|
{ |
|
check_quadratures(quadrature_indices, |
|
quadratures, |
|
patch_map.get_triangulation()); |
|
|
|
// We probably don't need more than 16 quadrature rules |
|
boost::container::small_vector<std::unique_ptr<FEValues<dim, spacedim>>, 16> |
|
all_position_fe_values; |
|
// PatchMap only supports looping over DoFHandler iterators, so we need to |
|
// make one and never use it explicitly |
|
const Triangulation<dim, spacedim> &tria = patch_map.get_triangulation(); |
|
// No mixed meshes yet |
|
Assert(tria.get_reference_cells().size() == 1, ExcNotImplemented()); |
|
const ReferenceCell reference_cell = tria.get_reference_cells().front(); |
|
FE_Nothing<dim, spacedim> fe_nothing(reference_cell); |
|
DoFHandler<dim, spacedim> dof_handler(tria); |
|
dof_handler.distribute_dofs(fe_nothing); |
|
for (const Quadrature<dim> &quad : quadratures) |
|
{ |
|
all_position_fe_values.emplace_back( |
|
std::make_unique<FEValues<dim, spacedim>>( |
|
position_mapping, fe_nothing, quad, update_quadrature_points)); |
|
} |
|
|
|
for (unsigned int patch_n = 0; patch_n < patch_map.size(); ++patch_n) |
|
{ |
|
auto patch = patch_map.get_patch(patch_n); |
|
tbox::Pointer<pdat::CellData<spacedim, Scalar>> qp_data = |
|
patch->getPatchData(qp_data_idx); |
|
Assert(qp_data, ExcMessage("Type mismatch")); |
|
Assert(qp_data->getDepth() == 1, ExcMessage("depth should be 1")); |
|
const hier::Box<spacedim> &patch_box = patch->getBox(); |
|
tbox::Pointer<geom::CartesianPatchGeometry<spacedim>> patch_geom = |
|
patch->getPatchGeometry(); |
|
Assert(patch_geom, ExcMessage("Type mismatch")); |
|
|
|
auto iter = patch_map.begin(patch_n, dof_handler); |
|
const auto end = patch_map.end(patch_n, dof_handler); |
|
for (; iter != end; ++iter) |
|
{ |
|
const auto cell = *iter; |
|
const auto quad_index = |
|
quadrature_indices[cell->active_cell_index()]; |
|
|
|
FEValues<dim, spacedim> &position_fe_values = |
|
*all_position_fe_values[quad_index]; |
|
position_fe_values.reinit(cell); |
|
for (const Point<spacedim> &q_point : |
|
position_fe_values.get_quadrature_points()) |
|
{ |
|
const hier::Index<spacedim> i = |
|
IBTK::IndexUtilities::getCellIndex(q_point, |
|
patch_geom, |
|
patch_box); |
|
if (patch_box.contains(i)) |
|
(*qp_data)(i) += Scalar(1); |
|
} |
|
} |
|
} |
|
} |
From a discussion today. This is not something I have time to complete myself but I still want to write down some notes.
The fundamental geometric problem we need to solve is ray intersection: we need to find 1) the points where a finite difference stencil intersects the mesh and 2) the corresponding unique element. If we get those then we can start building IIM algorithms.
There's a lot of interesting things to investigate:
@ryanleaf1000 A good place to start would be to look at how to intersect rays and elements in serial: i.e., given a
fdl::PatchMap, compute a new structure describing where the intersections are with SAMRAI indices, deal.II elements, points on the structure, and points in the reference configuration. We should get this working before doing any physics. This is similar tofiddle/source/interaction/interaction_utilities.cc
Lines 202 to 269 in 057b769