31#include "rheolef/geo_locate.h"
32#include "rheolef/geo.h"
33#include "rheolef/geo_element_contains.h"
34#include "rheolef/point_util.h"
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>
43#ifdef _RHEOLEF_HAVE_CGAL
48template <
class Tree,
class Iterator>
51 tree.make_tree (first, last);
53template <
class Traits,
class Iterator>
54inline void cgal_make_tree (CGAL::Segment_tree_1<Traits>& tree, Iterator first, Iterator last)
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);
69template <
class T,
class M>
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();
80 for (size_type iloc = 0, nloc = K.
size(); iloc < nloc; iloc++) {
81 size_type dis_inod = K[iloc];
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]);
89#ifdef _RHEOLEF_HAVE_CGAL
93template <
class Kernel,
class Val>
94class Segment_tree_map_traits_1 {
97 typedef typename Kernel::FT Point_1 ;
99 typedef Point_1 Key_1;
100 typedef std::pair<Key,Key> Pure_interval;
101 typedef std::pair<Pure_interval, Val> Interval;
105 Key_1 operator()(
const Interval& i)
106 {
return i.first.first;}
111 Key_1 operator()(
const Interval& i)
112 {
return i.first.second;}
117 Key_1 operator()(
const Key& k)
123 bool operator()(Key_1 k1, Key_1 k2)
125 return std::less<Float>()(k1,k2);
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;
138template <
class T,
size_t D>
struct cgal_locate_traits {};
141struct cgal_locate_traits<
T,1> {
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;
154 static Pure_interval make_cgal_bbox (
const point_basic<T>& xmin,
const point_basic<T>& xmax)
156 return Pure_interval(Key(xmin[0]),
159 static Pure_interval make_cgal_point_window (
const point_basic<T>& x,
const T& eps)
161 return Pure_interval (Key(x[0]-eps),
164 static void put (std::ostream& out,
const Pure_interval& b) {
165 out <<
"[" <<
b.first <<
"," <<
b.second <<
"[";
169struct cgal_locate_traits<
T,2> {
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;
182 static Pure_interval make_cgal_bbox (
const point_basic<T>& xmin,
const point_basic<T>& xmax)
184 return Pure_interval(Key(xmin[0], xmin[1]),
185 Key(xmax[0], xmax[1]));
187 static Pure_interval make_cgal_point_window (
const point_basic<T>& x,
const T& eps)
189 return Pure_interval (Key(x[0]-eps, x[1]-eps),
190 Key(x[0]+eps, x[1]+eps));
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() <<
"[";
198struct cgal_locate_traits<
T,3> {
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;
211 static Pure_interval make_cgal_bbox (
const point_basic<T>& xmin,
const point_basic<T>& xmax)
213 return Pure_interval(Key(xmin[0], xmin[1], xmin[2]),
214 Key(xmax[0], xmax[1], xmax[2]));
216 static Pure_interval make_cgal_point_window (
const point_basic<T>& x,
const T& eps)
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));
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() <<
"[";
230template <
class T,
class M>
237template <
class T,
class M>
245 return _ptr->seq_locate (omega, x, dis_ie_guest);
247template <
class T,
class M>
255 return _ptr->dis_locate (omega, x, dis_ie_guest);
260template <
class T,
class M>
261class geo_locate_abstract_rep {
264 virtual ~geo_locate_abstract_rep() {}
265 virtual void initialize (
const geo_base_rep<T,M>& omega)
const = 0;
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;
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;
279template <
class T,
class M,
size_t D>
280class geo_locate_rep :
public geo_locate_abstract_rep<T,M> {
287 typedef typename cgal_locate_traits<T,D>::Segment_tree_type Segment_tree_type;
288 typedef typename cgal_locate_traits<T,D>::Interval Interval;
292 geo_locate_rep() : _tree() {}
293 geo_locate_rep(
const geo_base_rep<T,M>& omega) : _tree() { initialize(omega); }
295 void initialize (
const geo_base_rep<T,M>& omega)
const;
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;
310 mutable Segment_tree_type _tree;
315template <
class T,
class M>
316geo_locate_abstract_rep<T,M>*
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));
330template <
class T,
class M,
size_t D>
336 std::list<Interval> boxes;
338 for (size_type ie = 0, ne = omega.size(); ie < ne; ie++) {
341 boxes.push_back (Interval(cgal_locate_traits<T,D>::make_cgal_bbox (xmin,xmax),ie));
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 (
356 size_type dis_ie_guest)
const
358 if (dis_ie_guest != std::numeric_limits<size_type>::max()) {
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;
367 return K_guest.dis_ie();
372 size_type dis_ie = std::numeric_limits<size_type>::max();
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;
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;
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 (
404 size_type dis_ie_guest)
const
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
414 dis_ie = mpi::all_reduce (omega.comm(), signed_size_type(dis_ie), mpi::maximum<signed_size_type>());
424template <
class T,
class M>
430 return _locator.seq_locate (*
this, x, dis_ie_guest);
432template <
class T,
class M>
438 return _locator.dis_locate (*
this, x, dis_ie_guest);
450 dis_ie.resize (x.ownership());
451 for (
size_type i = 0, n = x.size(); i < n; i++) {
454 check_macro (dis_ie[i] != std::numeric_limits<size_type>::max(),
459#ifdef _RHEOLEF_HAVE_MPI
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();
478 std::list<id_pt_t<T> > failed;
479 for (
size_type i = 0, n = x.size(); i < n; i++) {
481 if (dis_ie[i] == large) {
490 if (
comm.size() == 1 || fld_dis_size == 0) {
496 size_type last_fld_dis_i = fld_ownership. last_index();
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;
503 std::vector<id_pt_t<T> > massive_query (fld_dis_size, unset);
506 massive_failed.begin().operator->(),
507 massive_failed.size(),
508 massive_query.begin().operator->(),
512 std::vector<signed_size_type> massive_result (fld_dis_size, signed_large);
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);
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);
522 std::vector<signed_size_type> massive_merged (fld_dis_size, signed_large);
525 massive_result.begin().operator->(),
526 massive_result.size(),
527 massive_merged.begin().operator->(),
528 mpi::maximum<signed_size_type>());
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");
535 dis_ie[i] = massive_merged [fld_dis_i];
548template <
class T,
class M>
552template <
class T,
class M>
555 const geo_base_rep<T,M>& omega,
556 const point_basic<T>& x,
559 fatal_macro (
"geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
562template <
class T,
class M>
567 size_type dis_ie_guest)
const
569 fatal_macro (
"geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
572template <
class T,
class M>
576 size_type dis_ie_guest)
const
578 fatal_macro (
"geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
581template <
class T,
class M>
585 size_type dis_ie_guest)
const
587 fatal_macro (
"geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
597 fatal_macro (
"geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
599#ifdef _RHEOLEF_HAVE_MPI
608 fatal_macro (
"geo: locator not available (HINT: recompile Rheolef with the CGAL library)");
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>;
621#ifdef _RHEOLEF_HAVE_MPI
#define _RHEOLEF_instanciation(T, M, A)
field::size_type size_type
see the Float page for the full documentation
see the communicator page for the full documentation
see the disarray page for the full documentation
rep::base::size_type size_type
see the distributor page for the full documentation
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
base class for M=sequential or distributed meshes representations
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
size_type map_dimension() const
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
size_type dimension() const
const distributor & ownership() const
const communicator & comm() const
see the geo_element page for the full documentation
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
geo_locate_abstract_rep< T, M > * _ptr
base::size_type size_type
base::size_type size_type
sequential mesh representation
#define trace_macro(message)
#define error_macro(message)
#define fatal_macro(message)
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)
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)
void put(std::ostream &out, std::string name, const tiny_matrix< T > &a)
std::string ptos(const point_basic< T > &x, int d=3)
CGAL::Filtered_kernel_adaptor< custom_cgal::kernel_2d< T > > Kernel
CGAL::Filtered_kernel_adaptor< custom_cgal::kernel_2d< T > > Kernel
CGAL::Filtered_kernel_adaptor< custom_cgal::kernel_3d< T > > Kernel