void ElemCutter::find_intersection_points(const Elem &elem, const std::vector<Real> &vertex_distance_func) { _intersection_pts.clear(); for (unsigned int e=0; e<elem.n_edges(); e++) { AutoPtr<Elem> edge (elem.build_edge(e)); // find the element nodes el0, el1 that map unsigned int el0 = elem.get_node_index(edge->get_node(0)), el1 = elem.get_node_index(edge->get_node(1)); libmesh_assert (elem.is_vertex(el0)); libmesh_assert (elem.is_vertex(el1)); libmesh_assert_less (el0, vertex_distance_func.size()); libmesh_assert_less (el1, vertex_distance_func.size()); const Real d0 = vertex_distance_func[el0], d1 = vertex_distance_func[el1]; // if this egde has a 0 crossing if (d0*d1 < 0.) { libmesh_assert_not_equal_to (d0, d1); // then find d_star in [0,1], the // distance from el0 to el1 where the 0 lives. const Real d_star = d0 / (d0 - d1); // Prevent adding nodes trivially close to existing // nodes. const Real endpoint_tol = 0.01; if ( (d_star > endpoint_tol) && (d_star < (1.-endpoint_tol)) ) { const Point x_star = (edge->point(0)*(1.-d_star) + edge->point(1)*d_star); std::cout << "adding cut point (d_star, x_star) = " << d_star << " , " << x_star << std::endl; _intersection_pts.push_back (x_star); } } } }
//----------------------------------------------------------------- // Mesh refinement methods bool MeshRefinement::limit_level_mismatch_at_edge (const unsigned int max_mismatch) { // This function must be run on all processors at once parallel_only(); bool flags_changed = false; // Maps holding the maximum element level that touches an edge std::map<std::pair<unsigned int, unsigned int>, unsigned char> max_level_at_edge; std::map<std::pair<unsigned int, unsigned int>, unsigned char> max_p_level_at_edge; // Loop over all the active elements & fill the maps { MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); for (; elem_it != elem_end; ++elem_it) { const Elem* elem = *elem_it; const unsigned char elem_level = elem->level() + ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0); const unsigned char elem_p_level = elem->p_level() + ((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0); // Set the max_level at each edge for (unsigned int n=0; n<elem->n_edges(); n++) { AutoPtr<Elem> edge = elem->build_edge(n); unsigned int childnode0 = edge->node(0); unsigned int childnode1 = edge->node(1); if (childnode1 < childnode0) std::swap(childnode0, childnode1); for (const Elem *p = elem; p != NULL; p = p->parent()) { AutoPtr<Elem> pedge = p->build_edge(n); unsigned int node0 = pedge->node(0); unsigned int node1 = pedge->node(1); if (node1 < node0) std::swap(node0, node1); // If elem does not share this edge with its ancestor // p, refinement levels of elements sharing p's edge // are not restricted by refinement levels of elem. // Furthermore, elem will not share this edge with any // of p's ancestors, so we can safely break out of the // for loop early. if (node0 != childnode0 && node1 != childnode1) break; childnode0 = node0; childnode1 = node1; std::pair<unsigned int, unsigned int> edge_key = std::make_pair(node0, node1); if (max_level_at_edge.find(edge_key) == max_level_at_edge.end()) { max_level_at_edge[edge_key] = elem_level; max_p_level_at_edge[edge_key] = elem_p_level; } else { max_level_at_edge[edge_key] = std::max (max_level_at_edge[edge_key], elem_level); max_p_level_at_edge[edge_key] = std::max (max_p_level_at_edge[edge_key], elem_p_level); } } } } } // Now loop over the active elements and flag the elements // who violate the requested level mismatch { MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); for (; elem_it != elem_end; ++elem_it) { Elem* elem = *elem_it; const unsigned int elem_level = elem->level(); const unsigned int elem_p_level = elem->p_level(); // Skip the element if it is already fully flagged if (elem->refinement_flag() == Elem::REFINE && elem->p_refinement_flag() == Elem::REFINE) continue; // Loop over the nodes, check for possible mismatch for (unsigned int n=0; n<elem->n_edges(); n++) { AutoPtr<Elem> edge = elem->build_edge(n); unsigned int node0 = edge->node(0); unsigned int node1 = edge->node(1); if (node1 < node0) std::swap(node0, node1); std::pair<unsigned int, unsigned int> edge_key = std::make_pair(node0, node1); // Flag the element for refinement if it violates // the requested level mismatch if ( (elem_level + max_mismatch) < max_level_at_edge[edge_key] && elem->refinement_flag() != Elem::REFINE) { elem->set_refinement_flag (Elem::REFINE); flags_changed = true; } if ( (elem_p_level + max_mismatch) < max_p_level_at_edge[edge_key] && elem->p_refinement_flag() != Elem::REFINE) { elem->set_p_refinement_flag (Elem::REFINE); flags_changed = true; } } } } // If flags changed on any processor then they changed globally CommWorld.max(flags_changed); return flags_changed; }