5 #include "../misc/triplet.hpp" 6 #include <boost/foreach.hpp> 7 #include <boost/multiprecision/cpp_dec_float.hpp> 17 void PeriodicGetRidDuplicatesSingle(std::vector<int> &duplicate, std::vector<Vector2D> &toadd)
19 if (duplicate.empty())
21 assert(duplicate.size() == toadd.size());
22 std::vector<size_t> indeces =
sort_index(duplicate);
25 size_t N = duplicate.size();
26 std::vector<double> dx(N, 0);
27 std::vector<size_t> toremove;
28 for (
size_t i = 0; i < N; ++i)
32 for (
size_t i = 1; i < N; ++i)
35 if (duplicate[i] == duplicate[first])
37 for (
size_t j = first; j < i; ++j)
41 if (
fastabs(toadd[j] - toadd[i]) < dxmax*0.1)
43 toremove.push_back(i);
55 void PeriodicGetRidDuplicates(std::vector<int> &duplicate, std::vector<Vector2D> &toadd,
56 std::vector<int>
const& old_duplicate, std::vector<Vector2D>
const& old_toadd,
double Rproc)
58 if (duplicate.empty())
60 assert(duplicate.size() == toadd.size());
61 std::vector<size_t> indeces =
sort_index(duplicate);
64 size_t N = duplicate.size();
65 size_t Nold = old_duplicate.size();
66 std::vector<double> dx(N, 0), dx_old(Nold, 0);
67 std::vector<size_t> toremove;
68 for (
size_t i = 0; i < N; ++i)
70 for (
size_t i = 0; i < Nold; ++i)
71 dx_old[i] =
fastabs(old_toadd[i]);
73 PeriodicGetRidDuplicatesSingle(duplicate, toadd);
77 for (
size_t i = 0; i < N; ++i)
80 size_t index =
static_cast<size_t>(std::lower_bound(old_duplicate.begin(), old_duplicate.end(), duplicate[i])
81 - old_duplicate.begin());
84 for (
size_t j = index; j < Nold; ++j)
86 if (old_duplicate[j] != duplicate[i])
90 if (
fastabs(old_toadd[j] - toadd[i]) < dxmax*0.1)
92 toremove.push_back(i);
102 template<
class T>
bool is_in
106 BOOST_FOREACH(
const T&m, v) {
114 pair<int, int> find_diff(
const facet& f1,
const facet& f2)
129 throw UniversalError(
"Delaunay, Couldn't find difference bewteen two facets");
133 Delaunay::DataOnlyForBuild::DataOnlyForBuild() :copied(vector<vector<char> >())
136 Delaunay::DataOnlyForBuild::DataOnlyForBuild(DataOnlyForBuild
const& other) : copied(other.copied) {}
138 Delaunay::DataOnlyForBuild& Delaunay::DataOnlyForBuild::operator=
139 (DataOnlyForBuild
const& other)
143 copied = other.copied;
149 lastFacet(0), CalcRadius(false),
150 radius(vector<double>()),
151 PointWasAdded(false),
156 olength(0), location_pointer(0), last_loc(0),
157 OrgIndex(vector<int>()),
162 lastFacet(other.lastFacet),
163 CalcRadius(other.CalcRadius),
164 radius(other.radius),
165 PointWasAdded(other.PointWasAdded),
166 last_facet_added(other.last_facet_added),
169 length(other.length),
170 olength(other.olength),
171 location_pointer(other.location_pointer),
172 last_loc(other.last_loc),
173 OrgIndex(other.OrgIndex),
200 vector<double> CellSize(std::vector<std::pair<Vector2D, Vector2D> >
const& points)
202 int n =
static_cast<int>(points.size());
203 double minx = points[0].first.x;
204 double miny = points[0].first.y;
207 for (
int i = 1; i < n; ++i)
209 minx =
min(points[static_cast<size_t>(i)].first.x, minx);
210 miny =
min(points[static_cast<size_t>(i)].first.y, miny);
211 maxx =
max(points[static_cast<size_t>(i)].first.x, maxx);
212 maxy =
max(points[static_cast<size_t>(i)].first.y, maxy);
214 vector<double> res(4);
222 size_t find_index(
facet const& fc,
int i)
224 for (
size_t j = 0; j < 3; ++j)
233 void Delaunay::add_point(
size_t index, stack<std::pair<size_t, size_t> > &flip_stack)
237 const size_t triangle = Walk(index);
240 f[triangle].vertices.set(outer.
third, outer.
first, static_cast<int>(index));
241 f[triangle].neighbors.set(temp_friends.
third,
242 location_pointer + 1,
243 location_pointer + 2);
246 static_cast<int>(index)),
248 location_pointer + 2,
249 static_cast<int>(triangle))));
252 static_cast<int>(index)),
254 static_cast<int>(triangle),
255 location_pointer + 1)));
257 if (temp_friends.
second != last_loc)
259 const size_t i = find_index(f[static_cast<size_t>(temp_friends.
second)], static_cast<int>(triangle));
260 f[
static_cast<size_t>(temp_friends.
second)].neighbors[i] = location_pointer + 2;
262 if (temp_friends.
first != last_loc)
264 const size_t i = find_index(f[static_cast<size_t>(temp_friends.
first)], static_cast<int>(triangle));
265 f[
static_cast<size_t>(temp_friends.
first)].neighbors[i] = location_pointer + 1;
270 radius[
static_cast<size_t>(triangle)] = CalculateRadius(static_cast<int>(triangle));
271 int n = int(f.size());
272 int m = int(radius.size());
275 radius.push_back(CalculateRadius(location_pointer + 1));
276 radius.push_back(CalculateRadius(location_pointer + 2));
281 radius[
static_cast<size_t>(location_pointer) + 1] = CalculateRadius(location_pointer + 1);
282 radius.push_back(CalculateRadius(location_pointer + 2));
286 radius[
static_cast<size_t>(location_pointer) + 1] = CalculateRadius(location_pointer + 1);
287 radius[
static_cast<size_t>(location_pointer) + 2] = CalculateRadius(location_pointer + 2);
292 flip(triangle, static_cast<size_t>(temp_friends.
third), flip_stack);
293 flip(static_cast<size_t>(location_pointer) + 1, static_cast<size_t>(temp_friends.
first), flip_stack);
294 flip(static_cast<size_t>(location_pointer) + 2, static_cast<size_t>(temp_friends.
second), flip_stack);
297 location_pointer += 2;
300 void Delaunay::flip(
size_t i,
size_t j, stack<std::pair<size_t, size_t> > &flip_stack)
302 if (j == static_cast<size_t>(last_loc))
304 flip_stack.push(std::pair<size_t, size_t>(i, j));
305 while (!flip_stack.empty())
307 const pair<size_t, size_t> indexes = flip_stack.top();
309 const pair<int, int> check = find_diff(f[indexes.second],
311 const pair<int, int> other = find_diff(f[indexes.first],
314 facet& prefetch_1 = f[indexes.first];
318 cor[static_cast<size_t>(check.first)]) > 0)
321 const int v1 = prefetch_1.
vertices[
static_cast<size_t>(other.second + 1) % 3];
322 const int f1 = prefetch_1.
neighbors[
static_cast<size_t>(other.second)];
323 const int f12 = prefetch_1.
neighbors[
static_cast<size_t>(other.second + 2) % 3];
324 facet& prefetch_2 = f[indexes.second];
325 const int v2 = prefetch_2.
vertices[
static_cast<size_t>(check.second + 1) % 3];
326 const int f2 = prefetch_2.
neighbors[
static_cast<size_t>(check.second + 2) % 3];
327 const int f22 = prefetch_2.
neighbors[
static_cast<size_t>(check.second)];
328 prefetch_1.
vertices.
set(other.first, v1, check.first);
329 prefetch_2.
vertices.
set(check.first, v2, other.first);
330 prefetch_1.
neighbors.
set(f1, f2, static_cast<int>(indexes.second));
331 prefetch_2.
neighbors.
set(f22, f12, static_cast<int>(indexes.first));
335 f[
static_cast<size_t>(f2)].neighbors[static_cast<size_t>(find_index(f[static_cast<size_t>(f2)], static_cast<int>(indexes.second)))] = static_cast<int>(indexes.first);
339 f[
static_cast<size_t>(f12)].neighbors[static_cast<size_t>(find_index(f[static_cast<size_t>(f12)], static_cast<int>(indexes.first)))] = static_cast<int>(indexes.second);
344 radius[indexes.first] = CalculateRadius(static_cast<int>(indexes.first));
345 radius[indexes.second] = CalculateRadius(static_cast<int>(indexes.second));
351 flip_stack.push(std::pair<size_t, size_t>(indexes.second,
354 flip_stack.push(std::pair<size_t, size_t>(indexes.first,
378 DataOnlyForBuild data;
381 length = int(vp.size() + 3);
382 int len = length - 3;
383 olength =
static_cast<size_t>(len);
386 f.reserve(static_cast<size_t>(2 * length + 1 + static_cast<int>(17 * sqrt(1.*length))));
387 cor.reserve(static_cast<size_t>(length + 9 * static_cast<int>(sqrt(1.*length))));
389 for (
int i = 0; i < len; i++)
391 cor.push_back(vp[static_cast<size_t>(i)]);
396 vector<double> cellsize = CellSize(cpoints);
397 double width = cellsize[1] - cellsize[0];
398 double height = cellsize[3] - cellsize[2];
399 width =
max(width, height);
400 height =
max(width, height);
401 p_temp.
x = cellsize[0] - 100 * width;
402 p_temp.
y = cellsize[2] - 100 * height;
403 cor.push_back(p_temp);
404 p_temp.
x = cellsize[1] + 100 * width;
405 p_temp.
y = cellsize[2] - 100 * height;
406 cor.push_back(p_temp);
407 p_temp.
x = (cellsize[0] + cellsize[1]) / 2.0;
408 p_temp.
y = cellsize[3] + 100 * height;
409 cor.push_back(p_temp);
413 f[0].vertices[0] = len;
414 f[0].vertices[1] = len + 1;
415 f[0].vertices[2] = len + 2;
416 for (
size_t i = 0; i < 3; i++)
417 f[0].neighbors[i] = last_loc;
418 location_pointer = 0;
420 size_t nloop =
static_cast<size_t>(length) - 3;
421 stack<std::pair<size_t, size_t> > flip_stack;
422 for (
size_t i = 0; i < nloop; i++)
423 add_point(i, flip_stack);
425 radius.resize(f.size());
426 int n = int(f.size());
427 for (
int i = 0; i < n; ++i)
428 radius[static_cast<size_t>(i)] = CalculateRadius(i);
433 bool Delaunay::CheckCorrect(
void)
435 std::size_t Ntri = f.size();
436 for (std::size_t i = 0; i < Ntri; ++i)
438 facet const& T = f[i];
439 for (std::size_t j = 0; j < 3; ++j)
445 for (
size_t k = 0; k < 3; ++k)
446 if (f[static_cast<size_t>(T.
neighbors[j])].neighbors[k] == static_cast<int>(i))
451 eo.
AddEntry(
"Facet checked", static_cast<double>(i));
452 eo.
AddEntry(
"Neighbor that is not dual neighbor", static_cast<double>(T.
neighbors[j]));
460 for (
size_t k = 0; k < 3; ++k)
463 for (
size_t l = 0; l < 3; ++l)
474 cor[static_cast<size_t>(T.
vertices[2])], cor[static_cast<size_t>(f[static_cast<size_t>(T.
neighbors[j])].vertices[k])]) > 0)
477 eo.
AddEntry(
"Facet checked", static_cast<double>(i));
478 eo.
AddEntry(
"Point that is inside triangle", static_cast<double>(f[static_cast<size_t>(T.
neighbors[j])].vertices[k]));
494 (cor[static_cast<size_t>(f[static_cast<size_t>(index)].vertices.first)],
495 cor[static_cast<size_t>(f[static_cast<size_t>(index)].vertices.second)],
496 cor[static_cast<size_t>(f[static_cast<size_t>(index)].vertices.third)]);
501 return -0.5*(x1*y2 - x2*y1);
504 void Delaunay::update(
const vector<Vector2D>& points, std::vector<std::pair<Vector2D, Vector2D> >
const& cpoints)
513 int Triplet<int>::* walk_condition(
const vector<Vector2D>& cor,
518 (cor[static_cast<size_t>(vertices.
first)],
519 cor[static_cast<size_t>(vertices.
second)],
523 (cor[static_cast<size_t>(vertices.
second)],
524 cor[static_cast<size_t>(vertices.
third)],
528 (cor[static_cast<size_t>(vertices.
third)],
529 cor[static_cast<size_t>(vertices.
first)],
544 size_t find_new_facet(
const vector<Vector2D>& cor,
545 const vector<facet>& f,
549 size_t res = last_facet;
554 res =
static_cast<size_t>(f[res].neighbors.*next);
555 next = walk_condition(cor,
563 size_t Delaunay::Walk(
size_t point)
565 lastFacet =
static_cast<int>(find_new_facet(cor, f, point, static_cast<size_t>(lastFacet)));
566 return static_cast<size_t>(lastFacet);
569 vector<int> Delaunay::FindContainingTetras(
int StartTetra,
int point)
572 FindContainingTetras(StartTetra, point, res);
576 double Delaunay::FindMaxRadius(
int point)
578 const vector<int> vec = FindContainingTetras(static_cast<int>(Walk(static_cast<size_t>(point))), point);
580 for (
size_t i = 0; i < vec.size(); ++i)
581 r =
max(r, radius[static_cast<size_t>(vec[static_cast<size_t>(i)])]);
585 void Delaunay::FindContainingTetras(
int StartFacet,
int point, vector<int> &result)
588 int PointLocation = FindPointInFacet(StartFacet, point);
589 int NextFacet = f[
static_cast<size_t>(StartFacet)].neighbors[static_cast<size_t>(PointLocation)];
591 result.push_back(NextFacet);
592 while (NextFacet != StartFacet)
594 PointLocation = FindPointInFacet(NextFacet, point);
595 NextFacet = f[
static_cast<size_t>(NextFacet)].neighbors[static_cast<size_t>(PointLocation)];
596 result.push_back(NextFacet);
600 int Delaunay::FindPointInFacet(
int facet,
int point)
602 for (
int i = 0; i < 3; ++i)
603 if (f[static_cast<size_t>(facet)].vertices[static_cast<size_t>(i)] == point)
611 bool Delaunay::IsOuterFacet(
int facet)
const 614 for (
int i = 0; i < 3; ++i)
615 for (
size_t j = 0; j < 3; ++j)
616 if (f[static_cast<size_t>(facet)].vertices[static_cast<size_t>(i)] == static_cast<int>(olength + j))
621 double Delaunay::CalculateRadius(
int facet)
639 double Delaunay::CalcRadiusHiRes(
int facet)
641 std::array<boost::multiprecision::cpp_dec_float_50, 2> V0,V1,V2;
642 V0[0] = cor[
static_cast<size_t>(f[
static_cast<size_t>(facet)].vertices[0])].x;
643 V0[1] = cor[
static_cast<size_t>(f[
static_cast<size_t>(facet)].vertices[0])].y;
644 V1[0] = cor[
static_cast<size_t>(f[
static_cast<size_t>(facet)].vertices[1])].x;
645 V1[1] = cor[
static_cast<size_t>(f[
static_cast<size_t>(facet)].vertices[1])].y;
646 V2[0] = cor[
static_cast<size_t>(f[
static_cast<size_t>(facet)].vertices[2])].x;
647 V2[1] = cor[
static_cast<size_t>(f[
static_cast<size_t>(facet)].vertices[2])].y;
649 boost::multiprecision::cpp_dec_float_50 a = boost::multiprecision::sqrt((V0[0] - V1[0])*(V0[0] - V1[0]) + (V0[1] - V1[1])*(V0[1] - V1[1]));
650 boost::multiprecision::cpp_dec_float_50 b = boost::multiprecision::sqrt((V0[0] - V2[0])*(V0[0] - V2[0]) + (V0[1] - V2[1])*(V0[1] - V2[1]));
651 boost::multiprecision::cpp_dec_float_50 c = boost::multiprecision::sqrt((V2[0] - V1[0])*(V2[0] - V1[0]) + (V2[1] - V1[1])*(V2[1] - V1[1]));
653 boost::multiprecision::cpp_dec_float_50 temp1 = b + c - a;
654 boost::multiprecision::cpp_dec_float_50 temp2 = -b + c + a;
655 boost::multiprecision::cpp_dec_float_50 temp3 = b - c - a;
656 boost::multiprecision::cpp_dec_float_50 temp4 = a + b + c;
657 temp4 = a * b*c / boost::multiprecision::sqrt(temp4*temp1*temp2*temp3);
658 return (temp4).convert_to<
double>();
668 return radius[
static_cast<size_t>(facet)];
673 olength =
static_cast<size_t>(n);
693 return f[
static_cast<size_t>(index)];
699 return cor[
static_cast<size_t>(f[
static_cast<size_t>(Facet)].vertices[static_cast<size_t>(vertice)])].x;
701 return cor[
static_cast<size_t>(f[
static_cast<size_t>(Facet)].vertices[static_cast<size_t>(vertice)])].y;
712 return cor[
static_cast<size_t>(index)].x;
714 return cor[
static_cast<size_t>(index)].y;
716 throw UniversalError(
"Error in Delaunay::get_cor. Invalid index");
721 return static_cast<int>(f.size());
736 cor[
static_cast<size_t>(index)] = p;
741 return static_cast<int>(olength);
751 return static_cast<int>(cor.size());
756 int n =
static_cast<int>(points.size());
757 int N =
static_cast<int>(cor.size());
758 stack<std::pair<size_t, size_t> > flip_stack;
760 cor.insert(cor.end(), points.begin(), points.end());
762 for (
int i = 0; i < n; ++i)
763 if(InTriangle(OuterTri,cor[static_cast<size_t>(N + i)]))
764 add_point(static_cast<size_t>(N + i), flip_stack);
774 return static_cast<int>(cor.size());
777 bool Delaunay::IsTripleOut(
int index)
const 780 for (
size_t i = 0; i < 3; ++i)
781 if (IsOuterFacet(f[static_cast<size_t>(index)].neighbors[static_cast<size_t>(i)]))
789 int Delaunay::FindTripleLoc(facet
const& fct)
const 791 for (
size_t i = 0; i < 3; ++i)
792 if (!IsOuterFacet(fct.
neighbors[static_cast<size_t>(i)]))
793 return static_cast<int>((i + 1) % 3);
794 throw UniversalError(
"Trouble in constructing boundary triangles. No inner neighbor");
799 bool IsOuterQuick(facet
const& f,
int olength)
801 for (
size_t i = 0; i < 3; ++i)
802 if (f.
vertices[static_cast<size_t>(i)] >= olength)
807 bool IsEdgeFacet(vector<facet>
const& facets, facet
const& f,
int olength)
810 for (
size_t i = 0; i < 3; ++i)
812 if (f.
vertices[static_cast<size_t>(i)] >= olength)
814 if (IsOuterQuick(facets[static_cast<size_t>(f.
neighbors[static_cast<size_t>(i)])], olength))
823 bool CircleSegmentIntersect(
Edge const& edge,
Vector2D const& center,
double R)
835 double LAB =
abs(AB);
844 if (
abs(center - closest) > R)
851 vector<int> Delaunay::GetOuterFacets(
int start_facet,
int real_point,
int olength2)
853 int cur_facet = start_facet;
854 vector<int> f_temp, containing_facets;
855 f_temp.reserve(static_cast<size_t>(10 * sqrt(1.0*olength2)));
856 int point_index = FindPointInFacet(cur_facet, real_point);
857 if (IsOuterQuick(f[static_cast<size_t>(f[static_cast<size_t>(cur_facet)].neighbors[static_cast<size_t>(point_index)])], olength2))
859 point_index = (point_index + 1) % 3;
860 real_point = f[
static_cast<size_t>(cur_facet)].vertices[static_cast<size_t>(point_index)];
862 if (IsOuterQuick(f[static_cast<size_t>(f[static_cast<size_t>(cur_facet)].neighbors[static_cast<size_t>(point_index)])], olength2))
864 point_index = (point_index + 1) % 3;
865 real_point = f[
static_cast<size_t>(cur_facet)].vertices[static_cast<size_t>(point_index)];
869 FindContainingTetras(cur_facet, real_point, containing_facets);
870 int old_current = cur_facet;
871 for (
size_t i = 0; i < containing_facets.size(); ++i)
873 if (IsEdgeFacet(f, f[static_cast<size_t>(containing_facets[static_cast<size_t>(i)])], olength2) &&
874 containing_facets[
static_cast<size_t>(i)] != old_current)
875 cur_facet = containing_facets[
static_cast<size_t>(i)];
876 if (!IsOuterQuick(f[static_cast<size_t>(containing_facets[static_cast<size_t>(i)])], olength2))
877 f_temp.push_back(containing_facets[static_cast<size_t>(i)]);
879 point_index = (1 + FindPointInFacet(cur_facet, real_point)) % 3;
880 if (IsTripleOut(cur_facet))
881 point_index = (point_index + 1) % 3;
882 real_point = f[
static_cast<size_t>(cur_facet)].vertices[static_cast<size_t>(point_index)];
883 }
while (start_facet != cur_facet);
884 sort(f_temp.begin(), f_temp.end());
891 vector<int> range(
int len)
893 vector<int> res(static_cast<size_t>(len));
894 for(
int i=0;i<len;++i)
895 res.at(static_cast<size_t>(i)) = i;
899 vector<vector<int> > replicate_all_points(
const vector<Edge>& edges,
902 vector<vector<int> > res(edges.size());
903 const vector<int> my_range = range(static_cast<int>(olength));
904 for(
size_t i=0;i<edges.size(); ++i)
905 res.at(i) = my_range;
912 void clean_toduplicate(vector<vector<int> >& toduplicate)
914 for(
size_t i=0;i<toduplicate.size();++i){
915 sort(toduplicate.at(i).begin(),
916 toduplicate.at(i).end());
917 toduplicate.at(i) =
unique(toduplicate.at(i));
922 vector<vector<int> > Delaunay::FindOuterPoints(vector<Edge>
const& edges)
925 return replicate_all_points(edges, olength);
928 vector<vector<int> > toduplicate(edges.size());
930 int cur_facet =
static_cast<int>(Walk(olength));
931 vector<bool> checked(f.size(),
false);
932 AddOuterFacets(cur_facet, toduplicate, edges, checked);
934 clean_toduplicate(toduplicate);
938 void Delaunay::AddPeriodicMPI(std::vector<int> &toduplicate, std::vector<Vector2D> &periodic_add)
940 assert(periodic_add.size() == toduplicate.size());
941 std::vector<int> toremove;
942 std::vector<Vector2D> toadd;
943 for (
size_t j = 0; j < toduplicate.size(); ++j)
945 Vector2D temp = cor[
static_cast<size_t>(toduplicate[j])] + periodic_add[j];
947 (cor[static_cast<size_t>(olength)],
948 cor[static_cast<size_t>(olength + 1)],
949 cor[static_cast<size_t>(olength + 2)]),
951 toadd.push_back(temp);
953 toremove.push_back(static_cast<int>(j));
962 eo.
AddEntry(
"Error in AddRigid", 0);
967 void Delaunay::AddRigid(vector<Edge>
const& edges,
968 vector<vector<int> > &toduplicate)
970 vector<int> toremove;
971 for (
size_t i = 0; i < edges.size(); ++i)
974 if (toduplicate[i].empty())
976 vector<Vector2D> toadd;
977 toadd.reserve(toduplicate[i].size());
979 par = par /
abs(par);
980 for (
size_t j = 0; j < toduplicate[i].size(); ++j)
982 Vector2D temp = cor[
static_cast<size_t>(toduplicate[i][j])] - edges[i].vertices.first;
983 temp = 2 * par*
ScalarProd(par, temp) - temp + edges[i].vertices.first;
985 (cor[static_cast<size_t>(olength)],
986 cor[static_cast<size_t>(olength + 1)],
987 cor[static_cast<size_t>(olength + 2)]),
989 toadd.push_back(temp);
991 toremove.push_back(static_cast<int>(j));
1000 eo.
AddEntry(
"Error in AddRigid", 0);
1029 vector<vector<int> > Delaunay::AddPeriodic(
OuterBoundary const* obc, vector<Edge>
const& edges,
1030 vector<vector<int> > &toduplicate)
1034 for (
size_t i = 0; i < edges.size(); ++i)
1036 if (toduplicate[static_cast<size_t>(i)].empty())
1054 vector<Vector2D> toadd;
1055 toadd.reserve(toduplicate[static_cast<size_t>(i)].size());
1057 for (
size_t j = 0; j < toduplicate[static_cast<size_t>(i)].size(); ++j)
1059 toadd.push_back(cor[static_cast<size_t>(toduplicate[static_cast<size_t>(i)][static_cast<size_t>(j)])] + change);
1062 vector<int> order =
HilbertOrder(toadd, static_cast<int>(toadd.size()));
1069 vector<Edge> corneredges = GetCornerEdges(obc);
1070 vector<vector<int> > corners(toduplicate.size());
1071 for (
size_t i = 0; i < toduplicate.size(); ++i)
1073 for (
size_t j = 0; j < toduplicate[static_cast<size_t>(i)].size(); ++j)
1075 const int facet_loc =
static_cast<int>(Walk(static_cast<size_t>(toduplicate[static_cast<size_t>(i)][static_cast<size_t>(j)])));
1076 const Vector2D center = cor[
static_cast<size_t>(toduplicate[
static_cast<size_t>(i)][static_cast<size_t>(j)])];
1077 const double R = 2 * GetMaxRadius(toduplicate[static_cast<size_t>(i)][static_cast<size_t>(j)], facet_loc);
1078 if (CircleSegmentIntersect(corneredges[2 * static_cast<size_t>(i)], center, R))
1079 corners[
static_cast<size_t>(i)].push_back(toduplicate[static_cast<size_t>(i)][
static_cast<size_t>(j)]);
1080 if (CircleSegmentIntersect(corneredges[(2 * static_cast<size_t>(i) + 7) % 8], center, R))
1081 corners[(
static_cast<size_t>(i) + 3) % 4].push_back(toduplicate[static_cast<size_t>(i)][static_cast<size_t>(j)]);
1084 for (
size_t i = 0; i < corners.size(); ++i)
1086 if (corners[static_cast<size_t>(i)].empty())
1088 sort(corners[static_cast<size_t>(i)].begin(), corners[static_cast<size_t>(i)].end());
1089 corners[
static_cast<size_t>(i)] =
unique(corners[static_cast<size_t>(i)]);
1110 vector<Vector2D> toadd;
1111 toadd.reserve(corners[static_cast<size_t>(i)].size());
1113 for (
size_t j = 0; j < corners[static_cast<size_t>(i)].size(); ++j)
1115 toadd.push_back(cor[static_cast<size_t>(corners[static_cast<size_t>(i)][static_cast<size_t>(j)])] + change);
1123 void Delaunay::AddHalfPeriodic(
OuterBoundary const* obc, vector<Edge>
const& edges,
1124 vector<vector<int> > &toduplicate)
1128 for (
size_t i = 0; i < edges.size(); ++i)
1130 if (toduplicate[static_cast<size_t>(i)].empty())
1146 vector<Vector2D> toadd;
1147 toadd.reserve(toduplicate[static_cast<size_t>(i)].size());
1150 par = par /
abs(par);
1151 for (
size_t j = 0; j < toduplicate[static_cast<size_t>(i)].size(); ++j)
1153 Vector2D temp = cor[
static_cast<size_t>(toduplicate[
static_cast<size_t>(i)][static_cast<size_t>(j)])];
1156 temp -= edges[
static_cast<size_t>(i)].vertices.first;
1157 temp = 2 * par*
ScalarProd(par, temp) - temp + edges[
static_cast<size_t>(i)].vertices.first;
1159 toadd.push_back(temp + change);
1169 vector<vector<int> > toduplicate = FindOuterPoints(edges);
1173 AddRigid(edges, toduplicate);
1179 vector<vector<int> > corners = AddPeriodic(obc, edges, toduplicate);
1180 for (
size_t i = 0; i < 4; ++i)
1181 toduplicate.push_back(corners[static_cast<size_t>(i)]);
1183 for (
size_t i = 0; i < toduplicate.size(); ++i)
1184 for (
size_t j = 0; j < toduplicate[i].size(); ++j)
1185 OrgIndex.push_back(toduplicate[i][j]);
1190 AddHalfPeriodic(obc, edges, toduplicate);
1193 for (
size_t i = 0; i < toduplicate.size(); ++i)
1194 for (
size_t j = 0; j < toduplicate[i].size(); ++j)
1195 OrgIndex.push_back(toduplicate[i][j]);
1196 radius.resize(f.size());
1197 int n = int(f.size());
1198 for (
int i = 0; i < n; ++i)
1199 radius[static_cast<size_t>(i)] = CalculateRadius(i);
1205 facet
const& F = f[
static_cast<size_t>(index)];
1206 double x1 = cor[
static_cast<size_t>(F.
vertices[0])].x;
1207 double y1 = cor[
static_cast<size_t>(F.
vertices[0])].y;
1208 double x2 = cor[
static_cast<size_t>(F.
vertices[1])].x;
1209 double y2 = cor[
static_cast<size_t>(F.
vertices[1])].y;
1210 double x3 = cor[
static_cast<size_t>(F.
vertices[2])].x;
1211 double y3 = cor[
static_cast<size_t>(F.
vertices[2])].y;
1214 double d12 = (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2);
1215 double d23 = (x3 - x2)*(x3 - x2) + (y3 - y2)*(y3 - y2);
1216 double d13 = (x1 - x3)*(x1 - x3) + (y1 - y3)*(y1 - y3);
1218 double small = 1e-10;
1219 double d_inv = (2 * ((x2-x1)*(y3-y1) - (y2-y1) * (x3-x1)));
1220 if (d12 < (small*maxv) || d23 < (small*maxv) || d13 < (small*maxv) ||
std::abs(d_inv) <small*maxv)
1222 std::array<boost::multiprecision::cpp_dec_float_50, 2> V1,V2, V3;
1233 boost::multiprecision::cpp_dec_float_50 d = 2 * (V2[0] * V3[1] - V2[1] * V3[0]);
1234 boost::multiprecision::cpp_dec_float_50 r_x = (V3[1] * (V2[1] * V2[1] + V2[0] * V2[0]) - V2[1] * (V3[0] * V3[0] + V3[1] * V3[1])) / d;
1235 boost::multiprecision::cpp_dec_float_50 r_y = (-V3[0] * (V2[1] * V2[1] + V2[0] * V2[0]) + V2[0] * (V3[0] * V3[0] + V3[1] * V3[1])) / d;
1236 R = boost::multiprecision::sqrt(r_x*r_x + r_y * r_y).convert_to<
double>();
1237 center.
Set(r_x.convert_to<
double>() + x1, r_y.convert_to<
double>() + y1);
1241 d_inv = 1.0 / d_inv;
1246 double x = (y3*(x2*x2 + y2 * y2) - y2 * (x3*x3 + y3 * y3))*d_inv;
1247 double y = (-x3 * (x2*x2 + y2 * y2) + x2 * (x3*x3 + y3 * y3))*d_inv;
1248 R = std::sqrt(x*x + y * y);
1249 center.
Set(x + x1,y + y1);
1254 double Delaunay::GetMaxRadius(
int point,
int startfacet)
1257 vector<int> neigh = FindContainingTetras(startfacet, point);
1258 for (
size_t i = 0; i < neigh.size(); ++i)
1259 res =
max(res, radius[static_cast<size_t>(neigh[static_cast<size_t>(i)])]);
1263 void Delaunay::AddOuterFacets(
int tri, vector<vector<int> > &toduplicate,
1264 vector<Edge>
const& edges, vector<bool> &checked)
1268 while (!tocheck.empty())
1270 int cur_facet = tocheck.top();
1272 for (
size_t i = 0; i < 3; ++i)
1275 if (checked[static_cast<size_t>(f[static_cast<size_t>(cur_facet)].vertices[static_cast<size_t>(i)])] || (f[static_cast<size_t>(cur_facet)].vertices[static_cast<size_t>(i)] >= static_cast<int>(olength)))
1277 vector<int> neigh = FindContainingTetras(cur_facet, f[static_cast<size_t>(cur_facet)].vertices[static_cast<size_t>(i)]);
1278 for (
size_t k = 0; k < neigh.size(); ++k)
1282 for (
size_t l = 0; l < edges.size(); ++l)
1284 if (CircleSegmentIntersect(edges[static_cast<size_t>(l)], center, R))
1286 toduplicate[
static_cast<size_t>(l)].push_back(f[static_cast<size_t>(cur_facet)].vertices[
static_cast<size_t>(i)]);
1291 checked[
static_cast<size_t>(f[
static_cast<size_t>(cur_facet)].vertices[static_cast<size_t>(i)])] =
true;
1294 for (
size_t j = 0; j < neigh.size(); ++j)
1295 tocheck.push(neigh[static_cast<size_t>(j)]);
1302 int Delaunay::findSomeOuterPoint(
void)
1304 const size_t cur_facet = Walk(olength);
1305 for (
size_t i = 0; i < 3; ++i) {
1306 const int candidate = f.at(cur_facet).vertices[i];
1307 if (candidate < static_cast<int>(olength))
1312 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1313 std::cout <<
"Problem with rank " << rank <<
" chcked facet "<<cur_facet<<
" olength " 1314 <<olength<< std::endl;
1317 assert(
false &&
"something went wrong");
1323 calc_neighbors_own_edges
1325 const vector<Edge>& edge_list,
bool periodic)
1329 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1330 BOOST_FOREACH(
const Edge& edge, edge_list)
1334 res.push_back(other);
1341 std::sort(res.begin(), res.end());
1348 stack<int> initialise_tocheck
1349 (
const vector<int>& neightemp)
1352 for (
size_t i = 0; i < neightemp.size(); ++i)
1353 res.push(neightemp[i]);
1357 vector<int> calc_self_intersection
1358 (
const vector<Edge>& edge_list,
1362 for (
size_t i = 0; i < edge_list.size(); ++i) {
1363 const Edge& edge = edge_list.at(i);
1365 res.push_back(static_cast<int>(i));
1371 vector<vector<int> > Delaunay::AddOuterFacetsMPI
1373 vector<vector<int> > &toduplicate,
1375 vector<bool> &checked,
1377 const vector<Edge>& own_edges,
1378 bool periodic, std::vector<Vector2D> &periodic_add_self,
1379 std::vector<std::vector<Vector2D> >& periodic_add_others,
Vector2D const &ll,
Vector2D const &ur,
bool recursive)
1382 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1383 double procsize = tproc.
GetWidth(rank);
1384 vector<vector<int> > res;
1386 std::vector<Vector2D> toadd;
1390 res.resize(own_edges.size());
1397 stack<int> tocheck = initialise_tocheck(FindContainingTetras(static_cast<int>(Walk(static_cast<size_t>(point))),
1401 vector<int> allouter;
1402 for (
size_t i = 0; i < toduplicate.size(); ++i)
1404 for (
size_t j = 0; j < toduplicate[i].size(); ++j)
1406 vector<int> temp = FindContainingTetras
1407 (static_cast<int>(Walk(static_cast<size_t>(toduplicate[i][j]))), toduplicate[i][j]);
1408 for (
size_t k = 0; k < temp.size(); ++k)
1409 allouter.push_back(temp[k]);
1412 sort(allouter.begin(), allouter.end());
1413 allouter =
unique(allouter);
1414 for (
size_t i = 0; i < allouter.size(); ++i)
1415 tocheck.push(allouter[i]);
1417 while (!tocheck.empty())
1419 int cur_facet = tocheck.top();
1421 for (
size_t i = 0; i < 3; ++i)
1425 if (f[static_cast<size_t>(cur_facet)].vertices[i] >= static_cast<int>(olength))
1427 if (checked[static_cast<size_t>(f[static_cast<size_t>(cur_facet)].vertices[i])])
1429 vector<int> neighs = FindContainingTetras(cur_facet, f[static_cast<size_t>(cur_facet)].vertices[i]);
1433 for (
size_t k = 0; k < neighs.size(); ++k)
1437 vector<int> cputosendto;
1445 sort(cputosendto.begin(), cputosendto.end());
1446 cputosendto =
unique(cputosendto);
1449 if (periodic && recursive)
1451 if (!cputosendto.empty())
1453 std::vector<int> toremove2;
1454 for (
size_t l = 0; l < cputosendto.size(); ++l)
1455 if (cputosendto[l] == rank &&
fastabs(toadd[l]) < 0.01*procsize)
1456 toremove2.push_back(static_cast<int>(l));
1465 const vector<int> self_intersection = calc_self_intersection(own_edges, circ);
1466 if (!self_intersection.empty())
1468 BOOST_FOREACH(
int sindex, self_intersection)
1469 res[
static_cast<size_t>(sindex)].push_back(f[static_cast<size_t>(cur_facet)].vertices[i]);
1474 for (
size_t jj = 0; jj < 3; ++jj)
1475 max_neigh =
max(max_neigh, f[static_cast<size_t>(neighs[k])].vertices[jj]);
1477 if (!cputosendto.empty())
1480 for (
size_t j = 0; j < cputosendto.size(); ++j)
1482 if (cputosendto[j] == rank)
1484 res[0].push_back(f[static_cast<size_t>(cur_facet)].vertices[i]);
1485 periodic_add_self.push_back(toadd[j]);
1488 size_t index =
static_cast<size_t>(std::find(neigh.begin(), neigh.end(), cputosendto[j])
1490 if (index < neigh.size())
1492 toduplicate.at(index).push_back(f[static_cast<size_t>(cur_facet)].vertices[i]);
1494 periodic_add_others.at(index).push_back(toadd[j]);
1498 neigh.push_back(cputosendto[j]);
1499 toduplicate.push_back(vector<int>(1, f[static_cast<size_t>(cur_facet)].vertices[i]));
1501 periodic_add_others.push_back(vector<Vector2D>(1, toadd[j]));
1506 checked[
static_cast<size_t>(f[
static_cast<size_t>(cur_facet)].vertices[i])] =
true;
1507 if (added || (recursive&&static_cast<size_t>(max_neigh) >= olength))
1509 for (
size_t j = 0; j < neighs.size(); ++j)
1510 tocheck.push(neighs[j]);
1517 pair<vector<vector<int> >, vector<vector<int> > > Delaunay::findOuterPoints(
const Tessellation& t_proc,
1518 const vector<Edge>& edge_list,
const vector<Edge>& box_edges, vector<vector<int> > &NghostIndex,
bool periodic,
1519 std::vector<int> &cpu_neigh, std::vector<Vector2D> &periodic_add_self, std::vector<std::vector<Vector2D> >
1522 cpu_neigh = calc_neighbors_own_edges(t_proc, edge_list, periodic);
1523 const size_t some_outer_point = findSomeOuterPoint();
1524 vector<vector<int> > to_duplicate(cpu_neigh.size());
1525 periodic_add_others.resize(to_duplicate.size());
1526 vector<bool> checked(olength,
false);
1527 vector<vector<int> > self_points =
1529 (static_cast<int>(some_outer_point),
1534 box_edges, periodic, periodic_add_self, periodic_add_others,ll,ur);
1536 PeriodicGetRidDuplicatesSingle(self_points[0], periodic_add_self);
1537 for (
size_t i = 0; i < to_duplicate.size(); ++i)
1539 std::vector<size_t> sindex =
sort_index(to_duplicate[i]);
1540 to_duplicate[i] =
VectorValues(to_duplicate[i], sindex);
1543 periodic_add_others[i] =
VectorValues(periodic_add_others[i], sindex);
1544 PeriodicGetRidDuplicatesSingle(to_duplicate[i], periodic_add_others[i]);
1547 to_duplicate[i] =
unique(to_duplicate[i]);
1556 vector<vector<Vector2D> > incoming(cpu_neigh.size());
1557 vector<MPI_Request> req(cpu_neigh.size());
1558 vector<vector<double> > tosend(cpu_neigh.size());
1560 for (
size_t i = 0; i < cpu_neigh.size(); ++i)
1562 const int dest = cpu_neigh[i];
1563 std::vector<Vector2D> cortosend =
VectorValues(cor, to_duplicate[i]);
1566 for (
size_t j = 0; j < cortosend.size(); ++j)
1567 cortosend[j] += periodic_add_others[i][j];
1569 tosend[i] = list_serialize(cortosend);
1570 int size =
static_cast<int>(tosend[i].size());
1572 MPI_Isend(&dtemp, 1, MPI_DOUBLE, dest, 1, MPI_COMM_WORLD, &req[i]);
1577 MPI_Isend(&tosend[i][0], size, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD, &req[i]);
1580 for (
size_t i = 0; i < cpu_neigh.size(); ++i)
1582 vector<double> temprecv;
1584 MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1586 MPI_Get_count(&status, MPI_DOUBLE, &count);
1587 temprecv.resize(static_cast<size_t>(
max(count, 1)));
1588 MPI_Recv(&temprecv[0], count, MPI_DOUBLE, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
1589 if (status.MPI_TAG == 0)
1591 size_t location =
static_cast<size_t>(std::find(cpu_neigh.begin(), cpu_neigh.end(),
1592 status.MPI_SOURCE) - cpu_neigh.begin());
1593 if (location >= cpu_neigh.size())
1597 incoming[location] = list_unserialize(temprecv, cor[0]);
1601 eo.
AddEntry(
"Error in first send in triangulation", 0.0);
1606 if (status.MPI_TAG != 1)
1610 MPI_Waitall(static_cast<int>(req.size()), &req[0], MPI_STATUSES_IGNORE);
1614 for (
size_t i = 0; i < self_points.size(); ++i)
1616 std::vector<int> sindex;
1622 AddRigid(box_edges, self_points);
1626 std::vector<size_t> indeces =
sort_index(self_points[0]);
1627 self_points[0] =
VectorValues(self_points[0], indeces);
1628 periodic_add_self =
VectorValues(periodic_add_self, indeces);
1629 AddPeriodicMPI(self_points[0], periodic_add_self);
1631 for (
size_t i = 0; i < self_points.size(); ++i)
1632 for (
size_t j = 0; j < self_points[i].size(); ++j)
1633 OrgIndex.push_back(self_points[i][j]);
1635 NghostIndex.clear();
1636 NghostIndex.resize(incoming.size());
1637 for (
size_t i = 0; i < incoming.size(); ++i)
1639 for (
size_t j = 0; j < incoming.at(i).size(); ++j)
1641 OrgIndex.push_back(static_cast<int>(cor.size() + j));
1642 NghostIndex[i].push_back(static_cast<int>(cor.size() + j));
1646 MPI_Barrier(MPI_COMM_WORLD);
1647 return std::pair<vector<vector<int> >, vector<vector<int> > >
1648 (to_duplicate, self_points);
1651 vector<vector<int> > Delaunay::boundary_intersection_check(
const vector<Edge>& edges,
const vector<vector<int> >& to_duplicate)
1653 vector<vector<int> > res;
1654 res.reserve(edges.size());
1657 BOOST_FOREACH(
const Edge& edge, edges) {
1658 res.push_back(vector<int>());
1659 BOOST_FOREACH(
const vector<int>& line, to_duplicate) {
1660 BOOST_FOREACH(
const int index, line)
1666 res.back().push_back(index);
1673 pair<vector<vector<int> >, vector<int> > Delaunay::FindOuterPoints2
1675 const vector<Edge>& edge_list,
1676 vector<vector<int> > &to_duplicate,
1677 vector<vector<int> >& self_points,
1678 const vector<Edge>& box_edges,
1679 vector<vector<int> > &NghostIndex,
1681 std::vector<int> &cpu_neigh, std::vector<Vector2D> &periodic_add_self, std::vector<std::vector<Vector2D> >
1684 vector<vector<int> > real_boundary_points(box_edges.size());
1687 const vector<vector<int> > boundary_points = boundary_intersection_check(box_edges, to_duplicate);
1688 for (
size_t i = 0; i < boundary_points.size(); ++i)
1690 sort(self_points.at(i).begin(), self_points.at(i).end());
1691 BOOST_FOREACH(
int bp, boundary_points.at(i))
1693 if (!binary_search(self_points.at(i).begin(),
1694 self_points.at(i).end(),
1697 real_boundary_points.at(i).push_back(bp);
1700 sort(real_boundary_points.at(i).begin(),
1701 real_boundary_points.at(i).end());
1702 real_boundary_points.at(i) =
unique(real_boundary_points.at(i));
1707 for (
size_t i = 0; i < self_points.size(); ++i)
1709 std::vector<size_t> sindex =
sort_index(self_points[i]);
1711 periodic_add_self =
VectorValues(periodic_add_self, sindex);
1715 vector<vector<int> > to_duplicate_2 = to_duplicate;
1716 vector<int> old_neighbors = cpu_neigh;
1718 vector<bool> checked(olength,
false);
1719 size_t some_outer_point = 0;
1720 if (!to_duplicate.empty())
1722 if (!to_duplicate[0].empty())
1723 some_outer_point = to_duplicate[0][0];
1725 some_outer_point = self_points.at(0).at(0);
1728 some_outer_point = self_points.at(0).at(0);
1730 std::vector<Vector2D> periodic_add_self2;
1731 std::vector<std::vector<Vector2D> > periodic_add_others2(periodic_add_others);
1732 std::vector<std::vector<int> > self_send = AddOuterFacetsMPI
1733 (static_cast<int>(some_outer_point),
1741 periodic_add_others2,ll,ur,
true);
1745 MPI_Comm_size(MPI_COMM_WORLD, &wsize);
1746 vector<int> totalk(static_cast<size_t>(wsize), 0);
1747 vector<int> scounts(totalk.size(), 1);
1748 for (
size_t i = 0; i < cpu_neigh.size(); ++i)
1749 totalk[cpu_neigh[i]] = 1;
1751 MPI_Reduce_scatter(&totalk[0], &nrecv, &scounts[0], MPI_INT, MPI_SUM,
1754 vector<MPI_Request> req(cpu_neigh.size());
1755 for (
size_t i = 0; i < cpu_neigh.size(); ++i)
1756 MPI_Isend(&wsize, 1, MPI_INT, cpu_neigh[i], 3, MPI_COMM_WORLD, &req[i]);
1757 vector<int> talkwithme;
1758 for (
int i = 0; i < nrecv; ++i)
1761 MPI_Recv(&wsize, 1, MPI_INT, MPI_ANY_SOURCE, 3, MPI_COMM_WORLD, &status);
1762 talkwithme.push_back(status.MPI_SOURCE);
1764 vector<size_t> indices;
1765 for (
size_t i = 0; i < cpu_neigh.size(); ++i)
1767 if (is_in(cpu_neigh[i], talkwithme))
1768 indices.push_back(i);
1775 periodic_add_others2 =
VectorValues(periodic_add_others2, indices);
1778 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1779 for (
size_t i = 0; i < to_duplicate.size(); ++i)
1783 if (i < to_duplicate_2.size())
1784 PeriodicGetRidDuplicates(to_duplicate[i], periodic_add_others2[i], to_duplicate_2[i], periodic_add_others[i],t_proc.
GetWidth(rank));
1786 PeriodicGetRidDuplicatesSingle(to_duplicate[i], periodic_add_others2[i]);
1790 sort(to_duplicate[i].begin(), to_duplicate[i].end());
1791 to_duplicate[i] =
unique(to_duplicate[i]);
1794 vector<vector<int> > messages(to_duplicate.size());
1797 for (
size_t i = 0; i < to_duplicate.size(); ++i)
1799 const vector<int>::const_iterator it = find(old_neighbors.begin(), old_neighbors.end(), cpu_neigh.at(i));
1800 for (
size_t j = 0; j < to_duplicate.at(i).size(); ++j)
1802 if (it != old_neighbors.end())
1804 const size_t my_index =
static_cast<size_t>(it - old_neighbors.begin());
1805 if (!binary_search(to_duplicate_2.at(my_index).begin(), to_duplicate_2.at(my_index).end(),
1806 to_duplicate.at(i).at(j)))
1807 messages.at(i).push_back(to_duplicate.at(i).at(j));
1810 messages.at(i).push_back(to_duplicate.at(i).at(j));
1815 MPI_Waitall(static_cast<int>(cpu_neigh.size()), &req[0], MPI_STATUSES_IGNORE);
1816 MPI_Barrier(MPI_COMM_WORLD);
1819 req.resize(cpu_neigh.size());
1821 vector<vector<Vector2D> > incoming(cpu_neigh.size());
1822 vector<vector<double> > tosend(cpu_neigh.size());
1823 for (
size_t i = 0; i < cpu_neigh.size(); ++i)
1825 const int dest = cpu_neigh[i];
1828 std::vector<Vector2D> corsend =
VectorValues(cor, to_duplicate[i]);
1829 for (
size_t j = 0; j < corsend.size(); ++j)
1830 corsend[j] += periodic_add_others2[i][j];
1831 tosend[i] = list_serialize(corsend);
1834 tosend[i] = list_serialize(
VectorValues(cor, messages[i]));
1835 int size =
static_cast<int>(tosend[i].size());
1840 MPI_Isend(&tosend[i][0], size, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD, &req[i]);
1843 MPI_Isend(&dtemp, 1, MPI_DOUBLE, dest, 1, MPI_COMM_WORLD, &req[i]);
1845 for (
size_t i = 0; i < cpu_neigh.size(); ++i)
1847 vector<double> temprecv;
1849 MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1851 MPI_Get_count(&status, MPI_DOUBLE, &count);
1852 temprecv.resize(static_cast<size_t>(count));
1853 MPI_Recv(&temprecv[0], count, MPI_DOUBLE, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
1854 if (status.MPI_TAG == 0)
1856 size_t location =
static_cast<size_t>(std::find(cpu_neigh.begin(), cpu_neigh.end(), status.MPI_SOURCE) -
1858 if (location >= cpu_neigh.size())
1862 incoming[location] = list_unserialize(temprecv, cor[0]);
1866 eo.
AddEntry(
"Error in second send in triangulation", 0.0);
1867 eo.
AddEntry(
"Mpi status", static_cast<double>(status.MPI_SOURCE));
1868 eo.
AddEntry(
"Mpi tag", static_cast<double>(status.MPI_TAG));
1869 eo.
AddEntry(
"Mpi count", static_cast<double>(count));
1874 if (status.MPI_TAG != 1)
1878 MPI_Waitall(static_cast<int>(req.size()), &req[0], MPI_STATUSES_IGNORE);
1879 MPI_Barrier(MPI_COMM_WORLD);
1881 NghostIndex.resize(incoming.size());
1882 for (
size_t i = 0; i < incoming.size(); ++i)
1884 for (
size_t j = 0; j < incoming.at(i).size(); ++j)
1886 NghostIndex[i].push_back(static_cast<int>(cor.size() + j));
1887 OrgIndex.push_back(static_cast<int>(cor.size() + j));
1895 PeriodicGetRidDuplicates(self_send[0], periodic_add_self2, self_points[0], periodic_add_self,t_proc.
GetWidth(rank));
1896 AddPeriodicMPI(self_send[0], periodic_add_self2);
1897 for (
size_t j = 0; j < self_send[0].size(); ++j)
1898 OrgIndex.push_back(self_send[0][j]);
1900 for (
size_t i = 0; i < to_duplicate_2.size(); ++i)
1901 to_duplicate[i].insert(to_duplicate[i].begin(), to_duplicate_2[i].begin(), to_duplicate_2[i].end());
1905 AddRigid(box_edges, real_boundary_points);
1906 for (
size_t i = 0; i < real_boundary_points.size(); ++i)
1907 for (
size_t j = 0; j < real_boundary_points[i].size(); ++j)
1908 OrgIndex.push_back(real_boundary_points[i][j]);
1910 for (
size_t i = 0; i < self_points.size(); ++i)
1911 if (!real_boundary_points[i].empty())
1912 self_points[i].insert(self_points[i].end(), real_boundary_points[i].begin(),
1913 real_boundary_points[i].end());
1915 return std::pair<vector<vector<int> >, vector<int> >(to_duplicate, cpu_neigh);
1921 vector<vector<int> >& Nghost)
1926 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1937 for (
size_t i = 0; i < edge_index.size(); ++i)
1938 edges.push_back(tproc.
GetEdge(edge_index[i]));
1940 vector<Edge> box_edges;
1945 std::vector<int> cpu_neigh;
1946 std::vector<Vector2D> periodic_add_self;
1947 std::vector<std::vector<Vector2D> > periodic_add_others;
1948 std::pair<vector<vector<int> >, vector<vector<int> > > to_duplicate =
1949 findOuterPoints(tproc, edges, box_edges, Nghost, periodic, cpu_neigh, periodic_add_self, periodic_add_others,
1952 std::pair<vector<vector<int> >, vector<int> > res = FindOuterPoints2(tproc, edges, to_duplicate.first, to_duplicate.second, box_edges, Nghost, periodic, cpu_neigh,
1955 radius.resize(f.size());
1956 int n = int(f.size());
1957 for (
int i = 0; i < n; ++i)
1958 radius[static_cast<size_t>(i)] = CalculateRadius(i);
1965 if (index < static_cast<int>(olength))
1966 return static_cast<int>(olength);
1968 return OrgIndex.at(static_cast<size_t>(index) - 3 - olength);
vector< T > unique(vector< T > const &v)
Returns a vector containing only unique elements.
double get_cor(int index, int dim) const
Returns a coordinate.
const T & third
Reference to third item.
vector< T > VectorValues(vector< T > const &v, vector< int > const &index)
Returns only the values with indeces in index.
void Changelength(int n)
Changes the cor length.
double incircle(const Vector2D &point_1, const Vector2D &point_2, const Vector2D &point_3, const Vector2D &point_4)
Checks whether the 4th point is inside, outside or on the counterclockwise circle created by the firs...
void AddBoundaryPoints(vector< Vector2D > const &points)
Adds the points to the tessellation, used for boundary points.
void AddAditionalPoint(Vector2D const &vec)
Adds a point to the cor vector. Used in periodic boundaries with AMR.
void sort_index(const vector< T > &arr, vector< int > &res)
Returns the indeces of a sort.
Vector2D Parallel(Edge const &edge)
Calculates a unit vector parallel to an edge.
void set_point(int index, Vector2D p)
Change Mesh point.
const T & second
Reference to second item.
void RemoveVector(vector< T > &v, vector< int > &indeces)
Removes the elements in v given by indeces.
Abstract class for tessellation.
virtual int GetPointNo(void) const =0
Get Total number of mesh generating points.
const facet & get_facet(int index) const
Returns a facet.
virtual int GetOriginalIndex(int point) const
Returns the original index of the duplicated point.
Delanauy triangle data structure. Keeps the indexes of the vertices (right hand fashion) and the neig...
Container for error reports.
void update(const vector< Vector2D > &points, std::vector< std::pair< Vector2D, Vector2D > >const &cpoints)
Updates the triangulation.
const vector< Vector2D > & getCor(void) const
Access to coordinates.
Triplet< int > vertices
Indices of vertices.
int get_length(void) const
Returns the number of points.
void set(const T &first_i, const T &second_i, const T &third_i)
Changle all items.
int GetTotalLength(void)
Returns the length of all the points (included duplicated)
Interface between two cells.
Vector2D GetCircleCenter(int index, double &R) const
Returns the center of the circumscribed circle of a facet.
double max(vector< double > const &v)
returns the maximal term in a vector
double y
Component in the y direction.
A collection of three identical references.
vector< Vector2D > & GetMeshPoints(void)
Returns a refrence to the points.
virtual Edge const & GetEdge(int index) const =0
Returns edge (interface between cells)
void BuildBoundary(OuterBoundary const *obc, vector< Edge > const &edges)
Builds the boundary points.
~Delaunay(void)
Default destructor.
int get_num_facet(void) const
Returns the number of facets.
The Delaunay data structure. Gets a set of points and constructs the Delaunay tessellation.
double ScalarProd(Vector3D const &v1, Vector3D const &v2)
Scalar product of two vectors.
void RemoveVal(vector< T > &vec, T val)
Removes the first occurence of val inside a vector.
virtual BoundaryType GetBoundaryType(void) const =0
Returns the boundary type.
int GetCorSize(void) const
Gets the size of the cor vector.
virtual void output(vector< Vector2D > const &cor, vector< facet > const &f)
Dumps output.
std::pair< Vector2D, Vector2D > vertices
Points at the ends of the edge.
void ReArrangeVector(vector< T > &v, vector< int > const &indeces)
Rearranges the vector according to the indeces.
virtual double GetWidth(int index) const =0
Returns the effective width of a cell.
int GetOrgIndex(int index) const
Retrieves the original index of a point (in case a point was duplicated)
Vector2D get_point(size_t index) const
Returns a point.
vector< int > find_affected_cells(const Tessellation &tess, int index, Circle &circle, vector< int > &vtemp, bool periodic, std::vector< Vector2D > &periodic_add)
Non recursive version of find affected cells. Only searches one degree of separation.
double min(vector< double > const &v)
Returns the minimal term in a vector.
delaunay_loggers::DelaunayLogger * logger
Diagnostics.
vector< Edge > GetBoxEdges(void) const
Returns the outer box as a set of edges in the order: Right, Up, Left and Down. All neighbors are set...
vector< int > HilbertOrder(vector< Vector2D > const &cor, int num, int innernum=0)
Returns the Hilber curve ordering.
Triplet< int > neighbors
Indices of neighboring facets.
void Set(double ix, double iy)
Set vector components.
void find_affected_cells_recursive(const Tessellation &tess, int index, const Circle &circle, vector< int > &res, std::vector< Vector2D > &added, bool periodic, Vector2D const &ll, Vector2D const &ur)
Recursively finds all cells that intersect a circle.
vector< int > unique_index(vector< T > const &v)
Returns a vector containing only indeces of unique elements.
double get_facet_coordinate(int Facet, int vertice, int dim)
Returns a coordinate of a vertice.
std::pair< int, int > neighbors
Neighboring cells.
void ChangeOlength(int n)
Changes the cor olength.
bool edge_circle_intersect(const Edge &edge, const Circle &circle)
Determines if an edge and a circle intersect.
const T & first
Reference to first item.
int GetOriginalLength(void) const
Returns the original length of the points (without duplicated points)
double abs(Vector3D const &v)
Norm of a vector.
void AddEntry(std::string const &field, double value)
Adds an entry to the list.
virtual vector< int > const & GetCellEdges(int index) const =0
Returns the indexes of a cell's edges.
int get_last_loc(void) const
Returns the last location, a number used to identify the fact that the neighbor of a facet is empty...
Abstract class for geometric boundary conditions for the tessellation.
double triangle_area(int index)
Returns the area of the triangle. Negative result means the triangle isn't right handed.
Delaunay triangulation with mpi.
void build_delaunay(vector< Vector2D >const &vp, std::vector< std::pair< Vector2D, Vector2D > >const &cpoints)
Builds the Delaunay tessellation.
double GetFacetRadius(int facet) const
return the facet's radius
virtual double GetGridBoundary(Directions dir) const =0
Returns the boundary coordinate.
double orient2d(const TripleConstRef< Vector2D > &points)
Checks whether 3 given points are on a counterclockwise circle, clockwise circle or colinear...
double fastabs(Vector2D const &v)
Norm of a vector, less accurate.
double x
Component in the x direction.
Delaunay(void)
Class constructor.
vector< Vector2D > & ChangeCor(void)
Allows to change the cor.
int GetOriginalIndex(int NewPoint) const
Returns the original index of the duplicated point in Periodic Boundary conditions.