SheafSystem  0.0.0.0
array_cylindrical_point_locator.cc
Go to the documentation of this file.
1 
2 //
3 // Copyright (c) 2014 Limit Point Systems, Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 
20 
21 #include "SheafSystem/array_cylindrical_point_locator.h"
22 
23 #include "SheafSystem/sec_ed.h"
24 #include "SheafSystem/section_space_schema_poset.h"
25 #include "SheafSystem/structured_block_2d.h"
26 #include "SheafSystem/unstructured_block.h"
27 
28 using namespace std;
29 using namespace geometry; // Workaround for MS C++ bug.
30 
31 // ===========================================================
32 // ARRAY_CYLINDRICAL_POINT_LOCATOR FACET
33 // ===========================================================
34 
37  const block<size_type>& xbin_ub)
38  : cylindrical_point_locator(xcoords)
39 {
40  // Preconditions:
41 
42  require(xcoords.state_is_read_accessible());
43  require(xcoords.schema().df() == DC);
44  require(xcoords.schema().db() == DB);
45  require(is_dlinear_quads(xcoords) || is_dlinear_triangles(xcoords));
46  require(xbin_ub.ct() >= DB);
47  require_for_all(i, 0, DB, xbin_ub[i] > 0);
48 
49  // Body:
50 
51  for(int i=0; i<DB; i++)
52  {
53  _bin_ub[i] = xbin_ub[i];
54  }
55 
56  _bin_0_max = static_cast<sec_vd_value_type>(_bin_ub[0]) - 0.99;
57 
58  update();
59 
60  // Postconditions:
61 
62 
63  // Exit:
64 
65  return;
66 }
67 
70  : cylindrical_point_locator(xcoords)
71 {
72  // Preconditions:
73 
74  require(xcoords.state_is_read_accessible());
75  require(xcoords.schema().df() == DC);
76  require(is_dlinear_quads(xcoords) || is_dlinear_triangles(xcoords));
77 
78  // Body:
79 
80  // Set _bin_ub to the db()-th root of the number of evaluation members.
81 
82  double leval_ct = static_cast<double>(xcoords.schema().evaluation_ct());
83  size_type lbin_ub =
84  static_cast<size_type>(exp(log(leval_ct)/static_cast<double>(DB)));
85 
86  // Make sure ub is at least 1.
87 
88  lbin_ub = (lbin_ub > 1) ? lbin_ub : 1;
89 
90 
91  for(int i=0; i<DB; i++)
92  {
93  _bin_ub[i] = lbin_ub;
94  }
95 
96  _bin_0_max = _bin_ub[0] - 1;
97 
98  update();
99 
100  // Postconditions:
101 
102 
103  // Exit:
104 
105  return;
106 }
107 
110 {
111  // Preconditions:
112 
113  // Body:
114 
115  // Nothing to do.
116 
117  // Postconditions:
118 
119  // Exit:
120 
121  return;
122 }
123 
126 size() const
127 {
128  size_type result;
129 
130  // Preconditions:
131 
132 
133  // Body:
134 
135  result = _bins.ct();
136 
137  // Postconditions:
138 
139  ensure(result > 0);
140 
141  // Exit:
142 
143  return result;
144 }
145 
148 capacity() const
149 {
150  size_type result;
151 
152  // Preconditions:
153 
154 
155  // Body:
156 
157  result = _bins.ub();
158 
159  // Postconditions:
160 
161  ensure(result > 0);
162 
163  // Exit:
164 
165  return result;
166 }
167 
168 bool
170 is_dlinear_quads(const sec_ed& xcoords) const
171 {
172  bool result;
173 
174  // Preconditions:
175 
176  require(xcoords.state_is_read_accessible());
177 
178  // Body:
179 
180  result = (xcoords.schema().evaluator_family_name() == "dlinear");
181  if(result)
182  {
183  pod_index_type lbase_id = xcoords.schema().base_space_id();
184  string ltype_name =
185  xcoords.schema().host()->base_space().type_name(lbase_id);
186 
187  // The following is stricter than necessary; all we need is quads.
188  // but there's no other easy way to find out.
189 
190  result = (ltype_name == "structured_block_2d");
191  if(result)
192  {
193  structured_block_2d lblock(xcoords.schema().base_space());
194  ltype_name = lblock.local_cell_type_name();
195  result = (ltype_name.find("quad") != string::npos);
196  lblock.detach_from_state();
197  }
198  }
199 
200  // Postconditions:
201 
202 
203  // Exit:
204 
205  return result;
206 }
207 
208 bool
210 is_dlinear_triangles(const sec_ed& xcoords) const
211 {
212  bool result;
213 
214  // Preconditions:
215 
216  require(xcoords.state_is_read_accessible());
217 
218  // Body:
219 
220  result = (xcoords.schema().evaluator_family_name() == "dlinear");
221  if(result)
222  {
223  pod_index_type lbase_id = xcoords.schema().base_space_id();
224  string ltype_name =
225  xcoords.schema().host()->base_space().type_name(lbase_id);
226 
227  // The following is stricter than necessary; all we need is quads.
228  // but there's no other easy way to find out.
229 
230  result = (ltype_name == "unstructured_block");
231  if(result)
232  {
233  unstructured_block lblock(xcoords.schema().base_space());
234  ltype_name = lblock.local_cell_type_name();
235  result = (ltype_name.find("triangle") != string::npos);
236  lblock.detach_from_state();
237  }
238  }
239 
240  // Postconditions:
241 
242 
243  // Exit:
244 
245  return result;
246 }
247 
248 
249 // PROTECTED MEMBER FUNCTIONS
250 
251 void
254 {
255  // Preconditions:
256 
257  require(is_empty());
258 
259  // Body:
260 
261  // Compute the bin size.
262 
263  _bin_size[0] = 360.0/_bin_ub[0];
264  _bin_size[1] = 180.0/_bin_ub[1];
265 
266 
267  // Compute the reciprocal of the smallest bin size.
268  // Used for efficiency in relative_position_pa().
269 
271  for(int i=0; i<DB; i++)
272  {
273  _one_over_min_bin_size[i] = 1.0/_bin_size[i];
274  }
275 
276  // Reset the size of the bin array.
277 
278  size_type lbin_ct = 1;
279  for(int i=0; i<DB; i++)
280  {
281  lbin_ct *= _bin_ub[i];
282  }
283 
284  _bins.reserve(lbin_ct);
285  _bins.set_ct(lbin_ct);
286 
289 
291 
292  // Postconditions:
293 
294  // Exit:
295 
296  return;
297 }
298 
301 bin_id(const d_bin_coordinates<2, 2>& xcoord) const
302 {
303  return (xcoord[0]*_bin_ub[1] + xcoord[1]);
304 };
305 
308 bin_id(const block<size_type>& xid) const
309 {
310  return (xid[0]*_bin_ub[1] + xid[1]);
311 };
312 
316 {
317  return (xi*_bin_ub[1] + xj);
318 };
319 
320 
321 // ===========================================================
322 // CYLINDRICAL_POINT_LOCATOR FACET
323 // ===========================================================
324 
325 // PUBLIC MEMBER FUNCTIONS
326 
327 void
330 {
331  // Preconditions:
332 
333  require(xbox != 0);
334 
335  // Body:
336 
337  define_old_variable(size_type old_box_ct = _box_ct);
338 
339  size_type ilb = xbox->lb()[0];
340  size_type jlb = xbox->lb()[1];
341  size_type iub = xbox->ub()[0];
342  size_type jub = xbox->ub()[1];
343 
344  for(size_type i=ilb; i<=iub; ++i)
345  {
346  for(size_type j=jlb; j<=jub; ++j)
347  {
348  _bins[bin_id(i, j)].push_front(xbox);
349  }
350  }
351 
352  _box_ct++;
353 
354 
355  // Postconditions:
356 
357  ensure(contains_box(xbox));
358  ensure(box_ct() == old_box_ct + 1);
359 
360  // Exit:
361 
362  return;
363 }
364 
365 void
368 {
369  // Preconditions:
370 
371  require(xbox != 0);
372  require(contains_box(xbox));
373 
374  // Body:
375 
376  define_old_variable(size_type old_box_ct = _box_ct);
377 
378  size_type ilb = xbox->lb()[0];
379  size_type jlb = xbox->lb()[1];
380  size_type iub = xbox->ub()[0];
381  size_type jub = xbox->ub()[1];
382 
383  for(size_type i=ilb; i<=iub; ++i)
384  {
385  for(size_type j=jlb; j<=jub; ++j)
386  {
387  _bins[bin_id(i, j)].remove(xbox);
388  }
389  }
390 
391  _box_ct--;
392 
393  // Postconditions:
394 
395  ensure(!contains_box(xbox));
396  ensure(box_ct() == old_box_ct - 1);
397 
398  // Exit:
399 
400  return;
401 }
402 
406 {
407  // Preconditions:
408 
409  require(xpt != 0);
410  require(xpt_ub >= db());
411 
412  // Body:
413 
415  relative_position_pa(xpt, xpt_ub, lcoord);
416 
417  const box_list_type& result = _bins[bin_id(lcoord)];
418 
419  // Postconditions:
420 
421  // Exit:
422 
423  return result;
424 }
425 
426 bool
429 {
430  bool result = true;
431 
432  // Preconditions:
433 
434  require(xbox != 0);
435 
436  // Body:
437 
438  // Xbox has been inserted in this if and only if it has bin inserted in
439  // every bin that it overlaps. So all we have to check is one bin;
440  // the one containg the lower bound is convenient.
441 
442  box_list_type& llist = _bins[bin_id(xbox->lb())];
443  box_list_type::const_iterator itr = llist.begin();
444  while((itr != llist.end()) && (*itr != xbox))
445  {
446  ++itr;
447  }
448 
449  result = (itr != llist.end());
450 
451  // Postconditions:
452 
453 
454  // Exit:
455 
456  return result;
457 }
458 
459 void
462 {
463  // Preconditions:
464 
465  // Body:
466 
467  for(size_type i=0; i<_bins.ct(); i++)
468  {
469  _bins[i].clear();
470  }
471 
472  _box_ct = 0;
473 
474  // Postconditions:
475 
476  ensure(is_empty());
477 
478  // Exit:
479 
480  return;
481 }
482 
483 
484 // ===========================================================
485 // POINT_LOCATOR FACET
486 // ===========================================================
487 
488 // PUBLIC MEMBER FUNCTIONS
489 
493 operator=(const point_locator& xother)
494 {
495 
496  // Preconditions:
497 
498  // Body:
499 
500  not_implemented();
501 
502  // Postconditions:
503 
504  ensure(invariant());
505 
506  // Exit:
507 
508  return *this;
509 }
510 
515 {
516 
517  // Preconditions:
518 
519  // Body:
520 
521  not_implemented();
522 
523  // Postconditions:
524 
525  ensure(invariant());
526 
527  // Exit:
528 
529  return *this;
530 }
531 
532 bool
534 invariant() const
535 {
536  bool result = true;
537 
538  invariance(size() > 0);
539  invariance(capacity() > 0);
540 
541 
542  return result;
543 }
544 
545 
546 // ===========================================================
547 // NON-MEMBER FUNCTIONS
548 // ===========================================================
549 
550 std::ostream&
552 {
553  // Preconditions:
554 
555  // Body:
556 
557  cout << "lb =";
558  for(int i=0; i< xpl.db(); i++)
559  {
560  cout << " " << xpl.lb()[i];
561  }
562  cout << endl;
563 
564  cout << "ub =";
565  for(int i=0; i< xpl.db(); i++)
566  {
567  cout << " " << xpl.ub()[i];
568  }
569  cout << endl;
570 
571  // Postconditions:
572 
573  // Exit:
574 
575  return xos;
576 }
577 
size_type capacity() const
The number of bins allocated for use by the search structure.
array_cylindrical_point_locator()
Default constructor; disabled.
virtual void update()
Updates the search structure to the current values of coordinates().
size_type size() const
The number of bins used by the search structure.
block< sec_vd_value_type > _one_over_min_bin_size
Reciprocal of the dimensions of the smallest bins.
section_space_schema_poset * host() const
The poset which this is a handle to a component of.
size_type ct() const
The number of items currently in use.
bool is_dlinear_triangles(const sec_ed &xcoords) const
True if the base space of xcoords is a block of triangles and the evaluator family id dlinear...
A homogeneous collection of connected quads arranged in an i_size() x j_size() array.
size_type box_ct() const
The number of bounding boxes stored in the search structure.
std::string type_name(pod_index_type xmbr_hub_id) const
The type id of the member with hub id xmbr_hub_id.
bool state_is_read_accessible() const
True if this is attached and if the state is accessible for read or access control is disabled...
virtual void insert_box(d_bounding_box< 2, 2 > *xbox)
Insert xbox into this.
STL namespace.
block< size_type > _bin_ub
The upper bound for the bin index.
OBSOLETE: use zone_nodes_block or point_block_*d. A client handle for a base space member which repre...
const block< sec_vd_value_type > & lb() const
The lower bound of the domain defined by coordinates().
const d_bin_coordinates< DC, DB > & ub() const
The upper bound; the upper, right, rear corner.
iterator begin()
Returns an iterator to the first element of the container.
Fixed point relative coordinates for a tree domain.
sec_vd_value_type _bin_0_max
A sec_vd_value_type that truncates to the maximum index for bin 0.
static int_type ub()
The upper bound for components.
A section of a fiber bundle with a d-dimensional Euclidean vector space fiber.
Definition: sec_ed.h:47
void relative_position_pa(sec_vd_value_type *xpt, size_type xpt_ub, d_bin_coordinates< 2, 2 > &xresult) const
The position of xpt relative to the lower bound, in integer coordinates; pre-allocated version...
block< sec_vd_value_type > _bin_size
The dimensions of the smallest bins.
virtual array_cylindrical_point_locator & operator=(const point_locator &xother)
Assignment operator.
void update_bins()
Resets this with bounds xlb, xub, and xbin_ub. If xbin_ub == 0; use default_bin_ub().
A point location query in domains with global coordinate dimension DC and local coordinate dimension ...
bool is_dlinear_quads(const sec_ed &xcoords) const
True if the base space of xcoords is a block of quads and the evaluator family id dlinear...
size_type bin_id(const d_bin_coordinates< 2, 2 > &xcoord) const
The single index (offset) associated with tree coordinates xcoord.
const d_bin_coordinates< DC, DB > & lb() const
The lower bound; the lower, left, front corner.
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
virtual bool contains_box(d_bounding_box< 2, 2 > *xbox) const
True if xbox is in this.
A bounding box that can be strung together into a list.
virtual void remove_box(d_bounding_box< 2, 2 > *xbox)
Remove xbox from this.
std::string evaluator_family_name() const
The name of the evaluator family for section spaces on schemae hosted by this.
virtual const box_list_type & box_list(sec_vd_value_type *xpt, size_type xpt_ub) const
The list of bounding boxes which may contain xpt.
iterator end()
Returns an iterator to the element following the last element of the container.
SHEAF_DLL_SPEC void log(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute log of x0 (log(x0)) (pre-allocated version).
Definition: sec_at0.cc:1434
virtual void clear()
Clear this of all bounding boxes.
An abstract point location query in domains with global coordinate dimension dc and local coordinate ...
block< box_list_type > _bins
The search structure; a d-dimensional array of bins.
size_type _box_ct
The number of bounding boxes stored in the search structure.
int db() const
The intrinsic dimension of the domain; the dimension of the local coordinates.
total_poset_member & base_space()
The base space component of this (mutable version).
SHEAF_DLL_SPEC std::ostream & operator<<(std::ostream &xos, const array_cylindrical_point_locator &xpl)
Insert array_cylindrical_point_locator xpl into ostream xos.
virtual section_space_schema_member & schema()
The restricted schema for this (mutable version).
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
const char * local_cell_type_name() const
The type name of the prototype for the local cell.
int evaluation_ct() const
The number of members in the intersection of the evaluation subposet and the down set of the base spa...
const block< sec_vd_value_type > & ub() const
The upper bound of the domain defined by coordinates().
int db() const
The dimension of the base space component.
int df() const
The dimension of the fiber space component.
bool is_empty() const
True if this contains no bounding boxes.
SHEAF_DLL_SPEC void exp(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute exp of x0 (exp(x0)) (pre-allocated version).
Definition: sec_at0.cc:1310
Namespace for geometry component of sheaf system.
Definition: field_vd.h:54
vd_value_type sec_vd_value_type
The type of component in the value of a section at a point.
Definition: fiber_bundle.h:73
Wrapper class for forward_list or slist depending on compiler. The class replicates the minimum subse...
An abstract point location query in domains with global coordinate dimension dc and local coordinate ...
Definition: point_locator.h:52
base_space_poset & base_space()
The base space for section spaces on this schema.
pod_index_type base_space_id() const
The member id of the base space component of this.