On Thu, 29 Oct 2009, Roy Stogner wrote:
On Thu, 29 Oct 2009, Tim Kroeger wrote:
Hmm... There seems to be some misunderstanding either on my side or on
yours. To check whether two elems (say, A and B) have a common point,
Elem::find_point_neighbors calls A.contains_point(nB) for all nodes nB of B
and B.contains_point(nA) for all nodes nA of A. The method
Elem::contains_point(), however, does *not* check whether the given point
is a node of the respective element; rather it uses an inverse map to check
whether the point is contained in the element. Hence, if I understand
correctly what you mean, these cases are caught correctly (and would be by
Elem::find_edge_neighbors() the same way). Or did you mean something
different?
Ah, you're right! It's been a while since I wrote
find_point_neighbors; I thought it was just testing node sharing. The
inverse_map based point test ought to work fine, both for it and for
your proposed find_edge_neighbors.
Alright, here's my patch. I'll test whether my application does the
expected thing with this, and if it does (and nobody objects), I'll
try to do my first commit on Monday. I'll let you know whether it
worked.
Best Regards,
Tim
--
Dr. Tim Kroeger
[email protected] Phone +49-421-218-7710
[email protected] Fax +49-421-218-4236
Fraunhofer MEVIS, Institute for Medical Image Computing
Universitaetsallee 29, 28359 Bremen, Germany
Index: include/geom/elem.h
===================================================================
--- include/geom/elem.h (Revision 3518)
+++ include/geom/elem.h (Arbeitskopie)
@@ -211,12 +211,25 @@
bool contains_vertex_of(const Elem *e) const;
/**
+ * This function returns true iff an edge of \p e is contained in
+ * this element. (Internally, this is done by checking whether at
+ * least two vertices of \p e are contained in this element).
+ */
+ bool contains_edge_of(const Elem *e) const;
+
+ /**
* This function finds all elements which
* touch the current element at any point
*/
void find_point_neighbors(std::set<const Elem *> &neighbor_set) const;
/**
+ * This function finds all elements which touch the current element
+ * at any edge (more precisely, at at least two points).
+ */
+ void find_edge_neighbors(std::set<const Elem *> &neighbor_set) const;
+
+ /**
* Resets this element's neighbors' appropriate neighbor pointers
* and its parent's and children's appropriate pointers
* to point to the global remote_elem instead of this.
Index: src/geom/elem.C
===================================================================
--- src/geom/elem.C (Revision 3518)
+++ src/geom/elem.C (Arbeitskopie)
@@ -440,6 +440,27 @@
+bool Elem::contains_edge_of(const Elem *e) const
+{
+ unsigned int num_contained_edges = 0;
+
+ // Our vertices are the first numbered nodes
+ for (unsigned int n = 0; n != e->n_vertices(); ++n)
+ {
+ if (this->contains_point(e->point(n)))
+ {
+ num_contained_edges++;
+ if(num_contained_edges>=2)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+
void Elem::find_point_neighbors(std::set<const Elem *> &neighbor_set) const
{
neighbor_set.clear();
@@ -498,6 +519,64 @@
+void Elem::find_edge_neighbors(std::set<const Elem *> &neighbor_set) const
+{
+ neighbor_set.clear();
+ neighbor_set.insert(this);
+
+ unsigned int old_size;
+ do
+ {
+ old_size = neighbor_set.size();
+
+ // Loop over all the elements in the patch
+ std::set<const Elem*>::const_iterator it = neighbor_set.begin();
+ const std::set<const Elem*>::const_iterator end = neighbor_set.end();
+
+ for (; it != end; ++it)
+ {
+ const Elem* elem = *it;
+
+ for (unsigned int s=0; s<elem->n_sides(); s++)
+ {
+ const Elem* neighbor = elem->neighbor(s);
+ if (neighbor &&
+ neighbor != remote_elem) // we have a real neighbor on
this side
+ {
+ if (neighbor->active()) // ... if it is active
+ {
+ if (this->contains_edge_of(neighbor) // ... and touches
us
+ || neighbor->contains_edge_of(this))
+ neighbor_set.insert (neighbor); // ... then add it
+ }
+#ifdef LIBMESH_ENABLE_AMR
+ else // ... the neighbor is
*not* active,
+ { // ... so add *all*
neighboring
+ // active children
+ std::vector<const Elem*> active_neighbor_children;
+
+ neighbor->active_family_tree_by_neighbor
+ (active_neighbor_children, elem);
+
+ std::vector<const Elem*>::const_iterator
+ child_it = active_neighbor_children.begin();
+ const std::vector<const Elem*>::const_iterator
+ child_end = active_neighbor_children.end();
+ for (; child_it != child_end; ++child_it)
+ if (this->contains_edge_of(*child_it) ||
+ (*child_it)->contains_edge_of(this))
+ neighbor_set.insert (*child_it);
+ }
+#endif // #ifdef LIBMESH_ENABLE_AMR
+ }
+ }
+ }
+ }
+ while (old_size != neighbor_set.size());
+}
+
+
+
#ifdef DEBUG
void Elem::libmesh_assert_valid_node_pointers() const
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Libmesh-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libmesh-users