point_locator_list.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 // C++ includes
21 
22 // Local Includes
23 #include "libmesh/elem.h"
25 #include "libmesh/mesh_base.h"
27 
28 namespace libMesh
29 {
30 
31 
32 // typedefs
33 typedef std::vector<Point>::const_iterator const_list_iterator;
34 
35 
36 //------------------------------------------------------------------
37 // PointLocator methods
39  const PointLocatorBase* master) :
40  PointLocatorBase (mesh,master),
41  _list (NULL)
42 {
43  // This code will only work if your mesh is the Voroni mesh of it's
44  // own elements' centroids. If your mesh is that regular you might
45  // as well hand-code an O(1) algorithm for locating points within
46  // it. - RHS
47  libmesh_experimental();
48 
49  this->init();
50 }
51 
52 
53 
54 
56 {
57  this->clear ();
58 }
59 
60 
61 
62 
64 {
65  // only delete the list when we are the master
66  if (this->_list != NULL)
67  {
68  if (this->_master == NULL)
69  {
70  // we own the list
71  this->_list->clear();
72  delete this->_list;
73  }
74  else
75  // someone else owns and therefore deletes the list
76  this->_list = NULL;
77  }
78 }
79 
80 
81 
82 
83 
85 {
86  libmesh_assert (!this->_list);
87 
88  if (this->_initialized)
89  {
90  libMesh::err << "ERROR: Already initialized! Will ignore this call..."
91  << std::endl;
92  }
93 
94  else
95 
96  {
97 
98  if (this->_master == NULL)
99  {
100  START_LOG("init(no master)", "PointLocatorList");
101 
102  // We are the master, so we have to build the list.
103  // First create it, then get a handy reference, and
104  // then try to speed up by reserving space...
105  this->_list = new std::vector<std::pair<Point, const Elem *> >;
106  std::vector<std::pair<Point, const Elem *> >& my_list = *(this->_list);
107 
108  my_list.clear();
109  my_list.reserve(this->_mesh.n_active_elem());
110 
111  // fill our list with the centroids and element
112  // pointers of the mesh. For this use the handy
113  // element iterators.
114 // const_active_elem_iterator el (this->_mesh.elements_begin());
115 // const const_active_elem_iterator end(this->_mesh.elements_end());
116 
119 
120  for (; el!=end; ++el)
121  my_list.push_back(std::make_pair((*el)->centroid(), *el));
122 
123  STOP_LOG("init(no master)", "PointLocatorList");
124  }
125 
126  else
127 
128  {
129  // We are _not_ the master. Let our _list point to
130  // the master's list. But for this we first transform
131  // the master in a state for which we are friends
132  // (this should also beware of a bad master pointer?).
133  // And make sure the master @e has a list!
134  const PointLocatorList* my_master =
135  libmesh_cast_ptr<const PointLocatorList*>(this->_master);
136 
137  if (my_master->initialized())
138  this->_list = my_master->_list;
139  else
140  {
141  libMesh::err << "ERROR: Initialize master first, then servants!"
142  << std::endl;
143  libmesh_error();
144  }
145  }
146 
147  }
148 
149 
150  // ready for take-off
151  this->_initialized = true;
152 }
153 
154 
155 
156 
157 
158 const Elem* PointLocatorList::operator() (const Point& p) const
159 {
160  libmesh_assert (this->_initialized);
161 
162  START_LOG("operator()", "PointLocatorList");
163 
164  // Ask the list. This is quite expensive, since
165  // we loop through the whole list to try to find
166  // the @e nearest element.
167  // However, there is not much else to do: when
168  // we would use bounding boxes like in a tree,
169  // it may happen that a surface element is just
170  // in plane with a bounding box face, and quite
171  // close to it. But when a point comes, this
172  // point may belong to the bounding box (where the
173  // coplanar element does @e not belong to). Then
174  // we would search through the elements in this
175  // bounding box, while the other bounding box'es
176  // element is closer, but we simply don't consider
177  // it!
178  //
179  // We _can_, however, use size_sq() instead of size()
180  // here to avoid repeated calls to std::sqrt(), which is
181  // pretty expensive.
182  {
183  std::vector<std::pair<Point, const Elem *> >& my_list = *(this->_list);
184 
185  Real last_distance_sq = Point(my_list[0].first -p).size_sq();
186  const Elem * last_elem = NULL;
187  const std::size_t max_index = my_list.size();
188 
189 
190  for (std::size_t n=1; n<max_index; n++)
191  {
192  const Real current_distance_sq = Point(my_list[n].first -p).size_sq();
193 
194  if (current_distance_sq < last_distance_sq)
195  {
196  last_distance_sq = current_distance_sq;
197  last_elem = my_list[n].second;
198  }
199  }
200 
201  // If we found an element, it should be active
202  libmesh_assert (!last_elem || last_elem->active());
203 
204  STOP_LOG("operator()", "PointLocatorList");
205 
206  // return the element
207  return (last_elem);
208  }
209 
210 }
211 
212 void PointLocatorList::enable_out_of_mesh_mode (void)
213 {
214  /* This functionality is not yet implemented for PointLocatorList. */
215  libmesh_not_implemented();
216 }
217 
218 void PointLocatorList::disable_out_of_mesh_mode (void)
219 {
220  /* This functionality is not yet implemented for PointLocatorList. */
221  libmesh_not_implemented();
222 }
223 
224 } // namespace libMesh

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:06 UTC

Hosted By:
SourceForge.net Logo