Rheolef  7.2
an efficient C++ finite element environment
Loading...
Searching...
No Matches
geo_locate.cc
Go to the documentation of this file.
1
21//
22// given x, search K in mesh such that x in K
23//
24// author: Pierre.Saramito@imag.fr
25//
26// date: 12 march 2012
27//
28// implementation note:
29// use CGAL::Segment_tree for element location
30//
31#include "rheolef/geo_locate.h"
32#include "rheolef/geo.h"
33#include "rheolef/geo_element_contains.h"
34#include "rheolef/point_util.h"
35
36// internal includes:
37#ifdef _RHEOLEF_HAVE_CGAL
38#include "rheolef/cgal_traits.h"
39#include <CGAL/Segment_tree_k.h>
40#include <CGAL/Range_segment_tree_traits.h>
41#endif // _RHEOLEF_HAVE_CGAL
42
43#ifdef _RHEOLEF_HAVE_CGAL
44namespace rheolef { namespace details {
45// CGAL::Segment_tree_1::make_tree is broken in recent CGAL (6.x):
46// it passes a Tree_anchor pointer instead of a reference to the
47// Segment_tree_d constructor. Rebuild the 1D tree by hand.
48template <class Tree, class Iterator>
49inline void cgal_make_tree (Tree& tree, Iterator first, Iterator last)
50{
51 tree.make_tree (first, last);
52}
53template <class Traits, class Iterator>
54inline void cgal_make_tree (CGAL::Segment_tree_1<Traits>& tree, Iterator first, Iterator last)
55{
56 typedef typename CGAL::Segment_tree_1<Traits>::Segment_tree_1_type tree_type;
57 delete tree.segment_tree_1;
58 tree.segment_tree_1 = new tree_type (*tree.anchor);
59 tree.segment_tree_1->make_tree (first, last);
60}
61}} // namespace rheolef::details
62#endif // _RHEOLEF_HAVE_CGAL
63
64namespace rheolef {
65
66// ---------------------------------------------------------------------
67// 1) utility: bbox of a geo_element
68// ---------------------------------------------------------------------
69template <class T, class M>
70void
72{
73 // TODO: omega.order == 1 only: K.size == K.n_node
74 typedef typename geo_base_rep<T,M>::size_type size_type;
75 size_type d = omega.dimension();
76 for (size_type j = 0; j < d; j++) {
77 xmin[j] = std::numeric_limits<T>::max();
78 xmax[j] = -std::numeric_limits<T>::max();
79 }
80 for (size_type iloc = 0, nloc = K.size(); iloc < nloc; iloc++) {
81 size_type dis_inod = K[iloc];
82 const point_basic<T>& x = omega.dis_node(dis_inod);
83 for (size_type j = 0; j < d; j++) {
84 xmin[j] = std::min(x[j], xmin[j]);
85 xmax[j] = std::max(x[j], xmax[j]);
86 }
87 }
88}
89#ifdef _RHEOLEF_HAVE_CGAL
90// -----------------------------------------------------------------------------------
91// 2) missing in cgal: inspirated from "examples/RangeSegmentTrees/include/Tree_Traits.h"
92// -----------------------------------------------------------------------------------
93template <class Kernel, class Val>
94class Segment_tree_map_traits_1 {
95 public:
96 typedef Val Value;
97 typedef typename Kernel::FT Point_1 ;
98 typedef Point_1 Key;
99 typedef Point_1 Key_1;
100 typedef std::pair<Key,Key> Pure_interval;
101 typedef std::pair<Pure_interval, Val> Interval;
102
103 class C_Low_1{
104 public:
105 Key_1 operator()(const Interval& i)
106 { return i.first.first;}
107 };
108
109 class C_High_1{
110 public:
111 Key_1 operator()(const Interval& i)
112 { return i.first.second;}
113 };
114
115 class C_Key_1{
116 public:
117 Key_1 operator()(const Key& k)
118 { return k;}
119 };
120
121 class C_Compare_1{
122 public:
123 bool operator()(Key_1 k1, Key_1 k2)
124 {
125 return std::less<Float>()(k1,k2);
126 }
127 };
128
129 typedef C_Compare_1 compare_1;
130 typedef C_Low_1 low_1;
131 typedef C_High_1 high_1;
132 typedef C_Key_1 key_1;
133};
134// -----------------------------------------------------------------------------------
135// 3) helper a generic dimension=D implementation with cgal
136// -----------------------------------------------------------------------------------
137
138template <class T, size_t D> struct cgal_locate_traits {};
139
140template <class T>
141struct cgal_locate_traits<T,1> {
142
143// typedef:
144
146
147 typedef typename geo_cgal_traits<T,1>::Kernel Kernel;
148 typedef Segment_tree_map_traits_1<Kernel,size_type> Traits;
149 typedef ::CGAL::Segment_tree_1<Traits> Segment_tree_type;
150 typedef typename Traits::Interval Interval;
151 typedef typename Traits::Pure_interval Pure_interval;
152 typedef typename Traits::Key Key;
153
154 static Pure_interval make_cgal_bbox (const point_basic<T>& xmin, const point_basic<T>& xmax)
155 {
156 return Pure_interval(Key(xmin[0]),
157 Key(xmax[0]));
158 }
159 static Pure_interval make_cgal_point_window (const point_basic<T>& x, const T& eps)
160 {
161 return Pure_interval (Key(x[0]-eps),
162 Key(x[0]+eps));
163 }
164 static void put (std::ostream& out, const Pure_interval& b) {
165 out << "[" << b.first << "," << b.second << "[";
166 }
167};
168template <class T>
169struct cgal_locate_traits<T,2> {
170
171// typedef:
172
174
175 typedef typename geo_cgal_traits<T,2>::Kernel Kernel;
176 typedef ::CGAL::Segment_tree_map_traits_2<Kernel,size_type> Traits;
177 typedef ::CGAL::Segment_tree_2<Traits> Segment_tree_type;
178 typedef typename Traits::Interval Interval;
179 typedef typename Traits::Pure_interval Pure_interval;
180 typedef typename Traits::Key Key;
181
182 static Pure_interval make_cgal_bbox (const point_basic<T>& xmin, const point_basic<T>& xmax)
183 {
184 return Pure_interval(Key(xmin[0], xmin[1]),
185 Key(xmax[0], xmax[1]));
186 }
187 static Pure_interval make_cgal_point_window (const point_basic<T>& x, const T& eps)
188 {
189 return Pure_interval (Key(x[0]-eps, x[1]-eps),
190 Key(x[0]+eps, x[1]+eps));
191 }
192 static void put (std::ostream& out, const Pure_interval& b) {
193 out << "[" << b.first.x() << "," << b.second.x() << "[x["
194 << b.first.y() << "," << b.second.y() << "[";
195 }
196};
197template <class T>
198struct cgal_locate_traits<T,3> {
199
200// typedef:
201
203
204 typedef typename geo_cgal_traits<T,3>::Kernel Kernel;
205 typedef ::CGAL::Segment_tree_map_traits_3<Kernel,size_type> Traits;
206 typedef ::CGAL::Segment_tree_3<Traits> Segment_tree_type;
207 typedef typename Traits::Interval Interval;
208 typedef typename Traits::Pure_interval Pure_interval;
209 typedef typename Traits::Key Key;
210
211 static Pure_interval make_cgal_bbox (const point_basic<T>& xmin, const point_basic<T>& xmax)
212 {
213 return Pure_interval(Key(xmin[0], xmin[1], xmin[2]),
214 Key(xmax[0], xmax[1], xmax[2]));
215 }
216 static Pure_interval make_cgal_point_window (const point_basic<T>& x, const T& eps)
217 {
218 return Pure_interval (Key(x[0]-eps, x[1]-eps, x[2]-eps),
219 Key(x[0]+eps, x[1]+eps, x[2]+eps));
220 }
221 static void put (std::ostream& out, const Pure_interval& b) {
222 out << "[" << b.first.x() << "," << b.second.x() << "[x["
223 << b.first.y() << "," << b.second.y() << "[x["
224 << b.first.z() << "," << b.second.z() << "[";
225 }
226};
227// ---------------------------------------------------------------------
228// 4) the geo_locate interface
229// ---------------------------------------------------------------------
230template <class T, class M>
232{
233 if (_ptr != 0) {
234 delete_macro(_ptr);
235 }
236}
237template <class T, class M>
240 const geo_base_rep<T,M>& omega,
241 const point_basic<T>& x,
242 size_type dis_ie_guest) const
243{
244 if (_ptr == 0) { _ptr = make_ptr(omega); }
245 return _ptr->seq_locate (omega, x, dis_ie_guest);
246}
247template <class T, class M>
250 const geo_base_rep<T,M>& omega,
251 const point_basic<T>& x,
252 size_type dis_ie_guest) const
253{
254 if (_ptr == 0) { _ptr = make_ptr(omega); }
255 return _ptr->dis_locate (omega, x, dis_ie_guest);
256}
257// ---------------------------------------------------------------------
258// 5) the tree box abstract data structure
259// ---------------------------------------------------------------------
260template <class T, class M>
261class geo_locate_abstract_rep {
262public:
263 typedef typename disarray<T,M>::size_type size_type;
264 virtual ~geo_locate_abstract_rep() {}
265 virtual void initialize (const geo_base_rep<T,M>& omega) const = 0;
266 virtual size_type seq_locate (
267 const geo_base_rep<T,M>& omega,
268 const point_basic<T>& x,
269 size_type dis_ie_guest = std::numeric_limits<size_type>::max()) const = 0;
270 virtual size_type dis_locate (
271 const geo_base_rep<T,M>& omega,
272 const point_basic<T>& x,
273 size_type dis_ie_guest = std::numeric_limits<size_type>::max()) const = 0;
274};
275// ---------------------------------------------------------------------
276// 5) the tree box concrete, and dimension dependent, data structure
277// = cgal "segment" tree
278// ---------------------------------------------------------------------
279template <class T, class M, size_t D>
280class geo_locate_rep : public geo_locate_abstract_rep<T,M> {
281public:
282
283// typedef:
284
285 typedef typename geo_base_rep<T,M>::size_type size_type;
286
287 typedef typename cgal_locate_traits<T,D>::Segment_tree_type Segment_tree_type;
288 typedef typename cgal_locate_traits<T,D>::Interval Interval;
289
290// allocators:
291
292 geo_locate_rep() : _tree() {}
293 geo_locate_rep(const geo_base_rep<T,M>& omega) : _tree() { initialize(omega); }
294 ~geo_locate_rep() {}
295 void initialize (const geo_base_rep<T,M>& omega) const;
296
297// accessors:
298
299 size_type seq_locate (
300 const geo_base_rep<T,M>& omega,
301 const point_basic<T>& x,
302 size_type dis_ie_guest = std::numeric_limits<size_type>::max()) const;
303 size_type dis_locate (
304 const geo_base_rep<T,M>& omega,
305 const point_basic<T>& x,
306 size_type dis_ie_guest = std::numeric_limits<size_type>::max()) const;
307
308// data:
309protected:
310 mutable Segment_tree_type _tree; // cgal window query requires a mutable _tree (why?)
311};
312// ---------------------------------------------------------------------
313// 5a) allocator
314// ---------------------------------------------------------------------
315template <class T, class M>
316geo_locate_abstract_rep<T,M>*
318{
319 check_macro (omega.dimension() == omega.map_dimension(), "geo_locate: map_dim < dim: not supported");
320 switch (omega.dimension()) {
321 case 1: return new_macro((geo_locate_rep<T,M,1>)(omega));
322 case 2: return new_macro((geo_locate_rep<T,M,2>)(omega));
323 case 3: return new_macro((geo_locate_rep<T,M,3>)(omega));
324 default: error_macro ("unsupported dimension d=" << omega.dimension()); return 0;
325 }
326}
327// ---------------------------------------------------------------------
328// 5b) initialize
329// ---------------------------------------------------------------------
330template <class T, class M, size_t D>
331void
332geo_locate_rep<T,M,D>::initialize (const geo_base_rep<T,M>& omega) const
333{
334 // create the corresponding vector of bounding boxes
335 trace_macro ("geo::locate initialize...");
336 std::list<Interval> boxes;
337 point_basic<T> xmin, xmax;
338 for (size_type ie = 0, ne = omega.size(); ie < ne; ie++) {
339 const geo_element& K = omega[ie];
340 compute_bbox (omega, K, xmin, xmax);
341 boxes.push_back (Interval(cgal_locate_traits<T,D>::make_cgal_bbox (xmin,xmax),ie));
342 }
343 // create tree:
344 // _tree.clear(); // TODO : when e.g. nodes update, rebuild boxes & tree
345 details::cgal_make_tree (_tree, boxes.begin(), boxes.end());
346 trace_macro ("geo::locate initialize done");
347}
348// ---------------------------------------------------------------------
349// 5c) locate
350// ---------------------------------------------------------------------
351template <class T, class M, size_t D>
352typename geo_locate_rep<T,M,D>::size_type
353geo_locate_rep<T,M,D>::seq_locate (
354 const geo_base_rep<T,M>& omega,
355 const point_basic<T>& x,
356 size_type dis_ie_guest) const
357{
358 if (dis_ie_guest != std::numeric_limits<size_type>::max()) {
359 // have a guest:
360 const distributor& ownership = omega.ownership();
361 if (ownership.is_owned (dis_ie_guest)) {
362 size_type first_dis_ie = ownership.first_index();
363 size_type ie_guest = dis_ie_guest - first_dis_ie;
364 const geo_element& K_guest = omega[ie_guest];
365 bool intersect = details::contains (K_guest, omega.get_nodes(), x);
366 if (intersect) {
367 return K_guest.dis_ie();
368 }
369 }
370 }
371 typedef typename geo_base_rep<T,M>::size_type size_type;
372 size_type dis_ie = std::numeric_limits<size_type>::max();
373 // epsilon is only for bbox: then, predicate on element K is exact
374 // TODO: compute epsilon with omega.hmin scale ?
375 // static const T eps = 1e5*std::numeric_limits<T>::epsilon();
376 // static const T eps = 1000*std::numeric_limits<T>::epsilon();
377 static const T eps = sqrt(std::numeric_limits<T>::epsilon());
378 Interval xe = Interval (cgal_locate_traits<T,D>::make_cgal_point_window (x, eps), 0);
379 std::list<Interval> intersected_boxes;
380 // point query = inverse range query ; from ::CGAL documentation:
381 // "In order to perform an inverse range query, a range query of epsilon width has to be performed.
382 // We preferred not to offer an extra function for this sort of query, since the inverse range
383 // query is a special case of the range query (window_query)"
384 _tree.window_query (xe, std::back_inserter(intersected_boxes));
385 for (typename std::list<Interval>::iterator j = intersected_boxes.begin(); j != intersected_boxes.end(); j++) {
386 size_type ie = (*j).second;
387 const geo_element& K = omega[ie];
388 bool intersect = details::contains (K, omega.get_nodes(), x);
389 if (intersect) {
390 dis_ie = K.dis_ie();
391 break;
392 }
393 }
394 return dis_ie;
395}
396// ---------------------------------------------------------------------
397// 5c) dis_locate = one distributed computation
398// ---------------------------------------------------------------------
399template <class T, class M, size_t D>
400typename geo_locate_rep<T,M,D>::size_type
401geo_locate_rep<T,M,D>::dis_locate (
402 const geo_base_rep<T,M>& omega,
403 const point_basic<T>& x,
404 size_type dis_ie_guest) const
405{
406 // mpi::reduce with std::minimum handles unsigned=size_t as signed=long
407 // so use here long to reduce, otherwise leads to a bug
408 using signed_size_type = long;
409 const signed_size_type signed_large = -1;
410 size_type dis_ie = seq_locate (omega, x, dis_ie_guest);
411#ifdef _RHEOLEF_HAVE_MPI
412 if (omega.comm().size() > 1 && is_distributed<M>::value) {
413 // fix for numeric_limits<size_t> == -1 with long int
414 dis_ie = mpi::all_reduce (omega.comm(), signed_size_type(dis_ie), mpi::maximum<signed_size_type>());
415 }
416#endif // _RHEOLEF_HAVE_MPI
417 return dis_ie;
418}
419// ---------------------------------------------------------------------
420// 6) geo::locate()
421// ---------------------------------------------------------------------
422// 6a) scalar case:
423// ----------------
424template <class T, class M>
427 const point_basic<T>& x,
428 size_type dis_ie_guest) const
429{
430 return _locator.seq_locate (*this, x, dis_ie_guest);
431}
432template <class T, class M>
435 const point_basic<T>& x,
436 size_type dis_ie_guest) const
437{
438 return _locator.dis_locate (*this, x, dis_ie_guest);
439}
440// ----------------
441// 6b) disarray case:
442// ----------------
443template <class T>
444void
448 bool do_check) const
449{
450 dis_ie.resize (x.ownership());
451 for (size_type i = 0, n = x.size(); i < n; i++) {
452 dis_ie[i] = base::_locator.seq_locate (*this, x[i], dis_ie[i]);
453 if (do_check) {
454 check_macro (dis_ie[i] != std::numeric_limits<size_type>::max(),
455 "locate: failed at x="<<ptos(x[i],base::_dimension));
456 }
457 }
458}
459#ifdef _RHEOLEF_HAVE_MPI
460template <class T>
461void
465 // dis_ie(ix) can contains a guest for x in K=omega[dis_ie(ix)]
466 bool do_check) const
467{
468 // mpi::reduce with std::minimum handles unsigned=size_t as signed=long
469 // so use here long to reduce, otherwise leads to a bug
470 using signed_size_type = long;
471 const signed_size_type signed_large = -1;
472 const size_type large = std::numeric_limits<size_type>::max();
473 const T infty = std::numeric_limits<T>::max();
474 // 1) scan x and locate into the local mesh partition ; list when failed
475 distributor ownership = x.ownership();
476 if (dis_ie.ownership() != ownership) dis_ie.resize (ownership);
477 size_type first_dis_i = ownership.first_index();
478 std::list<id_pt_t<T> > failed;
479 for (size_type i = 0, n = x.size(); i < n; i++) {
480 dis_ie[i] = base::_locator.seq_locate (*this, x[i], dis_ie[i]);
481 if (dis_ie[i] == large) {
482 size_type dis_i = first_dis_i + i;
483 failed.push_back (id_pt_t<T>(dis_i, x[i]));
484 }
485 }
486 // 2) merge the failed list into a massive disarray, then distributed to all
487 communicator comm = ownership.comm();
488 distributor fld_ownership (distributor::decide, comm, failed.size());
489 size_type fld_dis_size = fld_ownership.dis_size();
490 if (comm.size() == 1 || fld_dis_size == 0) {
491 // no unsolved, on any procs: nothing to do !
492trace_macro ("locate done(1)");
493 return;
494 }
495 size_type first_fld_dis_i = fld_ownership.first_index();
496 size_type last_fld_dis_i = fld_ownership. last_index();
497 id_pt_t<T> unset (large, point_basic<T>(infty,infty,infty));
498 std::vector<id_pt_t<T> > massive_failed (fld_dis_size, unset);
499 typename std::list<id_pt_t<T> >::iterator iter = failed.begin();
500 for (size_type fld_dis_i = first_fld_dis_i; fld_dis_i < last_fld_dis_i; ++fld_dis_i, ++iter) {
501 massive_failed [fld_dis_i] = *iter;
502 }
503 std::vector<id_pt_t<T> > massive_query (fld_dis_size, unset);
504 mpi::all_reduce (
505 comm,
506 massive_failed.begin().operator->(),
507 massive_failed.size(),
508 massive_query.begin().operator->(),
510
511 // 3) run the locator on all failed points ON ALL PROCS, skipping local queries (already failed)
512 std::vector<signed_size_type> massive_result (fld_dis_size, signed_large);
513 // 3a) range [0:first[
514 for (size_type fld_dis_i = 0; fld_dis_i < first_fld_dis_i; ++fld_dis_i) {
515 massive_result [fld_dis_i] = base::_locator.seq_locate (*this, massive_query[fld_dis_i].second);
516 }
517 // 3b) range [last,dis_size[
518 for (size_type fld_dis_i = last_fld_dis_i; fld_dis_i < fld_dis_size; ++fld_dis_i) {
519 massive_result [fld_dis_i] = base::_locator.seq_locate (*this, massive_query[fld_dis_i].second);
520 }
521 // 4) send & merge the results to all
522 std::vector<signed_size_type> massive_merged (fld_dis_size, signed_large);
523 mpi::all_reduce (
524 comm,
525 massive_result.begin().operator->(),
526 massive_result.size(),
527 massive_merged.begin().operator->(),
528 mpi::maximum<signed_size_type>());
529
530 // 5) store the local range into the distributed disarray dis_ie:
531 for (size_type fld_dis_i = first_fld_dis_i; fld_dis_i < last_fld_dis_i; ++fld_dis_i, ++iter) {
532 size_type dis_i = massive_query [fld_dis_i].first;
533 check_macro (dis_i >= first_dis_i, "invalid index");
534 size_type i = dis_i - first_dis_i;
535 dis_ie[i] = massive_merged [fld_dis_i];
536 if (do_check) {
537 check_macro (dis_ie[i] != large,
538 "dis_locate: failed at x="<<ptos(x[i],base::_dimension));
539 }
540 }
541trace_macro ("locate done(2)");
542}
543#endif // _RHEOLEF_HAVE_MPI
544// ----------------------------------------------------------------------------
545// no CGAL: no locators
546// ----------------------------------------------------------------------------
547#else // _RHEOLEF_HAVE_CGAL
548template <class T, class M>
550{
551}
552template <class T, class M>
555 const geo_base_rep<T,M>& omega,
556 const point_basic<T>& x,
557 size_type dis_ie_guest) const
558{
559 fatal_macro ("geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
560 return 0;
561}
562template <class T, class M>
565 const geo_base_rep<T,M>& omega,
566 const point_basic<T>& x,
567 size_type dis_ie_guest) const
568{
569 fatal_macro ("geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
570 return 0;
571}
572template <class T, class M>
575 const point_basic<T>& x,
576 size_type dis_ie_guest) const
577{
578 fatal_macro ("geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
579 return 0;
580}
581template <class T, class M>
584 const point_basic<T>& x,
585 size_type dis_ie_guest) const
586{
587 fatal_macro ("geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
588 return 0;
589}
590template <class T>
591void
595 bool do_check) const
596{
597 fatal_macro ("geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
598}
599#ifdef _RHEOLEF_HAVE_MPI
600template <class T>
601void
605 // dis_ie(ix) can contains a guest for x in K=omega[dis_ie(ix)]
606 bool do_check) const
607{
608 fatal_macro ("geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
609}
610#endif // _RHEOLEF_HAVE_MPI
611#endif // _RHEOLEF_HAVE_CGAL
612// ----------------------------------------------------------------------------
613// instanciation in library
614// ----------------------------------------------------------------------------
615#define _RHEOLEF_instanciation(T,M) \
616template class geo_locate<Float,M>; \
617template class geo_base_rep<Float,M>; \
618template class geo_rep<Float,M>;
619
621#ifdef _RHEOLEF_HAVE_MPI
622_RHEOLEF_instanciation(Float,distributed)
623#endif // _RHEOLEF_HAVE_MPI
624
625} // namespace rheolef
#define _RHEOLEF_instanciation(T, M, A)
Definition asr.cc:223
field::size_type size_type
Definition branch.cc:430
see the Float page for the full documentation
see the communicator page for the full documentation
see the disarray page for the full documentation
Definition disarray.h:497
rep::base::size_type size_type
Definition disarray.h:501
see the distributor page for the full documentation
Definition distributor.h:69
size_type dis_size() const
global and local sizes
size_type first_index(size_type iproc) const
global index range and local size owned by ip-th process
static const size_type decide
Definition distributor.h:83
base class for M=sequential or distributed meshes representations
Definition geo.h:528
size_type dis_locate(const point_basic< T > &x, size_type dis_ie_guest=std::numeric_limits< size_type >::max()) const
geo_locate< T, M > _locator
Definition geo.h:692
size_type map_dimension() const
Definition geo.h:564
size_type seq_locate(const point_basic< T > &x, size_type dis_ie_guest=std::numeric_limits< size_type >::max()) const
base::size_type size_type
Definition geo.h:533
size_type dimension() const
Definition geo.h:563
const distributor & ownership() const
Definition geo.h:635
const communicator & comm() const
Definition geo.h:637
see the geo_element page for the full documentation
size_type size() const
size_type seq_locate(const geo_base_rep< T, M > &omega, const point_basic< T > &x, size_type dis_ie_guest=std::numeric_limits< size_type >::max()) const
size_type dis_locate(const geo_base_rep< T, M > &omega, const point_basic< T > &x, size_type dis_ie_guest=std::numeric_limits< size_type >::max()) const
static geo_locate_abstract_rep< T, M > * make_ptr(const geo_base_rep< T, M > &omega)
disarray< T, M >::size_type size_type
Definition geo_locate.h:42
geo_locate_abstract_rep< T, M > * _ptr
Definition geo_locate.h:58
base::size_type size_type
Definition geo.h:934
base::size_type size_type
Definition geo.h:791
sequential mesh representation
Definition geo.h:778
#define trace_macro(message)
Definition dis_macros.h:111
#define error_macro(message)
Definition dis_macros.h:49
#define fatal_macro(message)
Definition dis_macros.h:33
Expr1::float_type T
Definition field_expr.h:230
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
bool contains(const geo_element &K, const disarray< point_basic< T >, M > &node, const point_basic< T > &x)
void cgal_make_tree(Tree &tree, Iterator first, Iterator last)
Definition geo_locate.cc:49
This file is part of Rheolef.
void compute_bbox(const geo_base_rep< T, M > &omega, const geo_element &K, point_basic< T > &xmin, point_basic< T > &xmax)
Definition geo_locate.cc:71
void put(std::ostream &out, std::string name, const tiny_matrix< T > &a)
Definition tiny_lu.h:155
std::string ptos(const point_basic< T > &x, int d=3)
Definition point.h:413
CGAL::Filtered_kernel_adaptor< custom_cgal::kernel_2d< T > > Kernel
Definition cgal_traits.h:42
CGAL::Filtered_kernel_adaptor< custom_cgal::kernel_2d< T > > Kernel
Definition cgal_traits.h:46
CGAL::Filtered_kernel_adaptor< custom_cgal::kernel_3d< T > > Kernel
Definition cgal_traits.h:50
static const bool value