location_maps.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 #include <limits>
22 #include <utility>
23 
24 // Local Includes -----------------------------------
25 #include "libmesh/elem.h"
26 #include "libmesh/location_maps.h"
27 #include "libmesh/mesh_base.h"
28 #include "libmesh/node.h"
29 #include "libmesh/parallel.h"
30 
31 
32 
33 //--------------------------------------------------------------------------
34 namespace
35 {
36  using libMesh::Real;
37 
38  // 10 bits per coordinate, to work with 32+ bit machines
39  const unsigned int chunkmax = 1024;
40  const Real chunkfloat = 1024.0;
41 }
42 
43 
44 
45 namespace libMesh
46 {
47 
48 //--------------------------------------------------------------------------
49 template <typename T>
51 {
52  // This function must be run on all processors at once
53  // for non-serial meshes
54  if (!mesh.is_serial())
56 
57  START_LOG("init()", "LocationMap");
58 
59  // Clear the old map
60  _map.clear();
61 
62  // Cache a bounding box
63  _lower_bound.clear();
64  _lower_bound.resize(LIBMESH_DIM, std::numeric_limits<Real>::max());
65  _upper_bound.clear();
66  _upper_bound.resize(LIBMESH_DIM, -std::numeric_limits<Real>::max());
67 
69  const MeshBase::node_iterator end = mesh.nodes_end();
70 
71  for (; it != end; ++it)
72  {
73  Node* node = *it;
74 
75  for (unsigned int i=0; i != LIBMESH_DIM; ++i)
76  {
77  // Expand the bounding box if necessary
78  _lower_bound[i] = std::min(_lower_bound[i],
79  (*node)(i));
80  _upper_bound[i] = std::max(_upper_bound[i],
81  (*node)(i));
82  }
83  }
84 
85  // On a parallel mesh we might not yet have a full bounding box
86  if (!mesh.is_serial())
87  {
88  mesh.comm().min(_lower_bound);
89  mesh.comm().max(_upper_bound);
90  }
91 
92  this->fill(mesh);
93 
94  STOP_LOG("init()", "LocationMap");
95 }
96 
97 
98 
99 template <typename T>
101 {
102  this->_map.insert(std::make_pair(this->key(this->point_of(t)), &t));
103 }
104 
105 
106 
107 template <>
109 {
110  return node;
111 }
112 
113 
114 
115 template <>
117 {
118  return elem.centroid();
119 }
120 
121 
122 
123 template <typename T>
125  const Real tol)
126 {
127  START_LOG("find()","LocationMap");
128 
129  // Look for a likely key in the multimap
130  unsigned int pointkey = this->key(p);
131 
132  // Look for the exact key first
133  std::pair<typename map_type::iterator,
134  typename map_type::iterator>
135  pos = _map.equal_range(pointkey);
136 
137  while (pos.first != pos.second)
139  (this->point_of(*(pos.first->second)), tol))
140  {
141  STOP_LOG("find()","LocationMap");
142  return pos.first->second;
143  }
144  else
145  ++pos.first;
146 
147  // Look for neighboring bins' keys next
148  for (int xoffset = -1; xoffset != 2; ++xoffset)
149  {
150  for (int yoffset = -1; yoffset != 2; ++yoffset)
151  {
152  for (int zoffset = -1; zoffset != 2; ++zoffset)
153  {
154  std::pair<typename map_type::iterator,
155  typename map_type::iterator>
156  key_pos = _map.equal_range(pointkey +
157  xoffset*chunkmax*chunkmax +
158  yoffset*chunkmax +
159  zoffset);
160  while (key_pos.first != key_pos.second)
162  (this->point_of(*(key_pos.first->second)), tol))
163  {
164  STOP_LOG("find()","LocationMap");
165  return key_pos.first->second;
166  }
167  else
168  ++key_pos.first;
169  }
170  }
171  }
172 
173  STOP_LOG("find()","LocationMap");
174  return NULL;
175 }
176 
177 
178 
179 template <typename T>
180 unsigned int LocationMap<T>::key(const Point& p)
181 {
182  Real xscaled = 0., yscaled = 0., zscaled = 0.;
183 
184  Real deltax = _upper_bound[0] - _lower_bound[0];
185 
186  if (std::abs(deltax) > TOLERANCE)
187  xscaled = (p(0) - _lower_bound[0])/deltax;
188 
189  // Only check y-coords if libmesh is compiled with LIBMESH_DIM>1
190 #if LIBMESH_DIM > 1
191  Real deltay = _upper_bound[1] - _lower_bound[1];
192 
193  if (std::abs(deltay) > TOLERANCE)
194  yscaled = (p(1) - _lower_bound[1])/deltay;
195 #endif
196 
197  // Only check z-coords if libmesh is compiled with LIBMESH_DIM>2
198 #if LIBMESH_DIM > 2
199  Real deltaz = _upper_bound[2] - _lower_bound[2];
200 
201  if (std::abs(deltaz) > TOLERANCE)
202  zscaled = (p(2) - _lower_bound[2])/deltaz;
203 #endif
204 
205  unsigned int n0 = static_cast<unsigned int> (chunkfloat * xscaled),
206  n1 = static_cast<unsigned int> (chunkfloat * yscaled),
207  n2 = static_cast<unsigned int> (chunkfloat * zscaled);
208 
209  return chunkmax*chunkmax*n0 + chunkmax*n1 + n2;
210 }
211 
212 
213 
214 template <>
216 {
217  // Populate the nodes map
219  end = mesh.nodes_end();
220  for (; it != end; ++it)
221  this->insert(**it);
222 }
223 
224 
225 
226 template <>
228 {
229  // Populate the elem map
231  end = mesh.active_elements_end();
232  for (; it != end; ++it)
233  this->insert(**it);
234 }
235 
236 
237 
238 template class LocationMap<Elem>;
239 template class LocationMap<Node>;
240 
241 } // namespace libMesh

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

Hosted By:
SourceForge.net Logo