SheafSystem  0.0.0.0
d_bin_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 D_BIN_POINT_LOCATOR_IMPL_H
22 #define D_BIN_POINT_LOCATOR_IMPL_H
23 
24 #ifndef SHEAF_DLL_SPEC_H
25 #include "SheafSystem/sheaf_dll_spec.h"
26 #endif
27 
28 #ifndef D_BIN_POINT_LOCATOR_H
29 #include "SheafSystem/d_bin_point_locator.h"
30 #endif
31 
32 #ifndef ASSERT_CONTRACT_H
33 #include "SheafSystem/assert_contract.h"
34 #endif
35 
36 #ifndef CHART_POINT_3D_H
37 #include "SheafSystem/chart_point_3d.h"
38 #endif
39 
40 #ifndef D_BIN_COORDINATES_H
41 #include "SheafSystem/d_bin_coordinates.h"
42 #endif
43 
44 #ifndef EVAL_ITERATOR_H
45 #include "SheafSystem/eval_iterator.h"
46 #endif
47 
48 #ifndef ERROR_MESSAGE_H
49 #include "SheafSystem/error_message.h"
50 #endif
51 
52 #ifndef PREORDER_ITERATOR_H
53 #include "SheafSystem/preorder_iterator.h"
54 #endif
55 
56 #ifndef SEC_AT1_SPACE_H
57 #include "SheafSystem/sec_at1_space.h"
58 #endif
59 
60 #ifndef SEC_ED_H
61 #include "SheafSystem/sec_ed.h"
62 #endif
63 
64 
65 //#undef DIAGNOSTIC_OUTPUT
66 //#define DIAGNOSTIC_OUTPUT
67 
68 namespace geometry
69 {
70 
71 // ===========================================================
72 // D_BIN_POINT_LOCATOR FACET
73 // ===========================================================
74 
75 // PUBLIC MEMBER FUNCTIONS
76 
77 template <int DC, int DB>
80  : point_locator(xcoords),
81  _eval_itr(xcoords.schema(), false)
82 {
83  // Preconditions:
84 
85  require(precondition_of(point_locator(xcoords)));
86 
87  // Body:
88 
89  _bin_ub.reserve(DC);
90  _bin_ub.set_ct(DC);
91 
92  _bin_size.reserve(DC);
93  _bin_size.set_ct(DC);
94 
97 
98  _box_ct = 0;
99 
100  // The eval_itr owns the evaluator_family which owns the section_evaluators.
101  // The bounding boxes in _boxes keep pointers to these section evaluators.
102  // So the lifetime of the eval_family must be as long as _boxes.
103 
110 
112 
113  // Postconditions:
114 
115 
116  // Exit:
117 
118  return;
119 }
120 
121 template <int DC, int DB>
124 {
125  // Preconditions:
126 
127  // Body:
128 
129  // Nothing to do.
130 
131  // Postconditions:
132 
133  // Exit:
134 
135  return;
136 }
137 
138 template <int DC, int DB>
139 bool
141 invariant() const
142 {
143  bool result = true;
144 
145  invariance(coordinates().schema().df() == DC);
146 
147 
148  return result;
149 }
150 
151 
152 template <int DC, int DB>
153 const block<size_type>&
155 bin_ub() const
156 {
157  // Preconditions:
158 
159 
160  // Body:
161 
162  const block<size_type>& result = _bin_ub;
163 
164  // Postconditions:
165 
166  ensure_for_all(i, 0, dc(), result[i] > 0);
167 
168  // Exit:
169 
170  return result;
171 }
172 
173 template <int DC, int DB>
176 bin_size() const
177 {
178 
179  // Preconditions:
180 
181 
182  // Body:
183 
184  const block<sec_vd_value_type>& result = _bin_size;
185 
186  // Postconditions:
187 
188 
189  // Exit:
190 
191  return result;
192 }
193 
194 
195 template <int DC, int DB>
196 size_type
198 box_ct() const
199 {
200  size_type result;
201 
202  // Preconditions:
203 
204 
205  // Body:
206 
207  result = _box_ct;
208 
209  // Postconditions:
210 
211 
212  // Exit:
213 
214  return result;
215 }
216 
217 template <int DC, int DB>
218 bool
220 is_empty() const
221 {
222  bool result;
223 
224  // Preconditions:
225 
226 
227  // Body:
228 
229  result = (box_ct() == 0);
230 
231  // Postconditions:
232 
233  ensure(result == (box_ct() == 0));
234 
235  // Exit:
236 
237  return result;
238 }
239 
240 
241 template <int DC, int DB>
245 {
247 
248  // Preconditions:
249 
250  require(xpt != 0);
251  require(xpt_ub >= dc());
252 
253  // Body:
254 
255  result = new d_bin_coordinates<DC, DB>();
256  relative_position_pa(xpt, xpt_ub, *result);
257 
258  // Postconditions:
259 
260  ensure(result != 0);
261  ensure(postcondition_of(relative_position_pa(xpt, xpt_ub, result)));
262 
263  // Exit:
264 
265  return result;
266 }
267 
268 template <int DC, int DB>
269 void
272  size_type xpt_ub,
273  d_bin_coordinates<DC, DB>& xresult) const
274 {
275  // Preconditions:
276 
277  require(xpt != 0);
278  require(xpt_ub >= dc());
279 
280  // Body:
281 
282  sec_vd_value_type lrel_pos[DC];
283 
284 // cerr << " d_bin_point_locator<" << DC << ", " << DB
285 // <<">::relative_position_pa:" << endl;
286 // cerr << " i, xpt[i], _lb[i], _one_over_min_bin_size[i], lrel_pos[i] = "
287 // << endl;
288 
289  for(int i=0; i<DC; i++)
290  {
291  lrel_pos[i] = (xpt[i] - _lb[i])*_one_over_min_bin_size[i];
292 
293 // cerr << " " << i << ", " << xpt[i] << ", " << _lb[i] << ", "
294 // << _one_over_min_bin_size[i] << ", " << lrel_pos[i]
295 // << endl;
296  }
297 // cerr << endl;
298 
299  xresult = lrel_pos;
300 
301  // Postconditions:
302 
303  // Exit:
304 
305  return;
306 }
307 
308 
309 template <int DC, int DB>
310 void
313 {
314  // Preconditions:
315 
316  require(xbox != 0);
317 
318  // Body:
319 
320  define_old_variable(size_type old_box_ct = _box_ct);
321 
322  is_abstract();
323 
324  // Postconditions:
325 
326  ensure(contains_box(xbox));
327  ensure(box_ct() == old_box_ct + 1);
328 
329  // Exit:
330 
331  return;
332 }
333 
334 template <int DC, int DB>
335 void
338 {
339  // Preconditions:
340 
341  require(xbox != 0);
342  require(contains_box(xbox));
343 
344  // Body:
345 
346  define_old_variable(size_type old_box_ct = _box_ct);
347 
348  is_abstract();
349 
350  // Postconditions:
351 
352  ensure(!contains_box(xbox));
353  ensure(box_ct() == old_box_ct - 1);
354 
355  // Exit:
356 
357  return;
358 }
359 
360 template <int DC, int DB>
364 {
365  // Preconditions:
366 
367  require(xpt != 0);
368  require(xpt_ub >= dc());
369  require(domain_contains(xpt, xpt_ub));
370 
371  // Body:
372 
373 
374  is_abstract();
375 
376  static box_list_type result; // just to avoid compiler warnings
377 
378  // Postconditions:
379 
380 
381  // Exit:
382 
383  return result;
384 }
385 
386 template <int DC, int DB>
387 bool
390 {
391  bool result = true;
392 
393  // Preconditions:
394 
395  require(xbox != 0);
396 
397  // Body:
398 
399  is_abstract();
400 
401  // Postconditions:
402 
403 
404  // Exit:
405 
406  return result;
407 }
408 
409 template <int DC, int DB>
410 void
413 {
414  // Preconditions:
415 
416  // Body:
417 
418  is_abstract();
419 
420  // Postconditions:
421 
422  ensure(is_empty());
423 
424  // Exit:
425 
426  return;
427 }
428 
429 template <int DC, int DB>
433 {
434  return this->_gathered_dofs;
435 }
436 
437 
438 // PROTECTED MEMBER FUNCTIONS
439 
440 template <int DC, int DB>
441 void
444 {
445  // Preconditions:
446 
447  require(is_empty());
448 
449  // Body:
450 
451  is_abstract();
452 
453  // Postconditions:
454 
455  // Exit:
456 
457  return;
458 }
459 
460 
461 // ===========================================================
462 // POINT_LOCATOR FACET
463 // ===========================================================
464 
465 // PUBLIC MEMBER FUNCTIONS
466 
467 template <int DC, int DB>
468 void
471 {
472 #ifdef DIAGNOSTIC_OUTPUT
473  post_information_message("Entering update");
474 #endif
475 
476  // Preconditions:
477 
478  require(this->coordinates().state_is_read_accessible());
479 
480  // Body:
481 
482  update(true, 256); // Arbitrary eval capacity
483 
484  // Postconditions:
485 
486  ensure(!is_empty());
487 
488  // Exit:
489 
490 #ifdef DIAGNOSTIC_OUTPUT
491  post_information_message("Leaving update");
492 #endif
493 
494  return;
495 }
496 
497 template <int DC, int DB>
498 void
500 update(bool xpopulate, size_type xeval_capacity)
501 {
502 #ifdef DIAGNOSTIC_OUTPUT
503  post_information_message("Entering update(bool)");
504 #endif
505 
506 // cerr << endl;
507 // cerr << "Entering d_bin_point_locator<" << DC << ", " << DB
508 // <<">::update:" << endl;
509 // cerr << " xpopulate = " << boolalpha << xpopulate << endl;
510 // cerr << " xeval_capacity = " << xeval_capacity << endl;
511 // cerr << endl;
512 
513  // Preconditions:
514 
515  require(this->coordinates().state_is_read_accessible());
516 
517  // Body:
518 
519  this->update_domain();
520  this->update_bins();
521 
522  // For each coordinate field evaluator, we need to
523  // create a bounding box and insert the bounding box into the search structure.
524  // It's more efficient if we allocate all the bounding boxes at once.
525  // It's also more efficient if we gather all the dofs for each evaluator
526  // in advance. So find out how many evaluators we have:
527 
528  size_type leval_ct = this->coordinates().schema().evaluation_ct();
529 
530  if(xeval_capacity < leval_ct)
531  {
532  xeval_capacity = leval_ct;
533  }
534 
535  // We need one bounding box for each evaluation_member.
536 
537  this->_boxes.reserve(xeval_capacity);
538  this->_boxes.set_ct(0);
539 
540  // Start the dof buffer off at a reasonable size.
541  // We don't know how many dofs there are for each element,
542  // but the buffer will resize as necessary.
543 
544  this->_gathered_dofs.reserve(xeval_capacity*DC*8);
545  this->_gathered_dofs.set_ct(0);
546 
547  if(xpopulate)
548  {
549  // Iterate over the branches.
551 
552  sec_vd lbranch;
553  preorder_iterator lbranch_itr(coordinates(), "jims", DOWN, NOT_STRICT);
554  while(!lbranch_itr.is_done())
555  {
556  // Get a handle to this branch.
557 
558  const scoped_index& lbranch_id = lbranch_itr.index();
559  lbranch.attach_to_state(coordinates().host(), lbranch_id);
560 
561  // Re-anchor the eval itr to this branch.
562 
564  _eval_itr.reset(false);
565 
566  // Get the discretization members from the iterator.
567 
569 
570  // Iterate over the eval members in this branch,
571 
572  while(!_eval_itr.is_done())
573  {
574  // Save the starting location of the dofs for this eval member.
575 
576  size_type lold_dofs_ct = this->_gathered_dofs.ct();
577  sec_vd_dof_type* dofs_ptr = this->_gathered_dofs.base() + lold_dofs_ct;
578 
579  // Gather the dofs for this eval member.
580 
581  _eval_itr.gather_dofs(lbranch, this->_gathered_dofs);
582 
583  // Get the number of dofs for this eval member.
584 
585  size_type dof_ct = this->_gathered_dofs.ct() - lold_dofs_ct;
586 
587  // Get a bounding box for this eval member.
588 
589  this->_boxes.set_ct(this->_boxes.ct() + 1);
590  d_bounding_box<DC, DB>& bbox = this->_boxes.back();
591 
592  // Get the evaluator for this eval member.
593 
594  section_evaluator& levaluator = _eval_itr.evaluator();
595 
596  // Get the bounds for this eval member and put them in the bounding box.
597  // Must convert from the global coordinate system to search
598  // structure-relative coordinates.
599 
600  sec_vd_value_type gbl_pos[DC];
602 
603  levaluator.min(dofs_ptr, dof_ct, gbl_pos, DC);
604  this->relative_position_pa(gbl_pos, DC, rel_pos);
605 
606 // cerr << " lower bound: bbox.put_lb(rel_pos)" << endl;
607 // cerr << " gbl_pos[0], rel_pos[0] = " << gbl_pos[0] << " : " << rel_pos[0] << endl;
608 // cerr << " gbl_pos[1], rel_pos[1] = " << gbl_pos[1] << " : " << rel_pos[1] << endl;
609 // cerr << " gbl_pos[2], rel_pos[2] = " << gbl_pos[2] << " : " << rel_pos[2] << endl;
610 // cerr << endl;
611 
612  bbox.put_lb(rel_pos);
613 
614  levaluator.max(dofs_ptr, dof_ct, gbl_pos, DC);
615  this->relative_position_pa(gbl_pos, DC, rel_pos);
616 
617 // cerr << " upper bound: bbox.put_lb(rel_pos)" << endl;
618 // cerr << " gbl_pos[0], rel_pos[0] = " << gbl_pos[0] << " : " << rel_pos[0] << endl;
619 // cerr << " gbl_pos[1], rel_pos[1] = " << gbl_pos[1] << " : " << rel_pos[1] << endl;
620 // cerr << " gbl_pos[2], rel_pos[2] = " << gbl_pos[2] << " : " << rel_pos[2] << endl;
621 // cerr << endl;
622 
623  bbox.put_ub(rel_pos);
624 
625  // Set the other attributes of the bounding box.
626 
627  bbox.put_member_id(_eval_itr.index());
628  bbox.put_branch_id(lbranch_id);
629  bbox.put_dofs_index(lold_dofs_ct);
630  bbox.put_evaluator(&levaluator);
631  bbox.put_dof_ct(dof_ct);
632 
633  // Insert the bounding box into the search structure.
634 
635  this->insert_box(&bbox);
636 
637  // Move on to the next evaluator.
638 
639  _eval_itr.next();
640  }
641 
642  // Move on to the next branch.
643 
644  lbranch_itr.truncate();
645  }
646 
647  lbranch.detach_from_state();
648 
649  } // end if(xpoluate)
650 
651 
652  // Postconditions:
653 
654  ensure(is_empty() == !xpopulate);
655 
656  // Exit:
657 
658 
659 // cerr << "Leaving d_bin_point_locator<" << DC << ", " << DB
660 // <<">::update:" << endl;
661 // cerr << endl;
662 
663 #ifdef DIAGNOSTIC_OUTPUT
664  post_information_message("Leaving update");
665 #endif
666 
667  return;
668 }
669 
670 template <int DC, int DB>
673 assign_box(const scoped_index& xmbr_id,
674  const scoped_index& xbranch_id,
675  section_evaluator& xeval,
676  const sec_vd_dof_type* xdofs,
677  size_type xdofs_ct)
678 {
679 #ifdef DIAGNOSTIC_OUTPUT
680  post_information_message("Entering assign_box");
681 #endif
682 
683 // cerr << endl;
684 // cerr << "Entering d_bin_point_locator<" << DC << ", " << DB
685 // <<">::assign_box:" << endl;
686 // cerr << endl;
687 
688 
689  // Preconditions:
690 
691  require(this->coordinates().state_is_read_accessible());
692  require(xdofs_ct > 0);
693  require(xmbr_id.pod() < box_capacity());
694 
695  // Body:
696 
697  define_old_variable(size_type old_box_ct = box_ct());
698 
699  // Save the starting location of the dofs for this eval member.
700 
701  size_type lold_dofs_ct = this->_gathered_dofs.ct();
702  sec_vd_dof_type* dofs_ptr = this->_gathered_dofs.base() + lold_dofs_ct;
703 
704  // Make sure gathered_dofs has enough capacity;
705  // forcing the last item will efficiently reallocate if needed.
706 
707  size_type llast_dof = xdofs_ct - 1;
708  this->_gathered_dofs.force_item(lold_dofs_ct+llast_dof, xdofs[llast_dof]);
709  this->_gathered_dofs.set_ct(lold_dofs_ct+xdofs_ct);
710 
711  // Put the dofs into the gathered dofs buffer.
712 
713  for(size_type i=0; i<llast_dof; ++i)
714  {
715  dofs_ptr[i] = xdofs[i];
716  }
717 
718  // Get a bounding box for this eval member.
719 
720  // this->_boxes.set_ct(_boxes.ct() + 1);
721  // d_bounding_box<DC, DB>* result = &(this->_boxes.back());
722 
723  d_bounding_box<DC, DB>* result = &(this->_boxes[xmbr_id.pod()]);
724 
725  // Get the bounds for this eval member and put them in the bounding box.
726  // Must convert from the global coordinate system to search
727  // structure-relative coordinates.
728 
729  sec_vd_value_type gbl_pos[DC];
731 
732  xeval.min(dofs_ptr, xdofs_ct, gbl_pos, DC);
733  this->relative_position_pa(gbl_pos, DC, rel_pos);
734 
735 // cerr << " lower bound: result->put_lb(rel_pos)" << endl;
736 // cerr << " gbl_pos[0], rel_pos[0] = " << gbl_pos[0] << " : " << rel_pos[0] << endl;
737 // cerr << " gbl_pos[1], rel_pos[1] = " << gbl_pos[1] << " : " << rel_pos[1] << endl;
738 // cerr << " gbl_pos[2], rel_pos[2] = " << gbl_pos[2] << " : " << rel_pos[2] << endl;
739 // cerr << endl;
740 
741  result->put_lb(rel_pos);
742 
743  xeval.max(dofs_ptr, xdofs_ct, gbl_pos, DC);
744  this->relative_position_pa(gbl_pos, DC, rel_pos);
745 
746 // cerr << " upper bound: result->put_ub(rel_pos)" << endl;
747 // cerr << " gbl_pos[0], rel_pos[0] = " << gbl_pos[0] << " : " << rel_pos[0] << endl;
748 // cerr << " gbl_pos[1], rel_pos[1] = " << gbl_pos[1] << " : " << rel_pos[1] << endl;
749 // cerr << " gbl_pos[2], rel_pos[2] = " << gbl_pos[2] << " : " << rel_pos[2] << endl;
750 // cerr << endl;
751 
752  result->put_ub(rel_pos);
753 
754  // Set the other attributes of the bounding box.
755 
756  result->put_member_id(xmbr_id);
757  result->put_branch_id(xbranch_id);
758  result->put_dofs_index(lold_dofs_ct);
759  result->put_evaluator(&xeval);
760  result->put_dof_ct(xdofs_ct);
761 
762  // Postconditions:
763 
764  ensure(box_ct() == old_box_ct);
765  // ensure(allocated_box_ct() == old_allocated_box_ct+1);
766  // ensure(result == box(old_allocated_box_ct));
767  ensure(result == box(xmbr_id.pod()));
768 
769  // Exit:
770 
771 // cerr << endl;
772 // cerr << "Leaving d_bin_point_locator<" << DC << ", " << DB
773 // <<">::assign_box:" << endl;
774 // cerr << endl;
775 
776 #ifdef DIAGNOSTIC_OUTPUT
777  post_information_message("Leaving assign_box");
778 #endif
779 
780  return result;
781 }
782 
783 template <int DC, int DB>
784 size_type
787 {
788  return _boxes.ub();
789 }
790 
791 template <int DC, int DB>
795 {
796 #ifdef DIAGNOSTIC_OUTPUT
797  post_information_message("Entering box");
798 #endif
799 
800  // Preconditions:
801 
802  require((0 <= xi) && (xi < box_capacity()));
803 
804  // Body:
805 
806  d_bounding_box<DC, DB>* result = &(this->_boxes[xi]);
807 
808  // Postconditions:
809 
810 
811  // Exit:
812 
813 #ifdef DIAGNOSTIC_OUTPUT
814  post_information_message("Leaving box");
815 #endif
816 
817  return result;
818 }
819 
820 template <int DC, int DB>
821 void
824 {
825 #ifdef DIAGNOSTIC_OUTPUT
826  post_information_message("Entering update_box");
827 #endif
828 
829  // Preconditions:
830 
831  require((0 <= xi) && (xi < box_capacity()));
832  require(box(xi)->evaluator() != 0);
833  require(box(xi)->dof_ct() > 0);
834  require(xdofs_ct >= box(xi)->dof_ct());
835 
836  // Body:
837 
838  d_bounding_box<DC, DB>& lbox = this->_boxes[xi];
839 
840  //$$SCRIBBLE: The code in remove_box and insert_box called below
841  // is not optimal for the purpose here. Instead of
842  // remove_box we should only remove a box if it is
843  // in "old-new" and instead of insert_box only insert
844  // a box if it is in "new-old".
845 
846  // Remove the box if necessary.
847 
848  bool lcontains_box = contains_box(&lbox);
849  if(lcontains_box)
850  {
851  remove_box(&lbox);
852  }
853 
854  sec_vd_dof_type* ldofs_begin = _gathered_dofs.base() + lbox.dofs_index();
855 
856  // Update the gathered dofs for this box.
857 
858  sec_vd_dof_type* lptr = ldofs_begin;
859  for(size_type i=0; i<xdofs_ct; ++i, ++lptr)
860  {
861  *lptr = xdofs[i];
862  }
863 
864  // Update the bounds for this box.
865 
866  sec_vd_value_type gbl_pos[DC];
868 
869  section_evaluator& leval = *(lbox.evaluator());
870 
871  leval.min(xdofs, xdofs_ct, gbl_pos, DC);
872  this->relative_position_pa(gbl_pos, DC, rel_pos);
873  lbox.put_lb(rel_pos);
874 
875  leval.max(xdofs, xdofs_ct, gbl_pos, DC);
876  this->relative_position_pa(gbl_pos, DC, rel_pos);
877  lbox.put_ub(rel_pos);
878 
879  // Reinsert the box if necessary.
880 
881  if(lcontains_box)
882  {
883  insert_box(&lbox);
884  }
885 
886  // Postconditions:
887 
888  // Exit:
889 
890 #ifdef DIAGNOSTIC_OUTPUT
891  post_information_message("Leaving update_box");
892 #endif
893 
894  return;
895 }
896 
897 template <int DC, int DB>
898 void
901  size_type xvalue_ub,
902  chart_point& xresult)
903 {
904  require(xvalue != 0);
905  require(xvalue_ub >= this->dc());
906  require(xresult.db() >= this->db());
907 
908  // Body:
909 
911 
912  sec_vd_value_type* global_coords = const_cast<sec_vd_value_type*>(xvalue);
913 
914  // Initialize the chart id to invalid.
915  // If the inversion succeeds, it will be set to valid.
916 
917  xresult.invalidate();
918 
919  if(this->domain_contains(global_coords, DC))
920  {
921  // This point is within the domain.
922  // Find the bounding boxes that may contain the value.
923 
924  d_bin_coordinates<DC, DB> lrel_pos;
925  this->relative_position_pa(global_coords, DC, lrel_pos);
926 
927  const box_list_type& blist = this->box_list(global_coords, DC);
928 
929  // Iterate over the bounding boxes.
930 
931  typename box_list_type::const_iterator iter;
932 
933  for(iter=blist.begin(); !xresult.is_valid() && (iter!=blist.end()); ++iter)
934  {
935  const d_bounding_box<DC, DB>* bbox = *iter;
936 
937  if(bbox->contains_point(lrel_pos))
938  {
939  // Found a cell with a bounding box that contains the value;
940  // try inverting the value.
941 
942  section_evaluator* levaluator = bbox->evaluator();
943 
944  size_type dof_ct = bbox->dof_ct();
945  sec_vd_dof_type* dofs = this->_gathered_dofs.base() + bbox->dofs_index();
946 
947  levaluator->coord_at_value(dofs,
948  dof_ct,
949  global_coords,
950  DC,
951  xresult.local_coords(),
952  xresult.db());
953 
954  if(levaluator->in_standard_domain(xresult.local_coords(), xresult.db()))
955  {
956  // Inversion succeeded.
957  // The coordinates are already stored in xresult_coords;
958  // so just set the chart id.
959 
960  xresult.put_chart_id(bbox->member_id());
961  }
962  else
963  {
964  // Inversion failed.
965 
966  xresult.invalidate();
967  }
968  }
969  }
970  }
971  else
972  {
973  // This point is ouside the domain of the search structure and hence
974  // outside the range of the source coordinates.
975  // We can't invert it; just leave the result invalid.
976  }
977 
978 
979  // Postconditions:
980 
981  ensure(unexecutable(xresult.is_valid() ?
982  xresult.chart() contains xvalue at xresult.local_coord() :
983  no chart contains xvalue));
984 
985 
986  // Exit:
987 
988  return;
989 }
990 
991 template <int DC, int DB>
992 void
995  size_type xvalue_ub,
996  block<chart_point_3d>& xresult)
997 {
998 #ifdef DIAGNOSTIC_OUTPUT
999  post_information_message("Entering all_points_at_value");
1000 #endif
1001 
1002  require(xvalue != 0);
1003  require(xvalue_ub >= this->dc());
1004  require(this->db() <= 3);
1005 
1006  // Body:
1007 
1009 
1010  sec_vd_value_type* global_coords = const_cast<sec_vd_value_type*>(xvalue);
1011 
1012  define_old_variable(int old_xresult_ct = xresult.ct());
1013 
1014  chart_point_3d lchart_pt(invalid_pod_index(), 0.0, 0.0, 0.0);
1015 
1016  if(this->domain_contains(global_coords, DC))
1017  {
1018  // This point is within the domain.
1019  // Find the bounding boxes that may contain the value.
1020 
1021  d_bin_coordinates<DC, DB> lrel_pos;
1022  this->relative_position_pa(global_coords, DC, lrel_pos);
1023 
1024  const box_list_type& blist = this->box_list(global_coords, DC);
1025 
1026  // Iterate over the bounding boxes.
1027 
1028  typename box_list_type::const_iterator iter;
1029 
1030  for(iter = blist.begin(); iter != blist.end(); ++iter)
1031  {
1032  const d_bounding_box<DC, DB>* bbox = *iter;
1033 
1034  if(bbox->contains_point(lrel_pos))
1035  {
1036  // Found a cell with a bounding box that contains the value;
1037  // try inverting the value.
1038 
1039  section_evaluator* levaluator = bbox->evaluator();
1040 
1041  size_type dof_ct = bbox->dof_ct();
1042  sec_vd_dof_type* dofs = this->_gathered_dofs.base() + bbox->dofs_index();
1043 
1044  levaluator->coord_at_value(dofs,
1045  dof_ct,
1046  global_coords,
1047  DC,
1048  lchart_pt.local_coords(),
1049  lchart_pt.db());
1050 
1051  if(levaluator->in_standard_domain(lchart_pt.local_coords(), lchart_pt.db()))
1052  {
1053  // Inversion succeeded.
1054  // The coordinates are already stored in lchart_pt coords;
1055  // so just set the chart id.
1056 
1057  lchart_pt.put_chart_id(bbox->member_id());
1058  xresult.push_back(lchart_pt);
1059  }
1060  else
1061  {
1062  // Inversion failed; do nothing.
1063  }
1064  }
1065  }
1066  }
1067  else
1068  {
1069  // This point is ouside the domain of the search structure and hence
1070  // outside the range of the source coordinates.
1071  // We can't invert it; just leave the result empty.
1072  }
1073 
1074 
1075 #ifdef DIAGNOSTIC_OUTPUT
1076  cout << "result: " << xresult << endl;
1077 #endif
1078 
1079  // Postconditions:
1080 
1081  ensure_for_all(i, 0, xresult.ct(), xresult[i].is_valid());
1082 
1083 
1084  // Exit:
1085 
1086 #ifdef DIAGNOSTIC_OUTPUT
1087 
1088  post_information_message("Leaving all_points_at_value");
1089 #endif
1090 
1091  return;
1092 }
1093 
1094 template <int DC, int DB>
1095 void
1098  size_type xvalue_ub,
1099  block<branch_point_pair>& xresult)
1100 {
1101 #ifdef DIAGNOSTIC_OUTPUT
1102  post_information_message("Entering branch_points_at_value");
1103 #endif
1104 
1105  require(xvalue != 0);
1106  require(xvalue_ub >= this->dc());
1107  require(this->dc() <= 3);
1108 
1109  // Body:
1110 
1111  define_old_variable(int old_xresult_ct = xresult.ct());
1112 
1114 
1115  sec_vd_value_type* global_coords = const_cast<sec_vd_value_type*>(xvalue);
1116 
1117  branch_point_pair lbranch_pt;
1118  scoped_index& lbranch_id = lbranch_pt.first;
1119  chart_point_3d& lchart_pt = lbranch_pt.second;
1120 
1121  if(this->domain_contains(global_coords, DC))
1122  {
1123  // This point is within the domain.
1124  // Find the bounding boxes that may contain the value.
1125 
1126  d_bin_coordinates<DC, DB> lrel_pos;
1127  this->relative_position_pa(global_coords, DC, lrel_pos);
1128 
1129  const box_list_type& blist = this->box_list(global_coords, DC);
1130 
1131  // Iterate over the bounding boxes.
1132 
1133  typename box_list_type::const_iterator iter;
1134 
1135  for(iter = blist.begin(); iter != blist.end(); ++iter)
1136  {
1137  const d_bounding_box<DC, DB>* bbox = *iter;
1138 
1139 #ifdef DIAGNOSTIC_OUTPUT
1140 
1141  cout << "considering " << *bbox << endl;
1142 #endif
1143 
1144  lbranch_id = bbox->branch_id();
1145 
1146  if((_branches.find(lbranch_id) == _branches.end()) &&
1147  (bbox->contains_point(lrel_pos)))
1148  {
1149 
1150 #ifdef DIAGNOSTIC_OUTPUT
1151  cout << "Inverting it ... ";
1152 #endif
1153  // Haven't found a point for this branch yet and we've
1154  // found a cell with a bounding box that contains the value;
1155  // try inverting the value.
1156 
1157  section_evaluator* levaluator = bbox->evaluator();
1158 
1159 
1160  size_type dof_ct = bbox->dof_ct();
1161  sec_vd_dof_type* dofs = this->_gathered_dofs.base() + bbox->dofs_index();
1162 
1163  levaluator->coord_at_value(dofs,
1164  dof_ct,
1165  global_coords,
1166  DC,
1167  lchart_pt.local_coords(),
1168  lchart_pt.db());
1169 
1170  if(levaluator->in_standard_domain(lchart_pt.local_coords(), lchart_pt.db()))
1171  {
1172  // Inversion succeeded.
1173  // The coordinates are already stored in lchart_pt coords;
1174  // so just set the chart id.
1175 
1176 #ifdef DIAGNOSTIC_OUTPUT
1177  cout << "valid" << endl;
1178 #endif
1179 
1180  lchart_pt.put_chart_id(bbox->member_id());
1181  xresult.push_back(lbranch_pt);
1182 
1183  // We've found a point for this branch.
1184 
1185  _branches.insert(lbranch_id);
1186  }
1187  else
1188  {
1189  // Inversion failed; do nothing.
1190 
1191 #ifdef DIAGNOSTIC_OUTPUT
1192  cout << "invalid" << endl;
1193 #endif
1194 
1195  }
1196  }
1197  else
1198  {
1199 #ifdef DIAGNOSTIC_OUTPUT
1200  cout << "Ignoring it" << endl;
1201 #endif
1202 
1203  }
1204 
1205  }
1206  }
1207  else
1208  {
1209  // This point is ouside the domain of the search structure and hence
1210  // outside the range of the source coordinates.
1211  // We can't invert it; just leave the result empty.
1212  }
1213 
1214  // Clean up.
1215 
1216  _branches.clear();
1217 
1218 #ifdef DIAGNOSTIC_OUTPUT
1219 
1220  cout << "result: " << xresult << endl;
1221 #endif
1222 
1223  // Postconditions:
1224 
1225  ensure(xresult.ct() >= old_xresult_ct);
1226  ensure_for_all(i, old_xresult_ct, xresult.ct(),
1227  coordinates().host()->contains_member(xresult[i].first, false));
1228  ensure_for_all(i, old_xresult_ct, xresult.ct(), xresult[i].second.is_valid());
1229 
1230 
1231  // Exit:
1232 
1233 #ifdef DIAGNOSTIC_OUTPUT
1234 
1235  post_information_message("Leaving branch_points_at_value");
1236 #endif
1237 
1238  return;
1239 }
1240 
1241 
1242 // ===========================================================
1243 // NON-MEMBER FUNCTIONS
1244 // ===========================================================
1245 
1246 } // namespace geometry
1247 
1248 #endif // D_BIN_POINT_LOCATOR_IMPL_H
std::set< stl_scoped_index<> > _branches
The branches for which a point has already been found for the current evaluation member. Used in all_points_at_value, allocated her to avoid reallocation for each query.
virtual void remove_box(d_bounding_box< DC, DB > *xbox)=0
Remove xbox from the search structure.
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...
void truncate()
Makes this the next member of the subset which is not less than old this, i.e. the depth-first descen...
const block< sec_vd_value_type > & bin_size() const
The dimensions of the smallest bins.
virtual void update()
Updates the search structure to the current values of coordinates(); synonym for update(true);.
size_type ct() const
The number of items currently in use.
const pod_type & pod() const
The "plain old data" storage of this; the value in the external id space.
Definition: scoped_index.h:672
sec_ed & coordinates() const
The coordinate section this inverts.
const scoped_index & member_id() const
Index of the evaluation member this bounds.
void put_lb(const d_bin_coordinates< DC, DB > &xlb)
Copies the contents of xlb to lb().
section_evaluator & evaluator()
The section evaluator associated with the current evaluation member (mutable version).
block< sec_vd_value_type > _one_over_min_bin_size
Reciprocal of the dimensions of the smallest bins.
A point in a 3D chart space.
size_type box_capacity()
The number of boxes that have been allocated.
bool is_empty() const
True if this contains no bounding boxes.
d_bounding_box< DC, DB > * box(pod_index_type xi)
The xi-th bounding box.
virtual void force_is_done()
Force the iterator to be done.
virtual int db() const =0
The dimension of this chart.
Definition: chart_point.cc:141
void put_dof_ct(size_type xct)
Sets dof_ct() to xct.
virtual int db() const
The dimension of this chart.
eval_iterator _eval_itr
The evaluator iterator used to populate the search structure; must have same life time as the search ...
void force_item(index_type xindex, const_reference_type xitem)
Puts the item xitem at index xindex, resizing if necessary; any other new storage allocated is uninit...
void reserve(index_type xub)
Makes ub() at least xub; if new storage is allocated, it is uninitialized.
point_locator()
Default constructor.
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
void update_domain()
Initializes the domain bounds and dimension.
virtual ~d_bin_point_locator()
Destructor.
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.
iterator begin()
Returns an iterator to the first element of the container.
Fixed point relative coordinates for a tree domain.
virtual bool in_standard_domain(const dof_type xlocal_coords[], size_type xlocal_coords_ub) const =0
True if the specified local coordinates are in the "standard" domain.
bool is_valid() const
True if this ia a valid point in a chart.
Definition: chart_point.cc:303
A section of a fiber bundle with a d-dimensional Euclidean vector space fiber.
Definition: sec_ed.h:47
void update_box(pod_index_type xi, const sec_vd_dof_type *xdofs, size_type xdofs_ct)
Updates the xi-th bounding box with dofs xdofs.
std::pair< scoped_index, chart_point_3d > branch_point_pair
A point in base space paired with a branch in section space.
Definition: geometry.h:79
void invalidate()
Makes this invalid.
Definition: chart_point.cc:322
virtual void clear()=0
Clear the search structure of all bounding boxes.
const bool NOT_STRICT
Iteration strictness control.
Definition: sheaf.h:102
const bool DOWN
Iteration directions.
Definition: sheaf.h:77
bool contains_point(const d_bin_coordinates< DC, DB > &xpt) const
True if this contains point xpt.
virtual coord_type * local_coords()=0
The array of local coordinates.
Definition: chart_point.cc:209
size_type dof_ct() const
The number of dofs in the gathered dofs array for the evaluation member this bounds.
block< sec_vd_value_type > _lb
The lower bound of the domain.
void push_back(const_reference_type item)
Insert item at the end of the items in the auto_block.
virtual dof_type max(const dof_type xdofs[], size_type xdofs_ub) const
The maximum value of the scalar or component section defined by xdofs.
block< d_bounding_box< DC, DB > > _boxes
Bounding boxes for the evaluation members.
size_type dofs_index() const
Index into the gathered dofs array for the evaluation member this bounds.
block< size_type > _bin_ub
The upper bound for the bin index.
virtual const box_list_type & box_list(sec_vd_value_type *xpt, size_type xpt_ub) const =0
The list of bounding boxes which may contain xpt.
pointer_type base() const
The underlying storage array.
void put_schema_anchor(const section_space_schema_member &xschema_anchor)
Set schema_anchor() to the same state as xschema_anchor.
void set_ct(size_type xct)
Sets ct() == xct.
void put_member_id(const scoped_index &xid)
Sets member_id() to xid.
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
A bounding box that can be strung together into a list.
virtual void coord_at_value(const dof_type xdofs[], size_type xdofs_ub, const dof_type xvalue[], size_type xvalue_ub, dof_type xlocal_coords[], size_type xlocal_coords_ub) const =0
The local coordinates of a point at which the field has the value xvalue. The dofs are assumed to be ...
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. ...
void put_dofs_index(size_type xindex)
Sets dofs_index() to xindex.
virtual bool contains_box(d_bounding_box< DC, DB > *xbox) const =0
True if xbox is in the box list of some bin.
void next()
Makes this the next member of the subset.
d_bin_coordinates< DC, DB > * relative_position(sec_vd_value_type *xpt, size_type xpt_ub) const
The position of xpt relative to the lower bound, in integer coordinates; auto-allocated version...
iterator end()
Returns an iterator to the element following the last element of the container.
size_type box_ct() const
The number of bounding boxes stored in the search structure.
virtual void insert_box(d_bounding_box< DC, DB > *xbox)=0
Insert xbox into the search structure.
An abstract local section evaluator; a map from {local coordinates x dofs} to section value...
coord_type * local_coords()
The array of local coordinates.
A section of a fiber bundle with a d-dimensional vector space fiber.
Definition: sec_vd.h:54
section_evaluator * evaluator() const
Evaluator for the evaluation member this bounds.
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 void update_bins()=0
Updates the bin parameters.
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 and appends them to xresult...
void put_evaluator(section_evaluator *xevaluator)
Sets evaluator() to xevaluator.
int db() const
The intrinsic dimension of the domain; the dimension of the local coordinates.
virtual void reset(bool xreset_markers=true)
Restarts the iteration over the down set of anchor().
virtual dof_type min(const dof_type xdofs[], size_type xdofs_ub) const
The minimum value of the scalar or component section defined by xdofs.
void relative_position_pa(sec_vd_value_type *xpt, size_type xpt_ub, d_bin_coordinates< DC, DB > &xresult) const
The position of xpt relative to the lower bound, in integer coordinates; pre-allocated version...
size_type _box_ct
The number of bounding boxes stored in the search structure.
void put_ub(const d_bin_coordinates< DC, DB > &xub)
Copies the contents of xub to ub().
virtual section_space_schema_member & schema()
The restricted schema for this (mutable version).
const block< size_type > & bin_ub() const
The upper bound for the bin index.
d_bounding_box< DC, DB > * assign_box(const scoped_index &xmbr_id, const scoped_index &xbranch_id, section_evaluator &xeval, const sec_vd_dof_type *xdofs, size_type xdofs_ct)
Assigns a box to xmbr_id and initializes it, but does not insert it in the search structure...
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.
const scoped_index & branch_id() const
Index of the branch that contains the evaluation member this bounds.
int evaluation_ct() const
The number of members in the intersection of the evaluation subposet and the down set of the base spa...
void gather_dofs(const sec_vd &xsec, block< sec_vd::dof_type > &xdofs)
Gathers the dofs for the current evalaution member from section xsec and appends them to the back of ...
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.
const block< sec_vd_dof_type > & gathered_dofs() const
The dofs of gathered by evaluation member.
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.
void put_branch_id(const scoped_index &xid)
Sets branch_id() to xid.
double sec_vd_dof_type
The type of degree of freedom in the section space.
Definition: fiber_bundle.h:78
block< scoped_index > & discretization_members()
The discretization members in the downset of the current evaluation member (mutable version)...
virtual bool invariant() const
Class invariant.
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
SHEAF_DLL_SPEC pod_index_type invalid_pod_index()
The invalid pod index value.
Definition: pod_types.cc:31
bool domain_contains(sec_vd_value_type *xpt, size_type xpt_ub) const
True if the domain contains xpt.
block< sec_vd_dof_type > _gathered_dofs
The dofs of gathered by evaluation member.
block< sec_vd_value_type > _bin_size
The dimensions of the smallest bins.
virtual coord_type local_coord(int xi) const =0
The xi-th local coordinate of this point.
Definition: chart_point.cc:163
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
const scoped_index & index() const
The index of the current member of the iteration.
d_bin_point_locator()
Default constructor; disabled.