| 193 | } // ~IBFEPatchRecoveryPostProcessor |
| 194 | |
| 195 | void |
| 196 | IBFEPatchRecoveryPostProcessor::initializeFEData(const PeriodicBoundaries* const periodic_boundaries) |
| 197 | { |
| 198 | d_periodic_boundaries = periodic_boundaries; |
| 199 | |
| 200 | const Parallel::Communicator& comm = d_mesh->comm(); |
| 201 | const int mpi_rank = comm.rank(); |
| 202 | const int mpi_size = comm.size(); |
| 203 | |
| 204 | // Active local elements. |
| 205 | const MeshBase::const_element_iterator el_begin = d_mesh->active_local_elements_begin(); |
| 206 | const MeshBase::const_element_iterator el_end = d_mesh->active_local_elements_end(); |
| 207 | |
| 208 | // Determine the element patches associated with each node N, which is |
| 209 | // defined to be the collection of elements that contain node N. |
| 210 | // |
| 211 | // Unlike the standard Z-Z patch recovery algorithm, we use "tight" element |
| 212 | // patches for non-vertex nodes. |
| 213 | std::unique_ptr<PointLocatorBase> point_locator = PointLocatorBase::build(TREE, *d_mesh); |
| 214 | for (MeshBase::const_element_iterator el_it = el_begin; el_it != el_end; ++el_it) |
| 215 | { |
| 216 | const Elem* const elem = *el_it; |
| 217 | for (unsigned int n = 0; n < elem->n_nodes(); ++n) |
| 218 | { |
| 219 | // Only set up patches for local nodes. |
| 220 | const Node* const node = elem->get_node_ptr(n); |
| 221 | if (node->processor_id() != mpi_rank) continue; |
| 222 | |
| 223 | // Only set up patches once for each node. |
| 224 | const dof_id_type node_id = node->id(); |
| 225 | if (d_local_elem_patches.find(node_id) != d_local_elem_patches.end()) continue; |
| 226 | |
| 227 | // Find the elements that touch this node. |
| 228 | ElemPatch& elem_patch = d_local_elem_patches[node_id]; |
| 229 | std::set<const Elem*> elems; |
| 230 | elem->find_point_neighbors(*node, elems); |
| 231 | for (std::set<const Elem*>::const_iterator it = elems.begin(); it != elems.end(); ++it) |
| 232 | { |
| 233 | elem_patch.insert(boost::make_tuple(*it, CompositePeriodicMapping(), CompositePeriodicMapping())); |
| 234 | } |
| 235 | |
| 236 | // Account for periodic boundaries. |
| 237 | bool done = false || !d_periodic_boundaries; |
| 238 | while (!done) |
| 239 | { |
| 240 | ElemPatch periodic_neighbors; |
| 241 | for (ElemPatch::const_iterator it = elem_patch.begin(); it != elem_patch.end(); ++it) |
| 242 | { |
| 243 | const Elem* const elem = it->get<0>(); |
| 244 | const CompositePeriodicMapping& forward_mapping = it->get<1>(); |
| 245 | const CompositePeriodicMapping& inverse_mapping = it->get<2>(); |
| 246 | const libMesh::Point p = apply_composite_periodic_mapping(forward_mapping, *node); |
| 247 | TBOX_ASSERT(elem->contains_point(p)); |
| 248 | for (unsigned int i = 0; i < elem->n_neighbors(); ++i) |
| 249 | { |
| 250 | if (!elem->neighbor_ptr(i)) |
| 251 | { |
| 252 | const std::vector<boundary_id_type>& boundary_ids = |
nothing calls this directly
no test coverage detected