template <int length>
void
compute_face_index_compression(
- const std::vector<FaceToCellTopology<length>> &faces);
+ const std::vector<FaceToCellTopology<length>> &faces,
+ bool hold_all_faces_to_owned_cells);
/**
* This function computes the connectivity of the currently stored
template <int length>
void
DoFInfo::compute_face_index_compression(
- const std::vector<FaceToCellTopology<length>> &faces)
+ const std::vector<FaceToCellTopology<length>> &faces,
+ const bool hold_all_faces_to_owned_cells)
{
AssertDimension(length, vectorization_length);
n_vectorization_lanes_filled[dof_access_face_interior].resize(
faces.size());
- // all interior faces come before the boundary faces
- unsigned int n_exterior_faces = 0;
- for (; n_exterior_faces < faces.size(); ++n_exterior_faces)
- if (faces[n_exterior_faces].cells_exterior[0] ==
+ // all inner faces come before the boundary faces
+ unsigned int n_inner_faces = 0;
+ for (; n_inner_faces < faces.size(); ++n_inner_faces)
+ if (faces[n_inner_faces].cells_exterior[0] ==
+ numbers::invalid_unsigned_int)
+ break;
+
+ // all boundary faces come after the inner faces and before the ghosted
+ // inner faces
+ unsigned int n_boundary_faces = 0;
+ for (; n_inner_faces + n_boundary_faces < faces.size();
+ ++n_boundary_faces)
+ if (faces[n_inner_faces + n_boundary_faces].cells_exterior[0] !=
numbers::invalid_unsigned_int)
break;
+
+ const unsigned int size_exterior_faces =
+ hold_all_faces_to_owned_cells ? faces.size() : n_inner_faces;
+
index_storage_variants[dof_access_face_exterior].resize(
- n_exterior_faces, IndexStorageVariants::full);
+ size_exterior_faces, IndexStorageVariants::full);
dof_indices_contiguous[dof_access_face_exterior].resize(
- n_exterior_faces * length, numbers::invalid_unsigned_int);
+ size_exterior_faces * length, numbers::invalid_unsigned_int);
dof_indices_interleave_strides[dof_access_face_exterior].resize(
faces.size() * length, numbers::invalid_unsigned_int);
n_vectorization_lanes_filled[dof_access_face_exterior].resize(
- n_exterior_faces);
+ size_exterior_faces);
for (unsigned int face = 0; face < faces.size(); ++face)
{
face_computation(dof_access_face_interior,
faces[face].cells_interior);
- if (face < n_exterior_faces)
+ if (face < n_inner_faces ||
+ (hold_all_faces_to_owned_cells &&
+ face >= (n_inner_faces + n_boundary_faces)))
face_computation(dof_access_face_exterior,
faces[face].cells_exterior);
}
else if (face_is_owned[dcell->face(f)
->child(c)
->index()] ==
- FaceCategory::ghosted)
+ FaceCategory::ghosted ||
+ face_is_owned[dcell->face(f)
+ ->index()] ==
+ FaceCategory::ghosted)
{
inner_ghost_faces.push_back(create_face(
neighbor_face_no,
is_mixed_mesh));
}
else
- Assert(
- face_is_owned[dcell->face(f)
- ->index()] ==
- FaceCategory::
- locally_active_done_elsewhere ||
- face_is_owned[dcell->face(f)
- ->index()] ==
- FaceCategory::ghosted,
- ExcInternalError());
+ Assert(face_is_owned[dcell->face(f)
+ ->index()] ==
+ FaceCategory::
+ locally_active_done_elsewhere,
+ ExcInternalError());
}
else
{
task_info.refinement_edge_face_partition_data[0]));
for (auto &di : dof_info)
- di.compute_face_index_compression(face_info.faces);
+ di.compute_face_index_compression(
+ face_info.faces, additional_data.hold_all_faces_to_owned_cells);
// build the inverse map back from the faces array to
// cell_and_face_to_plain_faces
template void
DoFInfo::compute_face_index_compression<1>(
- const std::vector<FaceToCellTopology<1>> &);
+ const std::vector<FaceToCellTopology<1>> &,
+ bool);
template void
DoFInfo::compute_face_index_compression<2>(
- const std::vector<FaceToCellTopology<2>> &);
+ const std::vector<FaceToCellTopology<2>> &,
+ bool);
template void
DoFInfo::compute_face_index_compression<4>(
- const std::vector<FaceToCellTopology<4>> &);
+ const std::vector<FaceToCellTopology<4>> &,
+ bool);
template void
DoFInfo::compute_face_index_compression<8>(
- const std::vector<FaceToCellTopology<8>> &);
+ const std::vector<FaceToCellTopology<8>> &,
+ bool);
template void
DoFInfo::compute_face_index_compression<16>(
- const std::vector<FaceToCellTopology<16>> &);
+ const std::vector<FaceToCellTopology<16>> &,
+ bool);
template void
DoFInfo::compute_vector_zero_access_pattern<1>(
mf.vmult(out, in);
deallog << "Norm of result: " << out.l2_norm() << std::endl;
+
+ mf.manual_loop_vmult(out, in);
+
+ deallog << "Norm of result: " << out.l2_norm() << std::endl;
}
DEAL:2d::Testing FE_DGQ<2>(1)
DEAL:2d::Norm of result: 4.18
+DEAL:2d::Norm of result: 4.18
DEAL:3d::Testing FE_DGQ<3>(1)
DEAL:3d::Norm of result: 3.39
+DEAL:3d::Norm of result: 3.39
src);
}
+ void
+ manual_loop_vmult(VectorType &dst, const VectorType &src) const
+ {
+ src.update_ghost_values();
+ dst = 0;
+ local_apply(data, dst, src, std::make_pair(0, data.n_cell_batches()));
+ local_apply_face(data,
+ dst,
+ src,
+ std::make_pair(0, data.n_inner_face_batches()));
+ local_apply_boundary_face(data,
+ dst,
+ src,
+ std::make_pair(data.n_inner_face_batches(),
+ data.n_inner_face_batches() +
+ data.n_boundary_face_batches()));
+ local_apply_face(data,
+ dst,
+ src,
+ std::make_pair(data.n_inner_face_batches() +
+ data.n_boundary_face_batches(),
+ data.n_inner_face_batches() +
+ data.n_boundary_face_batches() +
+ data.n_ghost_inner_face_batches()));
+ }
+
private:
void
local_apply(const MatrixFree<dim, number, VectorizedArrayType> &data,