SheafSystem  0.0.0.0
db0_point_locator.impl.h
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 #ifndef DB0_POINT_LOCATOR_IMPL_H
22 #define DB0_POINT_LOCATOR_IMPL_H
23 
24 #ifndef SHEAF_DLL_SPEC_H
25 #include "SheafSystem/sheaf_dll_spec.h"
26 #endif
27 
28 #ifndef DB0_POINT_LOCATOR_H
29 #include "SheafSystem/db0_point_locator.h"
30 #endif
31 
32 #ifndef ASSERT_CONTRACT_H
33 #include "SheafSystem/assert_contract.h"
34 #endif
35 
36 #ifndef BLOCK_H
37 #include "SheafSystem/block.h"
38 #endif
39 
40 #ifndef CHART_POINT_3D_H
41 #include "SheafSystem/chart_point_3d.h"
42 #endif
43 
44 #ifndef ERROR_MESSAGE_H
45 #include "SheafSystem/error_message.h"
46 #endif
47 
48 #ifndef PREORDER_ITERATOR_H
49 #include "SheafSystem/preorder_iterator.h"
50 #endif
51 
52 #ifndef SEC_AT1_SPACE_H
53 #include "SheafSystem/sec_at1_space.h"
54 #endif
55 
56 #ifndef SEC_ED_H
57 #include "SheafSystem/sec_ed.h"
58 #endif
59 
60 #ifndef SEC_REP_DESCRIPTOR_H
61 #include "SheafSystem/sec_rep_descriptor.h"
62 #endif
63 
64 #ifndef SECTION_SPACE_SCHEMA_POSET_H
65 #include "SheafSystem/section_space_schema_poset.h"
66 #endif
67 
68 #ifndef STD_CMATH_H
69 #include "SheafSystem/std_cmath.h"
70 #endif
71 
72 #ifndef STD_IOMANIP_H
73 #include "SheafSystem/std_iomanip.h"
74 #endif
75 
76 #ifndef STD_LIMITS_H
77 #include "SheafSystem/std_limits.h"
78 #endif
79 
80 
81 //#undef DIAGNOSTIC_OUTPUT
82 //#define DIAGNOSTIC_OUTPUT
83 
84 namespace geometry
85 {
86 
87 // ===========================================================
88 // DB0_POINT_LOCATOR FACET
89 // ===========================================================
90 
91 // PUBLIC MEMBER FUNCTIONS
92 
93 template<int DC>
95 db0_point_locator(sec_ed& xcoords, const block<size_type>& xbin_ub)
96  : point_locator(xcoords)
97 {
98  // Preconditions:
99 
100  require(xcoords.state_is_read_accessible());
101  require(xcoords.schema().df() == DC);
102  require(xcoords.schema().rep().name() == "vertex_vertex_constant");
103  require(xbin_ub.ct() >= DC);
104  require_for_all(i, 0, xbin_ub.ct(), xbin_ub[i] > 0);
105 
106  // Body:
107 
108  _bin_ub.reserve(DC);
109  _bin_ub.set_ct(DC);
110 
111  _bin_size.reserve(DC);
112  _bin_size.set_ct(DC);
113 
116 
117  for(int i=0; i<DC; i++)
118  {
119  _bin_ub[i] = xbin_ub[i];
120  }
121 
122  update();
123 
124  // Postconditions:
125 
126 
127  // Exit:
128 
129  return;
130 }
131 
132 template<int DC>
134 db0_point_locator(sec_ed& xcoords, int xavg_occupancy)
135  : point_locator(xcoords)
136 {
137  // Preconditions:
138 
139  require(precondition_of(point_locator(xcoords)));
140  require(xcoords.state_is_read_accessible());
141  require(xcoords.schema().rep().name() == "vertex_vertex_constant");
142  require(xavg_occupancy > 0);
143 
144  // Body:
145 
146  _bin_ub.reserve(DC);
147  _bin_ub.set_ct(DC);
148 
149  _bin_size.reserve(DC);
150  _bin_size.set_ct(DC);
151 
154 
155  // Set _bin_ub to the dc()-th root of the number of disc members.
156 
157  double ldisc_ct = static_cast<double>(xcoords.schema().discretization_ct());
158  size_type lbin_ub = static_cast<size_type>(exp(log(ldisc_ct/xavg_occupancy)
159  / static_cast<double>(DC)));
160 
161  // Make sure ub is at least 1.
162 
163  lbin_ub = (lbin_ub > 1) ? lbin_ub : 1;
164 
165 
166  for(int i=0; i<DC; i++)
167  {
168  _bin_ub[i] = lbin_ub;
169  }
170 
171  update();
172 
173  // Postconditions:
174 
175 
176  // Exit:
177 
178  return;
179 }
180 
181 template<int DC>
184 {
185  // Preconditions:
186 
187  // Body:
188 
189  // Nothing to do.
190 
191  // Postconditions:
192 
193  // Exit:
194 
195  return;
196 }
197 
198 template<int DC>
199 const block<size_type>&
201 bin_ub() const
202 {
203  // Preconditions:
204 
205 
206  // Body:
207 
208  const block<size_type>& result = _bin_ub;
209 
210  // Postconditions:
211 
212  ensure_for_all(i, 0, dc(), result[i] > 0);
213 
214  // Exit:
215 
216  return result;
217 }
218 
219 template<int DC>
222 bin_size() const
223 {
224 
225  // Preconditions:
226 
227 
228  // Body:
229 
230  const block<sec_vd_value_type>& result = _bin_size;
231 
232  // Postconditions:
233 
234 
235  // Exit:
236 
237  return result;
238 }
239 
240 
241 template<int DC>
242 bool
244 is_empty() const
245 {
246  bool result;
247 
248  // Preconditions:
249 
250 
251  // Body:
252 
253  result = true;
254  for(int i=0; result && (i<_bins.ct()); ++i)
255  {
256  result = _bins[i].empty();
257  }
258 
259 
260  // Postconditions:
261 
262  // Exit:
263 
264  return result;
265 }
266 
267 
268 template<int DC>
269 void
272  bin_coord_type xresult[]) const
273 {
274  // Preconditions:
275 
276  require(xpt != 0);
277 
278  // Body:
279 
280  for(int i=0; i<DC; i++)
281  {
282 
283 #ifdef DIAGNOSTIC_OUTPUT
284  cout << "xpt: " << xpt[i] << endl;
285 #endif
286 
287  sec_vd_value_type ltmp = (xpt[i] - _lb[i])*_one_over_min_bin_size[i];
288 
289  xresult[i] = static_cast<bin_coord_type>(floor(ltmp));
290 
291 #ifdef DIAGNOSTIC_OUTPUT
292 
293  int lprecision = cout.precision();
294  cout << "tmp: " << scientific << setprecision(15) << ltmp;
295  cout.unsetf(ios_base::floatfield);
296  cout << setprecision(lprecision);
297  cout << " result: " << xresult[i] << endl;
298 #endif
299 
300  }
301 
302  // Postconditions:
303 
304  // Exit:
305 
306  return;
307 }
308 
309 
310 
311 template<int DC>
312 void
315 {
316  // Preconditions:
317 
318  // Body:
319 
320  for(int i=0; i<_bins.ct(); ++i)
321  {
322  _bins[i].clear();
323  }
324 
325  // Postconditions:
326 
327  ensure(is_empty());
328 
329  // Exit:
330 
331  return;
332 }
333 
334 
335 // PROTECTED MEMBER FUNCTIONS
336 
337 template<int DC>
338 void
341 {
342  // Preconditions:
343 
344  require(is_empty());
345 
346  // Body:
347 
348  // Compute the bin size.
349 
350 #ifdef DIAGNOSTIC_OUTPUT
351 
352  cout << "bin_ub: ";
353  for(int i=0; i<DC; i++)
354  {
355  cout << setw(6) << _bin_ub[i];
356  }
357  cout << endl;
358 #endif
359 
360  _bin_diag = 0.0;
361  for(int i=0; i<DC; i++)
362  {
363  _bin_size[i] = (this->_ub[i] - this->_lb[i])/_bin_ub[i];
364  _bin_diag += _bin_size[i]*_bin_size[i];
365  }
367 
368 #ifdef DIAGNOSTIC_OUTPUT
369 
370  cout << "bin_size: ";
371  for(int i=0; i<DC; i++)
372  {
373  cout << setw(12) << _bin_size[i];
374  }
375  cout << endl;
376 #endif
377 
378  // Compute the reciprocal of the smallest bin size.
379  // Used for efficiency in relative_position_pa().
380 
381  for(int i=0; i<DC; i++)
382  {
383  _one_over_min_bin_size[i] = 1.0/_bin_size[i];
384  }
385 
386 
387 #ifdef DIAGNOSTIC_OUTPUT
388  cout << "one_over_bin_size: ";
389  for(int i=0; i<DC; i++)
390  {
391  cout << setw(12) << _one_over_min_bin_size[i];
392  }
393  cout << endl;
394 #endif
395 
396  // Reset the size of the bin array.
397 
398  int lbin_ct = 1;
399  for(int i=0; i<DC; i++)
400  {
401  lbin_ct *= _bin_ub[i];
402  }
403 
404  _bins.reserve(lbin_ct);
405  _bins.set_ct(lbin_ct);
406 
409 
411 
412  // Postconditions:
413 
414  // Exit:
415 
416  return;
417 }
418 
419 template<int DC>
420 void
422 find_closest_bin(const bin_coord_type xpt_pos[], bin_coord_type xbin_pos[])
423 {
424  // Preconditions:
425 
426 
427  // Body:
428 
429  // Clip the point coords againt the bin bounds.
430 
431  for(int i=0; i<DC; ++i)
432  {
433  bin_coord_type lpt_coord = xpt_pos[i];
434 
435  if(lpt_coord < 0)
436  {
437  xbin_pos[i] = 0;
438  }
439  else if(lpt_coord >= _bin_ub[i])
440  {
441  xbin_pos[i] = _bin_ub[i] - 1;
442  }
443  else
444  {
445  xbin_pos[i] = lpt_coord;
446  }
447  }
448 
449 #ifdef DIAGNOSTIC_OUTPUT
450  print_coords(cout, xbin_pos, "closest_bin: ");
451 #endif
452 
453  // Postconditions:
454 
455  ensure_for_all(i, 0, DC, (0 <= xbin_pos[i]) && (xbin_pos[i] < _bin_ub[i]));
456 
457  // Exit:
458 
459  return;
460 }
461 
462 
463 template<int DC>
464 void
467 {
468 #ifdef DIAGNOSTIC_OUTPUT
469  cout << endl << endl;
470  post_information_message("entering initialize_search_region");
471 #endif
472 
473  // Preconditions:
474 
475 
476  // Body:
477 
478  // Convert the query point to bin coordinates.
479 
480  bin_coord_type lpt_pos[DC];
481  relative_position(xvalue, lpt_pos);
482 
483 #ifdef DIAGNOSTIC_OUTPUT
484 
485  print_value(cout, xvalue, "query point: ");
486  print_coords(cout, lpt_pos, "rel coords: ");
487 #endif
488 
489  // Find the closest bin.
490 
491  bin_coord_type lbin_pos[DC];
492  find_closest_bin(lpt_pos, lbin_pos);
493 
494  // Set the initial search radius to include the closest bin.
495 
496  _search_radius = max_bin_distance(xvalue, lbin_pos);
497 
498  // Compute the search region as the box proscribing the search sphere.
499 
500  compute_search_region(xvalue);
501 
502  // Put all the bins on the search queue.
503 
505 
506  // Postconditions:
507 
508 
509  // Exit:
510 
511 #ifdef DIAGNOSTIC_OUTPUT
512 
513  post_information_message("leaving initialize_search_region");
514  cout << endl << endl;
515 #endif
516 
517  return;
518 }
519 
520 
521 template<int DC>
522 void
525 {
526 #ifdef DIAGNOSTIC_OUTPUT
527  post_information_message("Entering expand_search_region.");
528 #endif
529 
530  // Preconditions:
531 
532  // Body:
533 
534  // Save the old search region
535 
536  bin_coord_type old_lb[DC];
537  bin_coord_type old_ub[DC];
538 
539  for(int c=0; c<DC; ++c)
540  {
541  old_lb[c] = _search_region_lb[c];
542  old_ub[c] = _search_region_ub[c];
543  }
544 
545  // Expand the search sphere and update the search region.
546 
548 
549  compute_search_region(xvalue);
550 
551  // Put the new bins in the search region on the search queue.
552 
553  update_search_q(old_lb, old_ub);
554 
555 
556  // Postconditions:
557 
558  ensure_for_all(i, 0, DC, (0 <= _search_region_lb[i]) &&
559  (_search_region_lb[i] <= _bin_ub[i]));
560 
561  ensure_for_all(i, 0, DC, (0 <= _search_region_ub[i]) &&
562  (_search_region_ub[i] <= _bin_ub[i]));
563 
564  ensure_for_all(i, 0, DC, _search_region_lb[i] <= _search_region_ub[i]);
565 
566 
567  // Exit:
568 
569 #ifdef DIAGNOSTIC_OUTPUT
570 
571  post_information_message("Leavinging expand_search_region.");
572 #endif
573 
574  return;
575 }
576 
577 
578 template<int DC>
579 void
582 {
583  // Preconditions:
584 
585 
586  // Body:
587 
588  // Create a search box enclosing search sphere.
589 
590  sec_vd_value_type lvalue_lb[DC];
591  sec_vd_value_type lvalue_ub[DC];
592  for(int i=0; i<DC; ++i)
593  {
594  lvalue_lb[i] = xvalue[i] - _search_radius;
595  lvalue_ub[i] = xvalue[i] + _search_radius;
596  }
597 
600 
601 
602 #ifdef DIAGNOSTIC_OUTPUT
603 
604  print_value(cout, xvalue, "query point: ");
605  cout << "search_radius: " << _search_radius << endl;
606  print_coords(cout, _search_region_lb, "search region lb: ");
607  print_coords(cout, _search_region_ub, "search region ub: ");
608 #endif
609 
610  // _search_region_ub is now the bin coords of the (virtual) bin
611  // that actually contains lvalue_ub.
612  // We want _ub to be an upper bound, not a max; add 1.
613 
614  for(int i=0; i<DC; ++i)
615  {
616  _search_region_ub[i] += 1;
617  }
618 
619 #ifdef DIAGNOSTIC_OUTPUT
620  print_coords(cout, _search_region_lb, "search region lb: ");
621  print_coords(cout, _search_region_ub, "search region ub: ");
622 #endif
623 
624  // The search region is the intersection of
625  // the search box with the source domain.
626 
627  for(int i=0; i<DC; ++i)
628  {
629  // The lb of the intersection is the max of the lbs
630 
632 
633  // The ub of the intersection is the min of the ubs
634 
635  _search_region_ub[i] =
637  }
638 
639 #ifdef DIAGNOSTIC_OUTPUT
640  print_coords(cout, _search_region_lb, "search region lb: ");
641  print_coords(cout, _search_region_ub, "search region ub: ");
642 #endif
643 
644  // Postconditions:
645 
646  ensure_for_all(i, 0, DC, (0 <= _search_region_lb[i]) &&
647  (_search_region_lb[i] <= _bin_ub[i]));
648 
649  ensure_for_all(i, 0, DC, (0 <= _search_region_ub[i]) &&
650  (_search_region_ub[i] <= _bin_ub[i]));
651 
652  ensure_for_all(i, 0, DC, _search_region_lb[i] <= _search_region_ub[i]);
653 
654 
655  // Exit:
656 
657  return;
658 }
659 
660 
661 template<int DC>
664 vertex_distance_sq(const sec_vd_value_type xglobal_coords[],
665  const vertex_type& xvertex_entry)
666 {
667  sec_vd_value_type result;
668 
669  // Preconditions:
670 
671 
672  // Body:
673 
674  // Compute the squared distance from the query point to the vertex.
675 
676  result = 0.0;
677  for(int i=0; i<DC; ++i)
678  {
679  sec_vd_dof_type ldif = xglobal_coords[i] - xvertex_entry.coords[i];
680  result += ldif*ldif;
681  }
682 
683 #ifdef DIAGNOSTIC_OUTPUT
684  cout << "vertex= " << setw(4) << xvertex_entry.disc_id
685  << " branch= " << setw(4) << xvertex_entry.branch_id
686  << " distance squared= " << result << endl;
687 #endif
688 
689  // Postconditions:
690 
691  ensure(result >= 0.0);
692 
693  // Exit:
694 
695  return result;
696 }
697 
698 template<int DC>
699 void
702  sec_vd_value_type& xclosest_dist_sq,
703  chart_point& xresult)
704 {
705  // Preconditions:
706 
707 
708  // Body:
709 
710  // Iterate over the bins in the search queue.
711 
712  while(!_search_q.empty())
713  {
714  int i = _search_q.front();
715  _search_q.pop();
716 
717 #ifdef DIAGNOSTIC_OUTPUT
718 
719  cout << "searching bin= " << setw(4) << i << endl;
720 #endif
721 
722  find_closest_vertex_in_bin(i, xvalue, xresult, xclosest_dist_sq);
723  }
724 
725  // Postconditions:
726 
727  // Exit:
728 
729  return ;
730 }
731 
732 
733 template<int DC>
734 void
737  const sec_vd_value_type* xvalue,
738  chart_point& xresult,
739  sec_vd_value_type& xclosest_dist_sq)
740 {
741  // Preconditions:
742 
743 
744  // Body:
745 
746  // Iterate over the vertices in this bin.
747 
748  const vertex_list_type& lvertex_list = _bins[xbin_id];
749  typename vertex_list_type::const_iterator iter;
750 
751  for(iter = lvertex_list.begin(); iter != lvertex_list.end(); ++iter)
752  {
753  // Compute the distance from the query point to the vertex.
754 
755  sec_vd_value_type lvertex_dist_sq = vertex_distance_sq(xvalue, *iter);
756 
757  if(lvertex_dist_sq < xclosest_dist_sq)
758  {
759  // This vertex is closer than previous one;
760  // it becomes the closest vertex.
761 
762  xclosest_dist_sq = lvertex_dist_sq;
763  xresult.put_chart_id(iter->disc_id);
764 
765 #ifdef DIAGNOSTIC_OUTPUT
766 
767  cout << "vertex= " << iter->disc_id << " is closest" << endl;
768 #endif
769 
770  }
771 
772  } // end for vertex list
773 
774  // Postconditions:
775 
776  // Exit:
777 
778  return;
779 }
780 
781 template<int DC>
782 void
784 print_bins(std::ostream& xos, const std::string& xmsg) const
785 {
786  // Preconditions:
787 
788 
789  // Body:
790 
791  using namespace std;
792 
793  xos << endl << xmsg << endl;
794 
795  xos << "_bins.ub()= " << _bins.ub()
796  << " _bins.ct()= " << _bins.ct()
797  << endl;
798 
799  for(int i=0; i<_bins.ct(); ++i)
800  {
801  cout << "bin: " << setw(4) << i << " vertices: " << endl;
802 
803  const vertex_list_type& lverts = _bins[i];
804 
805  for(typename vertex_list_type::const_iterator lv_itr = lverts.begin();
806  lv_itr != lverts.end();
807  ++lv_itr)
808  {
809  cout << setw(6) << lv_itr->disc_id
810  << setw(6) << lv_itr->branch_id;
811 
812  for(int lc=0; lc<DC; ++lc)
813  {
814  cout << setw(16) << lv_itr->coords[lc];
815  }
816  cout << endl;
817  }
818  cout << endl;
819  }
820 
821  // Postconditions:
822 
823 
824  // Exit:
825 
826  return;
827 }
828 
829 template<int DC>
830 void
832 print_queue(std::ostream& xos, const std::string& xmsg) const
833 {
834  // Preconditions:
835 
836 
837  // Body:
838 
839  using namespace std;
840 
841  xos << endl << xmsg << endl;
842 
843  // Type queue has no iterator, must access via front and pop,
844  // so we have to copy the queue to print it out.
845 
846  queue<int> ltmp(_search_q);
847 
848  while(!ltmp.empty())
849  {
850  xos << setw(6) << ltmp.front();
851  ltmp.pop();
852  }
853  xos << endl;
854 
855  // Postconditions:
856 
857 
858  // Exit:
859 
860  return;
861 }
862 
863 template<int DC>
864 void
866 print_value(std::ostream& xos,
867  const sec_vd_value_type xvalue[],
868  const std::string& xmsg) const
869 {
870  // Preconditions:
871 
872 
873  // Body:
874 
875  using namespace std;
876 
877  xos << xmsg;
878 
879  for(int i=0; i<DC; ++i)
880  {
881  cout << setw(12) << xvalue[i];
882  }
883  xos << endl;
884 
885  // Postconditions:
886 
887 
888  // Exit:
889 
890  return;
891 }
892 
893 template<int DC>
894 void
896 print_coords(std::ostream& xos,
897  const bin_coord_type xcoords[],
898  const std::string& xmsg) const
899 {
900  // Preconditions:
901 
902 
903  // Body:
904 
905  using namespace std;
906 
907  xos << xmsg;
908 
909  for(int i=0; i<DC; ++i)
910  {
911  cout << setw(6) << xcoords[i];
912  }
913  xos << endl;
914 
915  // Postconditions:
916 
917 
918  // Exit:
919 
920  return;
921 }
922 
923 
924 // ===========================================================
925 // POINT_LOCATOR FACET
926 // ===========================================================
927 
928 // PUBLIC MEMBER FUNCTIONS
929 
930 template<int DC>
931 bool
933 invariant() const
934 {
935  bool result = true;
936 
937  invariance(coordinates().schema().df() == dc());
938  invariance(coordinates().schema().rep().name() == "vertex_vertex_constant");
939 
940 
941  return result;
942 }
943 
944 template<int DC>
945 void
948 {
949  // Preconditions:
950 
951  require(coordinates().state_is_read_accessible());
952 
953  // Body:
954 
955  // Update the domain.
956 
957  this->update_domain();
958 
959  // Update the bin parameters.
960 
961  update_bins();
962 
963 #ifdef DIAGNOSTIC_OUTPUT
964 
965  print_bins(cout, "Before initializing bins:");
966 #endif
967 
968  // Iterate over the branches.
970 
971  vertex_type lvertex_entry;
972 
973  sec_vd lbranch;
974  preorder_iterator lbranch_itr(coordinates(), "jims", DOWN, NOT_STRICT);
975  while(!lbranch_itr.is_done())
976  {
977  // Get a handle to this branch.
978 
979  scoped_index lbranch_id = lbranch_itr.index();
980  lbranch.attach_to_state(coordinates().host(), lbranch_id);
981 
982  // Sort the vertices into the bins.
983 
984  size_type ldisc_ct = lbranch.schema().discretization_ct();
985 
986  scoped_index lindex(lbranch.schema().discretization_id_space());
987  lvertex_entry.disc_id =
988  coordinates().schema().host()->base_space().member_id(false);
989 
990  for(pod_index_type ldisc_id=0; ldisc_id<ldisc_ct; ++ldisc_id)
991  {
992  lindex = ldisc_id;
993 
994  lindex >> lvertex_entry.disc_id;
995 
996  lvertex_entry.branch_id = lbranch_id;
997 
998  // Get the value at vertex
999 
1000  lbranch.get_fiber(ldisc_id, lvertex_entry.coords,
1001  DC*sizeof(sec_vd_dof_type));
1002 
1003  // Get its bin coordinates.
1004 
1005  bin_coord_type lrel_pos[DC];
1006  relative_position(lvertex_entry.coords, lrel_pos);
1007 
1008  // Insert the vertex in the bin.
1009 
1010  int lbin_id = bin_id(lrel_pos);
1011 
1012  _bins[lbin_id].push_front(lvertex_entry);
1013  }
1014 
1015  // Move on to the next branch.
1016 
1017  lbranch_itr.truncate();
1018  }
1019 
1020  // Clean up.
1021 
1022  lbranch.detach_from_state();
1023 
1024 #ifdef DIAGNOSTIC_OUTPUT
1025 
1026  print_bins(cout, "After initializing bins:");
1027 #endif
1028 
1029  // Postconditions:
1030 
1031 
1032  // Exit:
1033 
1034  return;
1035 }
1036 
1037 template<int DC>
1038 void
1041  size_type xvalue_ub,
1042  chart_point& xresult)
1043 {
1044  require(xvalue != 0);
1045  require(xvalue_ub >= dc());
1046  require(xresult.db() >= db());
1047  require(coordinates().schema().discretization_ct() > 0);
1048 
1049  // Body:
1050 
1051  // Compute the initial search region and
1052  // put its bins on the search queue.
1053 
1054  initialize_search_region(xvalue);
1055 
1056  // Initialize the chart id to invalid.
1057  // If the inversion succeeds, it will be set to valid.
1058 
1059  xresult.invalidate();
1060 
1061  // Initialize distance (squared) to "infinity".
1062 
1064 
1065  // Keep expanding the search region until we find the closest point
1066  // or we've searched the entire structure. We should always find a
1067  // point unless the search structure is empty.
1068 
1069  do
1070  {
1071  // Find the closest vertex, if any, within the search region.
1072 
1073  find_closest_vertex(xvalue, lclosest_dist_sq, xresult);
1074 
1075  if(sqrt(lclosest_dist_sq) > _search_radius)
1076  {
1077  // Either we haven't found a vertex or we've found one outside
1078  // the search radius, so there may be a closer one in some
1079  // bin we haven't searched yet.
1080 
1081  expand_search_region(xvalue);
1082  }
1083  }
1084  while(!_search_q.empty());
1085 
1086  // Since precondition ensures there is at least one vertex,
1087  // we must have found it by now.
1088 
1089  assertion(xresult.is_valid());
1090 
1091 #ifdef DIAGNOSTIC_OUTPUT
1092 
1093  cout << " chart pt: " << xresult << endl;
1094 #endif
1095 
1096  // Postconditions:
1097 
1098  ensure(xresult.is_valid());
1099 
1100  // Exit:
1101 
1102  return;
1103 }
1104 
1105 template<int DC>
1106 void
1109  size_type xvalue_ub,
1110  block<chart_point_3d>& xresult)
1111 {
1112  require(xvalue != 0);
1113  require(xvalue_ub >= dc());
1114  require(db() <= 3);
1115 
1116  // Body:
1117 
1118  // There can be only one.
1119 
1120  xresult.set_ct(1);
1121  point_at_value(xvalue, xvalue_ub, xresult[0]);
1122 
1123  // Postconditions:
1124 
1125  ensure_for_all(i, 0, xresult.ct(), xresult[i].is_valid());
1126 
1127 
1128  // Exit:
1129 
1130  return;
1131 }
1132 
1133 template<int DC>
1134 void
1137  size_type xvalue_ub,
1138  block<branch_point_pair>& xresult)
1139 {
1140  require(xvalue != 0);
1141  require(xvalue_ub >= dc());
1142  require(db() <= 3);
1143 
1144  // Body:
1145 
1146  define_old_variable(int old_xresult_ct = xresult.ct());
1147 
1148  // There can be only one.
1149 
1150  xresult.set_ct(1);
1151  xresult[0].first = coordinates().index();
1152  point_at_value(xvalue, xvalue_ub, xresult[0].second);
1153 
1154  // Postconditions:
1155 
1156  ensure(xresult.ct() == old_xresult_ct + 1);
1157  ensure_for_all(i, old_xresult_ct, xresult.ct(),
1158  coordinates().host()->contains_member(xresult[i].first, false));
1159  ensure_for_all(i, old_xresult_ct, xresult.ct(), xresult[i].second.is_valid());
1160 
1161 
1162  // Exit:
1163 
1164  return;
1165 }
1166 
1167 
1168 // ===========================================================
1169 // NON-MEMBER FUNCTIONS
1170 // ===========================================================
1171 
1172 } // namespace geometry
1173 
1174 #endif // DB0_POINT_LOCATOR_IMPL_H
sec_vd_value_type _bin_diag
The diagonal length of the smallest bins.
SHEAF_DLL_SPEC void sqrt(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute sqrt of x0 (sqrt(x0)) (pre-allocated version).
Definition: sec_at0.cc:1556
void truncate()
Makes this the next member of the subset which is not less than old this, i.e. the depth-first descen...
void print_value(std::ostream &xos, const sec_vd_value_type xvalue[], const std::string &xmsg) const
Prints xvlaue on xos; intended for debugging.
virtual void update_bins()
Updates the bin parameters.
section_space_schema_poset * host() const
The poset which this is a handle to a component of.
virtual bool invariant() const
Class invariant.
size_type ct() const
The number of items currently in use.
void print_queue(std::ostream &xos, const std::string &xmsg) const
Prints the contents of the search queue on xos; intended for debugging.
sec_ed & coordinates() const
The coordinate section this inverts.
The information stored in the search structure for each vertex.
bool state_is_read_accessible() const
True if this is attached and if the state is accessible for read or access control is disabled...
void get_fiber(pod_index_type xdisc_id, vd_lite &xfiber) const
Sets xfiber to the fiber referred to by discretization id xdisc_id.
Definition: sec_vd.cc:1087
virtual void clear()
Clear the search structure of all bounding boxes.
void update_search_q(bin_coord_type xold_lb[], bin_coord_type xold_ub[])
Puts previous unsearched bins from the search region onto the search queue.
virtual int db() const =0
The dimension of this chart.
Definition: chart_point.cc:141
void initialize_search_q()
Puts all the bins from the search region onto the search queue.
void find_closest_bin(const bin_coord_type xpt_pos[], bin_coord_type xbin_pos[])
Set xbin_pos the bin closest to xpt_pos.
void find_closest_vertex(const sec_vd_value_type *xvalue, sec_vd_value_type &xclosest_dist_sq, chart_point &xresult)
Sets xresult.chart() to the vertex in _bins that is both closest to the point with value xvalue and c...
block< sec_vd_value_type > _bin_size
The dimensions of the smallest bins.
STL namespace.
void reserve(index_type xub)
Makes ub() at least xub; if new storage is allocated, it is uninitialized.
point_locator()
Default constructor.
bin_coord_type _search_region_ub[DC]
The upper bound of the search region.
void put_chart_id(pod_index_type xchart)
Sets chart_id() to xchart_id.
Definition: chart_point.cc:103
A point in chart space.
Definition: chart_point.h:52
sec_vd_value_type vertex_distance_sq(const sec_vd_value_type xglobal_coords[], const vertex_type &xvertex_entry)
The squared distance from the point with coordinates xglobal_coords to the vertex associated with xve...
void update_domain()
Initializes the domain bounds and dimension.
host_type * host() const
The poset this is a member of.
Definition: sec_at1.cc:525
const scoped_index & index() const
The index of the component state this handle is attached to.
std::string name() const
A name for this.
virtual void branch_points_at_value(const sec_vd_value_type *xvalue, size_type xvalue_ub, block< branch_point_pair > &xresult)
Finds one chart point in each branch at which coordinates() has value xvalue and appends them to xres...
virtual void all_points_at_value(const sec_vd_value_type *xvalue, size_type xvalue_ub, block< chart_point_3d > &xresult)
Finds all chart points at which coordinates() has value xvalue; for sections over db = 0 base spaces...
iterator begin()
Returns an iterator to the first element of the container.
bool is_empty() const
True if the search structure contains no vertices.
bool is_valid() const
True if this ia a valid point in a chart.
Definition: chart_point.cc:303
sec_vd_value_type _search_radius
The radius of a sphere centered on the query point that will be searched for vertices.
A section of a fiber bundle with a d-dimensional Euclidean vector space fiber.
Definition: sec_ed.h:47
std::queue< int > _search_q
The bins scheduled to be searched for the current query point.
void invalidate()
Makes this invalid.
Definition: chart_point.cc:322
void relative_position(const sec_vd_value_type xpt[], bin_coord_type xresult[]) const
The position of xpt relative to the lower bound in integer coordinates.
const bool NOT_STRICT
Iteration strictness control.
Definition: sheaf.h:102
const bool DOWN
Iteration directions.
Definition: sheaf.h:77
block< sec_vd_value_type > _lb
The lower bound of the domain.
block< sec_vd_value_type > _one_over_min_bin_size
Reciprocal of the dimensions of the smallest bins.
void set_ct(size_type xct)
Sets ct() == xct.
An index within the external ("client") scope of a given id space.
Definition: scoped_index.h:116
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
virtual bool contains_member(pod_index_type xmbr_hub_id, bool xauto_access=true) const
True if some version of this poset contains poset member with hub id xmbr_hub_id. ...
db0_point_locator()
Default constructor; disabled.
int discretization_ct() const
The number of members in the intersection of the discretization subposet and the down set of the base...
bin_coord_type _search_region_lb[DC]
The lower bound of the search region.
void compute_search_region(const sec_vd_value_type xvalue[])
Compute the intersection of the domain with the search box enclosing the search sphere.
int bin_coord_type
The type of the bin coordinates.
SHEAF_DLL_SPEC void max(const vd &x0, vd_value_type &xresult, bool xauto_access)
Maximum component of x0, pre-allocated version.
Definition: vd.cc:2097
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
A section of a fiber bundle with a d-dimensional vector space fiber.
Definition: sec_vd.h:54
const block< sec_vd_value_type > & bin_size() const
The dimensions of the smallest bins.
bool is_done() const
True if iteration finished.
void detach_from_state()
Detaches field from state it is currently attached to.
Definition: sec_tuple.cc:603
virtual ~db0_point_locator()
Destructor.
void print_bins(std::ostream &xos, const std::string &xmsg) const
Prints the contents of the bins on xos; intended for debugging.
int db() const
The intrinsic dimension of the domain; the dimension of the local coordinates.
virtual void point_at_value(const sec_vd_value_type *xvalue, size_type xvalue_ub, chart_point &xresult)
Finds a chart point at which coordinates() has value xvalue; for sections over db = 0 base spaces...
SHEAF_DLL_SPEC void floor(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute floor of x0 (floor(x0)) (pre-allocated version).
Definition: sec_at0.cc:1351
void find_closest_vertex_in_bin(int xbin_id, const sec_vd_value_type *xvalue, chart_point &xresult, sec_vd_value_type &xclosest_dist)
Sets xresult.chart() to the vertex, if any in bin xbin_id that is both.
const index_space_handle & discretization_id_space() const
The id space for the discretization members in the down set of the base space of this (const version)...
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
int dc() const
The spatial dimension of the domain; the dimension of the global coordinates.
block< sec_vd_value_type > _ub
The upper bound of the domain.
block< size_type > _bin_ub
The upper bound for the bin index.
int df() const
The dimension of the fiber space component.
void initialize_search_region(const sec_vd_value_type xvalue[])
Initialize the search radius and the search region.
void attach_to_state(const namespace_poset *xns, const poset_path &xpath, bool xauto_access=true)
Attach to the state specified by path xpath in the namespace xns.
const block< size_type > & bin_ub() const
The upper bound for the bin index.
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
virtual void update()
Updates the search structure to the current values of coordinates().
double sec_vd_dof_type
The type of degree of freedom in the section space.
Definition: fiber_bundle.h:78
void expand_search_region(const sec_vd_value_type xvalue[])
Increase the search radius and expand the search region to match.
sec_rep_descriptor & rep()
The representation for section spaces on this schema (mutable version).
block< vertex_list_type > _bins
The search structure; a d-dimensional array of bins.
sec_vd_value_type max_bin_distance(const sec_vd_value_type xpt[], const bin_coord_type xbin_pos[]) const
The maximum distance from the query point xpt to any point in the bin with coordinates xbin_pos...
Namespace for geometry component of sheaf system.
Definition: field_vd.h:54
void print_coords(std::ostream &xos, const bin_coord_type xcoords[], const std::string &xmsg) const
Prints xcoords on xos; intended for debugging.
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
int bin_id(const bin_coord_type xcoord[]) const
The id of the bin with bin coords xcoord.
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.
virtual const scoped_index & member_id(bool xauto_access) const
An id in the member hub id space; intended for copying to initialize ids to the member id space...
const scoped_index & index() const
The index of the current member of the iteration.