3 #include "../misc/simple_io.hpp" 7 #include "../mpi/mpi_commands.hpp" 17 template<
class T>
void tidy(vector<T>& v)
20 sort(v.begin(), v.end());
26 vector<Vector2D> UpdatePoints(vector<Vector2D>
const& points,
OuterBoundary const* obc)
31 res.reserve(points.size());
32 int npoints =
static_cast<int>(points.size());
35 for (
int i = 0; i < npoints; ++i)
37 Vector2D temp(points[static_cast<size_t>(i)]);
61 void CheckInput(std::vector<std::pair<Vector2D, Vector2D> > convexhull, std::vector<Vector2D>
const& cor)
63 size_t N = cor.size();
64 for (
size_t i = 0; i < N; ++i)
68 std::cout <<
"Point not in cell in checkinput" << std::endl;
69 std::cout <<
"Bad point " << cor[i].x <<
", " << cor[i].y << std::endl;
70 std::cout <<
"Bounding cell " << std::endl;
71 for (
size_t j = 0; j < convexhull.size(); ++j)
73 std::cout << convexhull[j].first.x <<
", " << convexhull[j].first.y <<
" "<<convexhull[j].second.x <<
", " <<
74 convexhull[j].second.y << std::endl;
77 eo.AddEntry(
"Point index", static_cast<double>(i));
85 (vector<Vector2D>
const& points,
90 cell_edges(vector<Edge>()),
91 edges(vector<Edge>()),
92 CM(vector<Vector2D>()),
93 mesh_vertices(vector<vector<int> >()),
95 GhostProcs(vector<int>()),
96 GhostPoints(vector<vector<int> >()),
97 SentProcs(vector<int>()),
98 SentPoints(vector<vector<int> >()),
99 selfindex(vector<size_t>()),
100 NGhostReceived(vector<vector<int> >()),
104 Initialise(points, &bc, HOrder);
110 vector<Vector2D>
const& points,
116 cell_edges(vector<Edge>()),
117 edges(vector<Edge>()),
118 CM(vector<Vector2D>()),
119 mesh_vertices(vector<vector<int> >()),
121 GhostProcs(vector<int>()),
122 GhostPoints(vector<vector<int> >()),
123 SentProcs(vector<int>()),
124 SentPoints(vector<vector<int> >()),
125 selfindex(vector<size_t>()),
126 NGhostReceived(vector<vector<int> >()),
130 Initialise(points, proctess, &bc, HOrder);
134 vector<int> VoronoiMesh::AddPointsAlongEdge(
size_t point, vector<vector<int> >
const&copied,
137 int ncopy =
static_cast<int>(copied[
static_cast<size_t>(side)].size());
139 vector<double> dist(static_cast<size_t>(ncopy));
140 for (
size_t i = 0; i < copied[static_cast<size_t>(side)].size(); ++i)
141 dist[i] = vec.
distance(Tri.
get_point(static_cast<size_t>(copied[static_cast<size_t>(side)][i])));
142 const int copylength =
min(7, static_cast<int>(copied[static_cast<size_t>(side)].size()) - 1);
143 vector<int> index, toadd(static_cast<size_t>(copylength));
145 for (
int i = 0; i < copylength; ++i)
146 toadd[static_cast<size_t>(i)] = copied[
static_cast<size_t>(side)][static_cast<size_t>(index[static_cast<size_t>(i) + 1])];
154 return 0.5*(wl + wr) + wprime;
159 const int n = int(mesh_vertices[static_cast<size_t>(index)].size());
161 for (
int i = 0; i < n; ++i)
163 const int n0 = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(index)][static_cast<size_t>(i)])].neighbors.first;
164 const int n1 = edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(index)][
static_cast<size_t>(i)])].neighbors.second;
165 if (n0 < 0 || n1 < 0 || n0 >= N || n1 >= N)
171 VoronoiMesh::~VoronoiMesh(
void) {}
191 cell_edges(vector<
Edge>()),
192 edges(vector<
Edge>()),
194 mesh_vertices(vector<vector<int> >()),
196 GhostProcs(vector<int>()),
197 GhostPoints(vector<vector<int> >()),
198 SentProcs(vector<int>()),
199 SentPoints(vector<vector<int> >()),
200 selfindex(vector<size_t>()),
201 NGhostReceived(vector<vector<int> >()),
209 cell_edges(other.cell_edges),
212 mesh_vertices(other.mesh_vertices),
214 GhostProcs(other.GhostProcs),
215 GhostPoints(other.GhostPoints),
216 SentProcs(other.SentProcs),
217 SentPoints(other.SentPoints),
218 selfindex(other.selfindex),
219 NGhostReceived(other.NGhostReceived),
224 void VoronoiMesh::build_v()
231 mesh_vertices.clear();
232 mesh_vertices.resize(static_cast<size_t>(Tri.
get_length()));
233 edges.reserve(static_cast<size_t>(Tri.
get_length()*3.5));
235 for (
int i = 0; i < N; ++i)
236 mesh_vertices[static_cast<size_t>(i)].reserve(7);
238 vector<Vector2D> centers(static_cast<size_t>(Nfacets));
240 for (
int i = 0; i < Nfacets; ++i)
242 for (
int i = 0; i < Nfacets; ++i)
244 center = centers[
static_cast<size_t>(i)];
246 for (j = 0; j < 3; ++j)
248 if (to_check.neighbors[static_cast<size_t>(j)] == Tri.
get_last_loc())
250 if (to_check.neighbors[static_cast<size_t>(j)] < i)
252 center_temp = centers[
static_cast<size_t>(to_check.neighbors[
static_cast<size_t>(j)])];
255 edge_temp.
vertices.second = center_temp;
256 edge_temp.
neighbors.first = to_check.vertices[
static_cast<size_t>(j)];
257 edge_temp.
neighbors.second = to_check.vertices[
static_cast<size_t>(j + 1) % 3];
258 if (legal_edge(&edge_temp))
266 mesh_vertices[static_cast<size_t>(edge_temp.
neighbors.first)].push_back(static_cast<int>(edges.size()));
268 mesh_vertices[static_cast<size_t>(edge_temp.
neighbors.second)].push_back(static_cast<int>(edges.size()));
269 edges.push_back(edge_temp);
280 std::vector<std::pair<Vector2D, Vector2D> > calc_procpoints(
const OuterBoundary& bc)
282 std::vector<std::pair<Vector2D, Vector2D> > res(4);
315 vector<Vector2D> points;
321 std::vector<std::pair<Vector2D, Vector2D> > cpoints = calc_procpoints(*obc);
322 points = UpdatePoints(points, obc);
323 CheckInput(cpoints, points);
327 Nextra =
static_cast<int>(Tri.
ChangeCor().size());
339 CM.resize(Tri.
getCor().size());
340 for (
size_t i = 0; i < pv.size(); ++i)
341 CM[i] = CalcCellCM(i);
343 size_t counter = pv.size() + 3;
346 for (
int i = static_cast<int>(counter); i < Tri.
GetCorSize(); ++i)
349 if (NorgIndex < Nextra)
351 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] +
353 Tri.
get_point(static_cast<size_t>(NorgIndex)));
361 for (
int i = static_cast<int>(counter); i < Tri.
GetCorSize(); ++i)
364 if (NorgIndex < Nextra)
367 Tri.
get_point(static_cast<size_t>(NorgIndex)));
368 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + Tri.
get_point(static_cast<size_t>(i))
370 CM[static_cast<size_t>(NorgIndex)] - Tri.
get_point(static_cast<size_t>(NorgIndex)));
377 for (
int i = static_cast<int>(counter); i < Tri.
GetCorSize(); ++i)
380 if (NorgIndex < Nextra)
383 if (dx_temp<1.0001*dx && dx_temp*1.0001>dx)
384 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + (Tri.
get_point(static_cast<size_t>(i)) -
385 Tri.
get_point(static_cast<size_t>(NorgIndex)));
389 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + Tri.
get_point(static_cast<size_t>(i))
391 CM[static_cast<size_t>(NorgIndex)] - Tri.
get_point(static_cast<size_t>(NorgIndex)));
399 bool VoronoiMesh::legal_edge(
Edge *e)
449 return mesh_vertices.at(static_cast<size_t>(index));
456 const size_t nloop = mesh_vertices[
static_cast<size_t>(index)].size();
457 for (
size_t i = 0; i < nloop; ++i)
459 const Vector2D p1 = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(index)][static_cast<size_t>(i)])].vertices.first -
461 const Vector2D p2 = edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(index)][
static_cast<size_t>(i)])].vertices.second -
468 Vector2D VoronoiMesh::CalcCellCM(
size_t index)
const 470 const Vector2D center = edges[
static_cast<size_t>(mesh_vertices[index].front())].vertices.first;
473 for (
size_t i = 1; i < mesh_vertices[index].size(); i++)
475 const Edge& edge = edges[
static_cast<size_t>(mesh_vertices[index][i])];
480 pc += (area_temp / 3.)*(center + edge.
vertices.first + edge.
vertices.second);
496 vector<Vector2D> procpoints;
502 vector<Vector2D> points = UpdatePoints(pv, obc);
504 std::vector<std::pair<Vector2D, Vector2D> > chull = calc_procpoints(*obc);
505 CheckInput(chull, points);
507 vector<int> HilbertIndeces;
510 HilbertIndeces =
HilbertOrder(points, static_cast<int>(pv.size()));
514 Tri.
update(points, chull);
516 Nextra =
static_cast<int>(Tri.
ChangeCor().size());
529 CM.resize(Tri.
getCor().size());
530 for (
size_t i = 0; i < points.size(); ++i)
531 CM[i] = CalcCellCM(i);
533 size_t counter = pv.size() + 3;
536 for (
int i = static_cast<int>(counter); i < Tri.
GetCorSize(); ++i)
539 if (NorgIndex < Nextra)
541 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + (Tri.
get_point(static_cast<size_t>(i)) -
542 Tri.
get_point(static_cast<size_t>(NorgIndex)));
550 for (
int i = static_cast<int>(counter); i < Tri.
GetCorSize(); ++i)
553 if (NorgIndex < Nextra)
556 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + Tri.
get_point(static_cast<size_t>(i))
558 CM[static_cast<size_t>(NorgIndex)] - Tri.
get_point(static_cast<size_t>(NorgIndex)));
565 for (
int i = static_cast<int>(counter); i < Tri.
GetCorSize(); ++i)
568 if (NorgIndex < Nextra)
571 if (dx_temp<1.0001*dx && dx_temp*1.0001>dx)
572 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + (Tri.
get_point(static_cast<size_t>(i)) -
573 Tri.
get_point(static_cast<size_t>(NorgIndex)));
577 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + Tri.
get_point(static_cast<size_t>(i))
579 CM[static_cast<size_t>(NorgIndex)] - Tri.
get_point(static_cast<size_t>(NorgIndex)));
585 return HilbertIndeces;
590 vector<int> res(mesh_vertices[static_cast<size_t>(index)].size());
591 for (
size_t i = 0; i < res.size(); ++i)
592 res[i] = edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(index)][i])].neighbors.first != index ?
593 edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(index)][i])].neighbors.first :
594 edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(index)][i])].neighbors.second;
600 neigh.resize(mesh_vertices[static_cast<size_t>(index)].size());
601 size_t N = neigh.size();
602 for (
size_t i = 0; i < N; ++i)
603 neigh[i] = edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(index)][i])].neighbors.first != index ?
604 edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(index)][i])].neighbors.first :
605 edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(index)][i])].neighbors.second;
611 int n =
static_cast<int>(mesh_vertices[
static_cast<size_t>(index)].size());
613 res.reserve(static_cast<size_t>(n));
614 for (
int i = 0; i < n; ++i)
616 int other = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(index)][static_cast<size_t>(i)])].neighbors.first;
620 res.push_back(other);
625 other = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(index)][static_cast<size_t>(i)])].neighbors.second;
626 res.push_back(other);
650 return Tri.
get_point(static_cast<size_t>(index));
655 return static_cast<int>(edges.size());
665 return edges[
static_cast<size_t>(index)];
670 return CM[
static_cast<size_t>(index)];
678 void VoronoiMesh::FindIntersectingOuterPoints(vector<Edge>
const&box_edges, vector<vector<int> >
679 &boxduplicate, vector<vector<int> >
const&firstduplicated)
681 int n =
static_cast<int>(box_edges.size());
682 boxduplicate.resize(static_cast<size_t>(n));
683 int N =
static_cast<int>(mesh_vertices.size());
686 for (
int i = 0; i < n; ++i)
687 for (
int j = 0; j < N; ++j)
688 boxduplicate[static_cast<size_t>(i)].push_back(j);
692 N =
static_cast<int>(firstduplicated.size());
693 for (
int i = 0; i < N; ++i)
695 n =
static_cast<int>(firstduplicated[
static_cast<size_t>(i)].size());
696 for (
int j = 0; j < n; ++j)
698 vector<int> temp = CellIntersectOuterBoundary(box_edges, firstduplicated[static_cast<size_t>(i)][static_cast<size_t>(j)]);
699 int jj =
static_cast<int>(temp.size());
702 for (
int k = 0; k < jj; ++k)
703 boxduplicate[static_cast<size_t>(temp[static_cast<size_t>(k)])].push_back(firstduplicated[static_cast<size_t>(i)][
static_cast<size_t>(j)]);
707 n =
static_cast<int>(box_edges.size());
708 for (
int i = 0; i < n; ++i)
710 if (!boxduplicate[static_cast<size_t>(i)].empty())
712 sort(boxduplicate[static_cast<size_t>(i)].begin(), boxduplicate[static_cast<size_t>(i)].end());
713 boxduplicate[
static_cast<size_t>(i)] =
unique(boxduplicate[static_cast<size_t>(i)]);
718 void VoronoiMesh::FindIntersectingPoints(vector<Edge>
const &box_edges,
719 vector<vector<int> > &toduplicate)
721 int n =
static_cast<int>(box_edges.size());
722 toduplicate.resize(static_cast<size_t>(n));
723 int N =
static_cast<int>(mesh_vertices.size());
726 for (
int i = 0; i < n; ++i)
727 for (
int j = 0; j < N; ++j)
728 toduplicate[static_cast<size_t>(i)].push_back(j);
732 for (
int i = 0; i < N; ++i)
735 temp = CellIntersectBoundary(box_edges, i);
736 int j =
static_cast<int>(temp.size());
739 for (
int k = 0; k < j; ++k)
740 toduplicate[static_cast<size_t>(temp[static_cast<size_t>(k)])].push_back(i);
743 for (
int i = 0; i < n; ++i)
745 if (!toduplicate[static_cast<size_t>(i)].empty())
747 sort(toduplicate[static_cast<size_t>(i)].begin(), toduplicate[static_cast<size_t>(i)].end());
748 toduplicate[
static_cast<size_t>(i)] =
unique(toduplicate[static_cast<size_t>(i)]);
753 vector<int> VoronoiMesh::CellIntersectBoundary(vector<Edge>
const&box_edges,
int cell)
755 int ncell =
static_cast<int>(mesh_vertices[
static_cast<size_t>(cell)].size());
756 int nbox =
static_cast<int>(box_edges.size());
759 for (
int i = 0; i < ncell; ++i)
761 for (
int j = 0; j < nbox; ++j)
763 if (
SegmentIntersection(box_edges[static_cast<size_t>(j)], edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(cell)][static_cast<size_t>(i)])],
768 sort(res.begin(), res.end());
770 int nintersect =
static_cast<int>(res.size());
773 vector<Vector2D> cpoints;
775 for (
int i = 0; i < nbox; ++i)
776 if (
PointInCell(cpoints, box_edges[static_cast<size_t>(i)].vertices.first) ||
777 PointInCell(cpoints, box_edges[static_cast<size_t>(i)].vertices.second))
779 sort(res.begin(), res.end());
785 vector<int> VoronoiMesh::CellIntersectOuterBoundary(vector<Edge>
const&box_edges,
int cell)
787 int ncell =
static_cast<int>(mesh_vertices[
static_cast<size_t>(cell)].size());
788 int nbox =
static_cast<int>(box_edges.size());
791 boost::array<Vector2D, 3> tocheck;
792 for (
int i = 0; i < ncell; ++i)
794 for (
int j = 0; j < nbox; ++j)
796 if (
SegmentIntersection(box_edges[static_cast<size_t>(j)], edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(cell)][static_cast<size_t>(i)])],
799 double r = sqrt(edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(cell)][static_cast<size_t>(i)])].GetLength()*
800 box_edges[static_cast<size_t>(j)].GetLength());
803 (box_edges[static_cast<size_t>(j)].vertices.second - box_edges[static_cast<size_t>(j)].vertices.first,
804 edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(cell)][static_cast<size_t>(i)])].vertices.second - box_edges[static_cast<size_t>(j)].vertices.first,
805 edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(cell)][static_cast<size_t>(i)])].vertices.first - box_edges[static_cast<size_t>(j)].vertices.first)))
808 if (
DistanceToEdge(edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(cell)][static_cast<size_t>(i)])].vertices.first,
809 box_edges[static_cast<size_t>(j)]) < eps1*r)
811 if (
DistanceToEdge(edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(cell)][static_cast<size_t>(i)])].vertices.second,
812 box_edges[static_cast<size_t>(j)]) < eps1*r)
814 if ((intersect.
distance(edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(cell)][static_cast<size_t>(i)])].vertices.first)
815 > eps1*r) && (intersect.
distance(edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(cell)][static_cast<size_t>(i)])].vertices.second)
821 sort(res.begin(), res.end());
827 bool VoronoiMesh::CloseToBorder(
int point,
int &border)
830 int n =
static_cast<int>(mesh_vertices[
static_cast<size_t>(point)].size());
831 for (
int i = 0; i < n; ++i)
833 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][
static_cast<size_t>(i)])].neighbors.second == point)
834 border = edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][
static_cast<size_t>(i)])].neighbors.first;
836 border = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(point)][static_cast<size_t>(i)])].neighbors.second;
837 if (border > olength)
843 vector<int> VoronoiMesh::GetBorderingCells(vector<int>
const& copied,
844 vector<int>
const& totest,
int tocheck, vector<int> tempresult,
int outer)
848 tempresult.push_back(tocheck);
849 sort(tempresult.begin(), tempresult.end());
850 int n =
static_cast<int>(mesh_vertices[
static_cast<size_t>(tocheck)].size());
851 for (
int i = 0; i < n; ++i)
853 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(tocheck)][
static_cast<size_t>(i)])].neighbors.second == tocheck)
854 test = edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(tocheck)][
static_cast<size_t>(i)])].neighbors.first;
856 test = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(tocheck)][static_cast<size_t>(i)])].neighbors.second;
861 if (CloseToBorder(test, border))
863 if (!binary_search(copied.begin(), copied.end(), test) &&
864 !binary_search(totest.begin(), totest.end(), test) &&
865 !binary_search(tempresult.begin(), tempresult.end(), test))
866 tempresult = GetBorderingCells(copied, totest, test, tempresult, outer);
871 void VoronoiMesh::GetAdditionalBoundary(vector<vector<int> > &copied,
872 vector<vector<int> > &neighbors, vector<vector<int> > &totest)
874 int nsides =
static_cast<int>(copied.size());
877 neighbors.resize(static_cast<size_t>(nsides));
878 for (
int i = 0; i < nsides; ++i)
880 sort(copied[static_cast<size_t>(i)].begin(), copied[static_cast<size_t>(i)].end());
882 int n =
static_cast<int>(totest[
static_cast<size_t>(i)].size());
883 for (
int j = 0; j < n; ++j)
885 if (totest[static_cast<size_t>(i)][
static_cast<size_t>(j)] == -1)
889 if (CloseToBorder(totest[static_cast<size_t>(i)][
static_cast<size_t>(j)], outer))
890 toadd = GetBorderingCells(copied[static_cast<size_t>(i)], totest[
static_cast<size_t>(i)], totest[static_cast<size_t>(i)][
static_cast<size_t>(j)], toadd, outer);
891 int nn =
static_cast<int>(toadd.size());
892 for (
int k = 0; k < nn; ++k)
893 neighbors[static_cast<size_t>(i)].push_back(toadd[static_cast<size_t>(k)]);
895 sort(neighbors[static_cast<size_t>(i)].begin(), neighbors[static_cast<size_t>(i)].end());
896 neighbors[
static_cast<size_t>(i)] =
unique(neighbors[static_cast<size_t>(i)]);
897 neighbors[
static_cast<size_t>(i)] =
RemoveList(neighbors[static_cast<size_t>(i)], copied[
static_cast<size_t>(i)]);
901 void VoronoiMesh::GetRealNeighbor(vector<int> &result,
int point)
const 904 int n =
static_cast<int>(mesh_vertices[
static_cast<size_t>(point)].size());
906 for (
int i = 0; i < n; ++i)
908 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][static_cast<size_t>(i)])].neighbors.first == point)
910 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][static_cast<size_t>(i)])].neighbors.second > -1 &&
911 edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][static_cast<size_t>(i)])].neighbors.second < olength)
912 result.push_back(edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][static_cast<size_t>(i)])].neighbors.second);
916 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][static_cast<size_t>(i)])].neighbors.first > -1 &&
917 edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][static_cast<size_t>(i)])].neighbors.first < olength)
918 result.push_back(edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][static_cast<size_t>(i)])].neighbors.first);
921 sort(result.begin(), result.end());
931 int n =
static_cast<int>(neigh.size());
932 for (
int i = 0; i < n; ++i)
939 for (
size_t j = 0; j < temp.size(); ++j)
942 sort(result.begin(), result.end());
948 void VoronoiMesh::GetNeighborNeighborsMPI(vector<int> &result,
int point)
952 GetRealNeighbor(neigh, point);
953 int n =
static_cast<int>(neigh.size());
954 for (
int i = 0; i < n; ++i)
957 GetRealNeighbor(temp, neigh[static_cast<size_t>(i)]);
958 int N =
static_cast<int>(temp.size());
959 for (
int j = 0; j < N; ++j)
960 result.push_back(temp[static_cast<size_t>(j)]);
962 sort(result.begin(), result.end());
966 void VoronoiMesh::GetCorners(vector<vector<int> > &copied,
967 vector<vector<int> > &result)
970 int nsides =
static_cast<int>(copied.size());
973 OrgCorner.resize(static_cast<size_t>(nsides));
974 result.resize(static_cast<size_t>(nsides));
975 vector<vector<int> > toadd(static_cast<size_t>(nsides));
976 for (
int i = 0; i < nsides; ++i)
978 int n =
static_cast<int>(copied[
static_cast<size_t>(i)].size());
979 for (
int j = 0; j < n; ++j)
981 if (binary_search(copied[static_cast<size_t>((i + 1) % nsides)].begin(), copied[
static_cast<size_t>((i + 1) % nsides)].end(),
982 copied[
static_cast<size_t>(i)][static_cast<size_t>(j)]))
985 GetNeighborNeighborsMPI(temp, copied[static_cast<size_t>(i)][static_cast<size_t>(j)]);
986 result[
static_cast<size_t>(i)].insert(result[static_cast<size_t>(i)].end(), temp.begin(), temp.end());
987 temp = AddPointsAlongEdge(static_cast<size_t>(copied[static_cast<size_t>(i)][static_cast<size_t>(j)]), copied, i);
988 toadd[
static_cast<size_t>((i + 1) % nsides)].insert(toadd[static_cast<size_t>((i + 1) % nsides)].end(), temp.begin(),
990 temp =
GetNeighbors(copied[static_cast<size_t>(i)][static_cast<size_t>(j)]);
991 for (vector<int>::iterator it = temp.begin(); it != temp.end(); ++it)
993 OrgCorner[static_cast<size_t>(i)].push_back(*it);
994 OrgCorner[
static_cast<size_t>(i)].push_back(copied[static_cast<size_t>(i)][
static_cast<size_t>(j)]);
996 if (binary_search(copied[static_cast<size_t>((i - 1 + nsides) % nsides)].begin(), copied[static_cast<size_t>((i - 1 + nsides) % nsides)].end(),
997 copied[static_cast<size_t>(i)][static_cast<size_t>(j)]))
1000 GetNeighborNeighborsMPI(temp, copied[static_cast<size_t>(i)][static_cast<size_t>(j)]);
1001 result[
static_cast<size_t>((i - 1 + nsides) % nsides)].insert(result[static_cast<size_t>((i - 1 + nsides) % nsides)].end()
1002 , temp.begin(), temp.end());
1003 temp = AddPointsAlongEdge(static_cast<size_t>(copied[static_cast<size_t>(i)][static_cast<size_t>(j)]), copied, i);
1004 toadd[
static_cast<size_t>((i - 1 + nsides) % nsides)].insert(toadd[static_cast<size_t>((i - 1 + nsides) % nsides)].end(),
1005 temp.begin(), temp.end());
1006 temp =
GetNeighbors(copied[static_cast<size_t>(i)][static_cast<size_t>(j)]);
1007 for (vector<int>::iterator it = temp.begin(); it != temp.end(); ++it)
1009 OrgCorner[static_cast<size_t>((i - 1 + nsides) % nsides)].push_back(*it);
1010 OrgCorner[
static_cast<size_t>((i - 1 + nsides) % nsides)].push_back(copied[static_cast<size_t>(i)][static_cast<size_t>(j)]);
1014 for (
int i = 0; i < nsides; ++i)
1016 copied[
static_cast<size_t>(i)].insert(copied[static_cast<size_t>(i)].end(), toadd[
static_cast<size_t>(i)].begin(), toadd[
static_cast<size_t>(i)].end());
1017 sort(copied[static_cast<size_t>(i)].begin(), copied[static_cast<size_t>(i)].end());
1018 copied[
static_cast<size_t>(i)] =
unique(copied[static_cast<size_t>(i)]);
1019 sort(result[static_cast<size_t>(i)].begin(), result[static_cast<size_t>(i)].end());
1020 result[
static_cast<size_t>(i)] =
unique(result[static_cast<size_t>(i)]);
1021 if (!OrgCorner[static_cast<size_t>(i)].empty())
1023 sort(OrgCorner[static_cast<size_t>(i)].begin(), OrgCorner[static_cast<size_t>(i)].end());
1024 OrgCorner[
static_cast<size_t>(i)] =
unique(OrgCorner[static_cast<size_t>(i)]);
1029 void VoronoiMesh::GetToTest(vector<vector<int> > &copied, vector<vector<int> > &totest)
1031 int nsides =
static_cast<int>(copied.size());
1034 for (
int i = 0; i < nsides; ++i)
1035 sort(copied[static_cast<size_t>(i)].begin(), copied[static_cast<size_t>(i)].end());
1036 totest.resize(static_cast<size_t>(nsides));
1038 for (
int i = 0; i < nsides; ++i)
1040 vector<int> totest2;
1041 int ncopy =
static_cast<int>(copied[
static_cast<size_t>(i)].size());
1042 for (
int j = 0; j < ncopy; ++j)
1044 int n =
static_cast<int>(mesh_vertices[
static_cast<size_t>(copied[
static_cast<size_t>(i)][static_cast<size_t>(j)])].size());
1045 for (
int k = 0; k < n; ++k)
1047 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(copied[static_cast<size_t>(i)][
static_cast<size_t>(j)])][
static_cast<size_t>(k)])].neighbors.first ==
1048 copied[
static_cast<size_t>(i)][static_cast<size_t>(j)])
1049 test = edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(copied[static_cast<size_t>(i)][
static_cast<size_t>(j)])][
static_cast<size_t>(k)])].neighbors.second;
1051 test = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(copied[
static_cast<size_t>(i)][static_cast<size_t>(j)])][static_cast<size_t>(k)])].neighbors.first;
1053 totest2.push_back(test);
1056 sort(totest2.begin(), totest2.end());
1057 totest2 =
unique(totest2);
1058 totest[
static_cast<size_t>(i)] = totest2;
1062 vector<int> VoronoiMesh::FindEdgeStartConvex(
int point)
1064 int n =
static_cast<int>(mesh_vertices[
static_cast<size_t>(point)].size());
1066 int min_index = 0, p_index;
1067 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][
static_cast<size_t>(0)])].vertices.first.x <
1068 edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(point)][0])].vertices.second.x)
1070 min_point = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(point)][0])].vertices.first;
1075 min_point = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(point)][0])].vertices.second;
1078 for (
int i = 1; i < n; ++i)
1080 double R = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(point)][static_cast<size_t>(i)])].GetLength();
1081 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][static_cast<size_t>(i)])].vertices.first.x < (min_point.
x - R*eps))
1083 min_point = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(point)][static_cast<size_t>(i)])].vertices.first;
1087 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][
static_cast<size_t>(i)])].vertices.second.x < (min_point.
x - R*eps))
1089 min_point = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(point)][static_cast<size_t>(i)])].vertices.second;
1093 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][
static_cast<size_t>(i)])].vertices.first.x < (min_point.
x + R*eps) &&
1094 edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][
static_cast<size_t>(i)])].vertices.first.y < min_point.
y)
1096 min_point = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(point)][static_cast<size_t>(i)])].vertices.first;
1101 if (edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][
static_cast<size_t>(i)])].vertices.second.x < (min_point.
x + R*eps) &&
1102 edges[static_cast<size_t>(mesh_vertices[static_cast<size_t>(point)][
static_cast<size_t>(i)])].vertices.second.y < min_point.
y)
1104 min_point = edges[
static_cast<size_t>(mesh_vertices[
static_cast<size_t>(point)][static_cast<size_t>(i)])].vertices.second;
1115 void VoronoiMesh::ConvexEdgeOrder(
void)
1117 int n =
static_cast<int>(mesh_vertices.size());
1118 for (
int i = 0; i < n; ++i)
1121 vector<int> min_index = FindEdgeStartConvex(i);
1122 int p_loc = min_index[1];
1123 int edge_loc = mesh_vertices[
static_cast<size_t>(i)][static_cast<size_t>(min_index[0])];
1124 int nedges =
static_cast<int>(mesh_vertices[
static_cast<size_t>(i)].size());
1125 std::list<int> elist;
1126 for (
int j = 0; j < nedges; ++j)
1128 if (j != min_index[0])
1129 elist.push_back(mesh_vertices[static_cast<size_t>(i)][static_cast<size_t>(j)]);
1131 vector<int> new_order;
1132 new_order.reserve(static_cast<size_t>(nedges));
1133 new_order.push_back(edge_loc);
1134 for (
int j = 0; j < nedges; ++j)
1136 if (j == min_index[0])
1138 int nlist =
static_cast<int>(elist.size());
1139 std::list<int>::iterator it = elist.begin();
1140 for (
int k = 0; k < nlist; ++k)
1142 double temp0 =
pair_member(edges[static_cast<size_t>(edge_loc)].vertices, (p_loc + 1) % 2).distance(edges[static_cast<size_t>(*it)].vertices.first);
1148 new_order.push_back(edge_loc);
1151 double temp1 =
pair_member(edges[static_cast<size_t>(edge_loc)].vertices, (p_loc + 1) % 2).distance(
1152 edges[static_cast<size_t>(*it)].vertices.second);
1157 new_order.push_back(edge_loc);
1164 mesh_vertices[
static_cast<size_t>(i)] = new_order;
1185 return NGhostReceived;
1190 return NGhostReceived;
1195 return static_cast<int>(Tri.
getCor().size());
1218 size_t endp = cpoints.size();
1219 for (
size_t i = 0; i < endp; ++i)
1221 for (
size_t i = 0; i < endp; ++i)
1223 if (
fastabs(cpoints[i] - cpoints[(i + 1) % endp]) < eps * Rmax)
1226 cpoints[(i + 1) % endp],
1236 size_t endp = cpoints.size();
1237 for (
size_t i = 0; i < endp; ++i)
1240 cpoints[i].second, vec)) < -0.0)
1247 boost::array<double, 4> VoronoiMesh::FindMaxCellEdges(
void)
1249 int n =
static_cast<int>(cell_edges.size());
1250 boost::array<double, 4> res;
1251 res[0] =
min(cell_edges[0].vertices.first.x, cell_edges[0].vertices.second.x);
1252 res[1] =
max(cell_edges[0].vertices.first.x, cell_edges[0].vertices.second.x);
1253 res[2] =
min(cell_edges[0].vertices.first.y, cell_edges[0].vertices.second.y);
1254 res[3] =
max(cell_edges[0].vertices.first.y, cell_edges[0].vertices.second.y);
1255 for (
int i = 1; i < n; ++i)
1257 res[0] =
min(
min(cell_edges[static_cast<size_t>(i)].vertices.first.x, cell_edges[static_cast<size_t>(i)].vertices.second.x), res[0]);
1258 res[1] =
max(
max(cell_edges[static_cast<size_t>(i)].vertices.first.x, cell_edges[static_cast<size_t>(i)].vertices.second.x), res[1]);
1259 res[2] =
min(
min(cell_edges[static_cast<size_t>(i)].vertices.first.y, cell_edges[static_cast<size_t>(i)].vertices.second.y), res[2]);
1260 res[3] =
max(
max(cell_edges[static_cast<size_t>(i)].vertices.first.y, cell_edges[static_cast<size_t>(i)].vertices.second.y), res[3]);
1267 (
const vector<Vector2D>& points,
1270 NGhostReceived.clear();
1272 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1276 for (
size_t i = 0; i < cedges.size(); ++i)
1277 cell_edges.push_back(vproc.
GetEdge(cedges[i]));
1280 std::vector<std::pair<Vector2D, Vector2D> > cpoints;
1283 vector<int> HilbertIndeces;
1284 vector<Vector2D> newcor;
1287 HilbertIndeces =
HilbertOrder(points, static_cast<int>(points.size()));
1295 newcor =
UpdateMPIPoints(vproc, rank, newcor, obc, selfindex, SentProcs, SentPoints);
1304 size_t bad_index =
static_cast<size_t>(eo.
GetValues()[0]);
1306 eo.
AddEntry(
"original point in cor x", points[bad_index].x);
1307 eo.
AddEntry(
"original point in cor y", points[bad_index].y);
1309 for (
size_t i = 0; i < edge_index.size(); ++i)
1311 eo.
AddEntry(
"edge number", static_cast<double>(edge_index[i]));
1319 Nextra =
static_cast<int>(Tri.
ChangeCor().size());
1322 GhostPoints.clear();
1324 NGhostReceived.clear();
1327 pair<vector<vector<int> >, vector<int> > ptemp = Tri.
BuildBoundary(obc, vproc, NGhostReceived);
1328 GhostPoints = ptemp.first;
1329 GhostProcs = ptemp.second;
1333 std::vector<double> xtemp;
1334 for (
size_t i = 0; i < newcor.size(); ++i)
1335 xtemp.push_back(newcor[i].x);
1338 for (
size_t i = 0; i < newcor.size(); ++i)
1339 xtemp.push_back(newcor[i].y);
1348 size_t n =
static_cast<size_t>(
GetPointNo());
1349 CM.resize(Tri.
getCor().size());
1350 for (
size_t i = 0; i < n; ++i)
1351 CM[i] = CalcCellCM(i);
1355 for (
int i = Nextra; i < Tri.
GetCorSize(); ++i)
1358 if (NorgIndex < Nextra)
1360 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + (Tri.
get_point(i) -
1361 Tri.
get_point(static_cast<size_t>(NorgIndex)));
1369 for (
int i = Nextra; i < Tri.
GetCorSize(); ++i)
1372 if (NorgIndex < Nextra)
1375 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + Tri.
get_point(i)
1377 CM[static_cast<size_t>(NorgIndex)] - Tri.
get_point(static_cast<size_t>(NorgIndex)));
1385 vector<vector<Vector2D> > incoming = MPI_exchange_data(GhostProcs, GhostPoints, CM);
1387 for (
size_t i = 0; i < incoming.size(); ++i)
1388 for (
size_t j = 0; j < incoming.at(i).size(); ++j)
1389 CM[NGhostReceived.at(i).at(j)] = incoming[i][j];
1393 std::vector<Vector2D> & localcor = Tri.
ChangeCor();
1394 incoming = MPI_exchange_data(GhostProcs, GhostPoints, localcor);
1395 for (
size_t i = 0; i < incoming.size(); ++i)
1396 for (
size_t j = 0; j < incoming.at(i).size(); ++j)
1397 CM[NGhostReceived.at(i).at(j)] += localcor[NGhostReceived.at(i).at(j)] - incoming[i][j];
1400 return HilbertIndeces;
1404 (vector<Vector2D>
const& pv,
1408 NGhostReceived.clear();
1410 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1415 for (
size_t i = 0; i < cedges.size(); ++i)
1416 cell_edges.push_back(vproc.
GetEdge(cedges[i]));
1418 vector<Vector2D> points;
1424 std::vector<std::pair<Vector2D, Vector2D> > cpoints;
1427 CheckInput(cpoints, points);
1431 Nextra =
static_cast<int>(Tri.
ChangeCor().size());
1434 GhostPoints.clear();
1436 NGhostReceived.clear();
1437 selfindex.resize(points.size());
1438 size_t npoints = points.size();
1439 for (
size_t i = 0; i < npoints; ++i)
1443 pair<vector<vector<int> >, vector<int> > ptemp = Tri.
BuildBoundary(obc, vproc, NGhostReceived);
1444 GhostPoints = ptemp.first;
1445 GhostProcs = ptemp.second;
1449 std::vector<double> xtemp;
1450 for (
size_t i = 0; i < points.size(); ++i)
1451 xtemp.push_back(points[i].x);
1454 for (
size_t i = 0; i < points.size(); ++i)
1455 xtemp.push_back(points[i].y);
1485 size_t n =
static_cast<size_t>(
GetPointNo());
1486 CM.resize(Tri.
getCor().size());
1487 for (
size_t i = 0; i < n; ++i)
1488 CM[i] = CalcCellCM(i);
1492 for (
int i = Nextra; i < Tri.
GetCorSize(); ++i)
1495 if (NorgIndex < Nextra)
1497 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + (Tri.
get_point(i) -
1498 Tri.
get_point(static_cast<size_t>(NorgIndex)));
1506 for (
int i = Nextra; i < Tri.
GetCorSize(); ++i)
1509 if (NorgIndex < Nextra)
1512 CM[
static_cast<size_t>(i)] = CM[static_cast<size_t>(NorgIndex)] + Tri.
get_point(i)
1514 CM[static_cast<size_t>(NorgIndex)] - Tri.
get_point(static_cast<size_t>(NorgIndex)));
1522 vector<vector<Vector2D> > incoming = MPI_exchange_data(GhostProcs, GhostPoints, CM);
1524 for (
size_t i = 0; i < incoming.size(); ++i)
1525 for (
size_t j = 0; j < incoming.at(i).size(); ++j)
1526 CM[NGhostReceived.at(i).at(j)] = incoming[i][j];
1531 std::vector<Vector2D> & localcor = Tri.
ChangeCor();
1532 incoming = MPI_exchange_data(GhostProcs, GhostPoints, localcor);
1533 for (
size_t i = 0; i < incoming.size(); ++i)
1534 for (
size_t j = 0; j < incoming.at(i).size(); ++j)
1535 CM[NGhostReceived.at(i).at(j)] += localcor[NGhostReceived.at(i).at(j)] - incoming[i][j];
1541 vector<Vector2D> &points,
OuterBoundary const* obc, vector<size_t> &selfindex,
1542 vector<int> &sentproc, vector<vector<int> > &sentpoints)
1544 vector<Vector2D> res;
1545 res.reserve(points.size());
1547 size_t npoints = points.size();
1548 size_t nproc =
static_cast<size_t>(vproc.
GetPointNo());
1551 vector<std::pair<Vector2D, Vector2D> > cproc;
1554 vector<int> realneigh;
1555 std::vector<size_t> neigh_keep;
1556 vector<vector<std::pair<Vector2D, Vector2D> > > neigh_chull;
1560 for (
size_t i = 0; i < neighbors.size(); ++i)
1562 if (static_cast<size_t>(neighbors[i]) < nproc || periodic)
1564 if (static_cast<size_t>(neighbors[i]) >= nproc)
1567 if (temp_neigh == rank)
1569 realneigh.push_back(temp_neigh);
1570 vector< std::pair<Vector2D, Vector2D> > temp;
1573 for (
size_t j = 0; j < temp.size(); ++j)
1575 temp[j].first += to_add_neigh;
1576 temp[j].second += to_add_neigh;
1578 neigh_chull.push_back(temp);
1579 sentproc.push_back(temp_neigh);
1580 neigh_keep.push_back(i);
1584 realneigh.push_back(neighbors[i]);
1585 vector< std::pair<Vector2D, Vector2D> > temp;
1587 neigh_chull.push_back(temp);
1588 sentproc.push_back(neighbors[i]);
1589 neigh_keep.push_back(i);
1594 std::sort(sentproc.begin(), sentproc.end());
1595 sentproc =
unique(sentproc);
1596 sentpoints.resize(sentproc.size());
1598 for (
size_t i = 0; i < npoints; ++i)
1604 res.push_back(temp);
1605 selfindex.push_back(i);
1610 for (
size_t j = 0; j < realneigh.size(); ++j)
1615 if (periodic && static_cast<size_t>(neighbors[j]) >= nproc)
1617 size_t index = std::find(sentproc.begin(), sentproc.end(), realneigh[j]) - sentproc.begin();
1618 assert(index < sentproc.size());
1619 sentpoints[index].push_back(static_cast<int>(i));
1626 vector<std::pair<Vector2D, Vector2D> > cellpoints;
1627 for (
size_t j = 0; j < nproc; ++j)
1629 if (std::find(realneigh.begin(), realneigh.end(), j) != realneigh.end() || j ==
static_cast<size_t>(rank))
1631 ConvexHull(cellpoints, vproc, static_cast<int>(j));
1635 size_t index = std::find(sentproc.begin(), sentproc.end(), j) - sentproc.begin();
1636 if (index >= sentproc.size())
1638 sentproc.push_back(static_cast<int>(j));
1639 sentpoints.push_back(vector<int>(1, static_cast<int>(i)));
1642 sentpoints[index].push_back(static_cast<int>(i));
1650 vector<std::pair<Vector2D, Vector2D> > cellpoints;
1651 for (
size_t j = 0; j < nproc; ++j)
1653 ConvexHull(cellpoints, vproc, static_cast<int>(j));
1655 std::vector<Vector2D> moved_point(8, temp);
1657 moved_point[1] +=
Vector2D(-dx, 0);
1658 moved_point[2] +=
Vector2D(dx, dy);
1659 moved_point[3] +=
Vector2D(dx, -dy);
1660 moved_point[4] +=
Vector2D(-dx, dy);
1661 moved_point[5] +=
Vector2D(-dx, -dy);
1663 moved_point[7] +=
Vector2D(0, -dy);
1665 for (
size_t k = 0; k < 8; ++k)
1670 points[i] = moved_point[k];
1671 if (static_cast<int>(j) == rank)
1673 res.push_back(moved_point[k]);
1674 selfindex.push_back(i);
1677 size_t index = std::find(sentproc.begin(), sentproc.end(), j) - sentproc.begin();
1678 if (index >= sentproc.size())
1680 sentproc.push_back(static_cast<int>(j));
1681 sentpoints.push_back(vector<int>(1, static_cast<int>(i)));
1684 sentpoints[index].push_back(static_cast<int>(i));
1696 eo.
AddEntry(
"Point number", static_cast<double>(i));
1697 eo.
AddEntry(
"Point x cor", points[i].x);
1698 eo.
AddEntry(
"Point y cor", points[i].y);
1699 eo.
AddEntry(
"cpu points", static_cast<double>(rank));
1700 for (
size_t jj = 0; jj < cproc.size(); ++jj)
1702 eo.
AddEntry(
"x1", cproc[jj].first.x);
1703 eo.
AddEntry(
"y1", cproc[jj].first.y);
1704 eo.
AddEntry(
"x2", cproc[jj].second.x);
1705 eo.
AddEntry(
"y2", cproc[jj].second.y);
1707 cproc[jj].second, points[i])));
1709 for (
size_t jj = 0; jj < neigh_chull.size(); ++jj)
1711 eo.
AddEntry(
"Cell number", static_cast<double>(realneigh[jj]));
1712 for (
size_t kk = 0; kk < neigh_chull[jj].size(); ++kk)
1714 eo.
AddEntry(
"x1", neigh_chull[jj][kk].first.x);
1715 eo.
AddEntry(
"y1", neigh_chull[jj][kk].first.y);
1716 eo.
AddEntry(
"x2", neigh_chull[jj][kk].second.x);
1717 eo.
AddEntry(
"y2", neigh_chull[jj][kk].second.y);
1719 neigh_chull[jj][kk].second, points[i])));
1727 MPI_Comm_size(MPI_COMM_WORLD, &wsize);
1728 vector<int> totalk(static_cast<size_t>(wsize), 0);
1729 vector<int> scounts(totalk.size(), 1);
1730 for (
size_t i = 0; i < sentproc.size(); ++i)
1731 totalk[sentproc[i]] = 1;
1733 MPI_Reduce_scatter(&totalk[0], &nrecv, &scounts[0], MPI_INT, MPI_SUM,
1736 vector<MPI_Request> req(sentproc.size());
1737 for (
size_t i = 0; i < sentproc.size(); ++i)
1738 MPI_Isend(&wsize, 1, MPI_INT, sentproc[i], 3, MPI_COMM_WORLD, &req[i]);
1739 vector<int> talkwithme;
1740 for (
int i = 0; i < nrecv; ++i)
1743 MPI_Recv(&wsize, 1, MPI_INT, MPI_ANY_SOURCE, 3, MPI_COMM_WORLD, &status);
1744 talkwithme.push_back(status.MPI_SOURCE);
1747 MPI_Waitall(static_cast<int>(req.size()), &req[0], MPI_STATUSES_IGNORE);
1748 MPI_Barrier(MPI_COMM_WORLD);
1749 for (
size_t i = 0; i < talkwithme.size(); ++i)
1751 if (std::find(sentproc.begin(), sentproc.end(), talkwithme[i]) == sentproc.end())
1753 sentproc.push_back(talkwithme[i]);
1754 sentpoints.push_back(vector<int>());
1758 vector<vector<Vector2D> > incoming(sentproc.size());
1759 vector<vector<double> > tosend(sentproc.size());
1760 vector<double> torecv;
1764 req.resize(sentproc.size());
1765 vector<int> indeces;
1766 vector<Vector2D> cortemphilbert;
1767 for (
size_t i = 0; i < sentproc.size(); ++i)
1769 const int dest = sentproc.at(i);
1770 if (!sentpoints.at(i).empty())
1772 cortemphilbert =
VectorValues(points, sentpoints.at(i));
1773 indeces =
HilbertOrder(cortemphilbert, static_cast<int>(cortemphilbert.size()));
1774 tosend[i] = list_serialize(
VectorValues(cortemphilbert, indeces));
1777 if (tosend[i].empty())
1778 MPI_Isend(&dtemp, 1, MPI_DOUBLE, dest, 1, MPI_COMM_WORLD, &req[i]);
1780 MPI_Isend(&tosend[i][0], static_cast<int>(tosend[i].size()), MPI_DOUBLE, dest, 0, MPI_COMM_WORLD, &req[i]);
1782 for (
size_t i = 0; i < sentproc.size(); ++i)
1785 MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
1787 MPI_Get_count(&status, MPI_DOUBLE, &count);
1788 torecv.resize(static_cast<size_t>(count));
1789 MPI_Recv(&torecv[0], count, MPI_DOUBLE, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
1790 if (status.MPI_TAG == 0)
1792 size_t location =
static_cast<size_t>(std::find(sentproc.begin(), sentproc.end(), status.MPI_SOURCE) -
1794 if (location >= sentproc.size())
1796 incoming[location] = list_unserialize(torecv, vtemp);
1800 if (status.MPI_TAG != 1)
1805 MPI_Waitall(static_cast<int>(req.size()), &req[0], MPI_STATUSES_IGNORE);
1806 MPI_Barrier(MPI_COMM_WORLD);
1809 for (
size_t i = 0; i < incoming.size(); ++i)
1810 for (
size_t j = 0; j < incoming[i].size(); ++j)
1811 res.push_back(incoming[i][j]);
vector< T > unique(vector< T > const &v)
Returns a vector containing only unique elements.
Voronoi tessellation class.
double distance(Vector2D const &v1) const
Caluclates the distance from the Vector to v1.
vector< int > GetSentProcs(void) const
Returns the indeces of the processors with whom points where exchanged.
int GetOriginalIndex(int point) const
Returns the original index of the duplicated point.
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.
Edge const & GetEdge(int index) const
Returns edge (interface between cells)
vector< vector< int > > & GetDuplicatedPoints(void)
Returns the indeces of the points that where sent to other processors as ghost points.
void sort_index(const vector< T > &arr, vector< int > &res)
Returns the indeces of a sort.
bool SegmentIntersection(Edge const &edge1, Edge const &edge2, Vector2D &Intersection, double eps=1e-8)
Calculates the intersection of two edges.
int GetTotalPointNumber(void) const
Returns the total number of points (including ghost)
vector< int > Update(const vector< Vector2D > &points, const Tessellation &vproc, bool reorder=false)
Updates the tessellation.
Abstract class for tessellation.
vector< size_t > GetSelfPoint(void) const
Returns the indeces of the points that remain with the processor after the ne processor mesh is built...
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.
void write_vector(vector< double > const &v, string const &fname, int prec=6)
Writes a list of numbers to a file.
vector< Vector2D > UpdateMPIPoints(Tessellation const &vproc, int rank, vector< Vector2D > &points, OuterBoundary const *obc, vector< size_t > &selfindex, vector< int > &sentproc, vector< vector< int > > &sentpoints)
Communicate position of mesh generating points between processes.
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.
bool PointInCell(vector< Vector2D > const &cpoints, Vector2D const &vec)
Checks if a point is inside a Voronoi cell.
int get_length(void) const
Returns the number of points.
std::vector< double > const & GetValues(void) const
Returns entry values.
vector< vector< int > > const & GetSentPoints(void) const
Returns the indeces of the points that where sent to other processors.
vector< int > GetNeighbors(int index) const
Returns the indeces of the neighbors.
void output(const VoronoiMesh &v)
Outputs information from the Voronoi tessellation.
Interface between two cells.
virtual Vector2D GetMeshPoint(int index) const =0
Returns Position of mesh generating point.
void Initialise(vector< Vector2D > const &points, Tessellation const &vproc, OuterBoundary const *outer, bool reorder=true)
Initialise the tessellation.
virtual void output(const VoronoiMesh &v)
Outputs information from the Voronoi tessellation.
vector< int > GetLiteralNeighbors(int index) const
Returns the list of neighbors including ghost points.
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
vector< int > GetDuplicatedProcs(void) const
Returns the indeces of the processors with whom ghost points where exchanged.
std::string int2str(int n)
Converts an integer to a string.
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)
T pair_member(const std::pair< T, T > &p, int index)
Selects a member of std::pair.
void BuildBoundary(OuterBoundary const *obc, vector< Edge > const &edges)
Builds the boundary points.
double GetWidth(int index) const
Returns the effective width of a cell.
void ConvexHull(vector< Vector2D > &result, Tessellation const &tess, int index)
Returns the ConvexHull for a set of points.
int get_num_facet(void) const
Returns the number of facets.
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.
bool NearBoundary(int index) const
Returns if the cell is adjacent to a boundary.
void GetNeighborNeighbors(vector< int > &result, int point) const
Retrieves vicarious neighbors.
vector< Edge > & GetAllEdges(void)
Returns a reference to a list of all edges.
int GetPointNo(void) const
Get Total number of mesh generating points.
Vector2D const & GetCellCM(int index) const
Returns Position of Cell's CM.
virtual BoundaryType GetBoundaryType(void) const =0
Returns the boundary type.
int GetCorSize(void) const
Gets the size of the cor vector.
std::pair< Vector2D, Vector2D > vertices
Points at the ends of the edge.
vector< int > const & GetCellEdges(int index) const
Returns a reference to a vector<int> containing the indexes of the edges related to a cell...
const vector< Edge > & getAllEdges(void) const
Returns reference to the list of all edges.
int GetOrgIndex(int index) const
Retrieves the original index of a point (in case a point was duplicated)
Method for dumping tessellation data to hdf5 file.
void reorder(vector< T > &v, vector< size_t > const &order)
Reorder a vector according to an index vector (obtained from the 'ordered' function) ...
Vector2D get_point(size_t index) const
Returns a point.
double min(vector< double > const &v)
Returns the minimal term in a vector.
Vector2D normalize(const Vector2D &v)
Normalized a vector.
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.
int GetTotalSidesNumber(void) const
Returns the total number of faces.
VoronoiMesh * clone(void) const
Cloning function.
std::pair< int, int > neighbors
Neighboring cells.
double DistanceToEdge(Vector2D const &point, Edge const &edge)
Calculates the distance of a point to an edge.
void SetPointNo(int N)
Set the number of points.
VoronoiMesh(void)
Class default constructor.
int GetOriginalLength(void) const
Returns the original length of the points (without duplicated points)
Voronoi tessellation with MPI option.
vector< vector< int > > & GetGhostIndeces(void)
Returns the indeces of each ghost point in the vector of points that the tessellation holds...
double abs(Vector3D const &v)
Norm of a vector.
double GetVolume(int index) const
Returns the volume of a cell.
vector< Vector2D > & GetMeshPoints(void)
Returns a reference to the point vector.
void AddEntry(std::string const &field, double value)
Adds an entry to the list.
Writes tessellation data to hdf5 format.
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.
voronoi_loggers::VoronoiLogger * logger
Diagnostics method.
vector< T > RemoveList(vector< T > const &v, vector< T > const &list)
Returns only elements from vector v which are not in vector list, assumes list is sorted...
void build_delaunay(vector< Vector2D >const &vp, std::vector< std::pair< Vector2D, Vector2D > >const &cpoints)
Builds the Delaunay tessellation.
Vector2D GetMeshPoint(int index) const
Returns Position of mesh generating point.
double GetLength(void) const
Returns the length of the edge.
virtual vector< int > GetNeighbors(int index) const =0
Returns the indeces of the neighbors.
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...
void ConvexEdges(vector< int > &result, Tessellation const &tess, int index)
Returns the ConvexHull of the edges of a cell.
double fastabs(Vector2D const &v)
Norm of a vector, less accurate.
Vector2D CalcFaceVelocity(Vector2D wl, Vector2D wr, Vector2D rL, Vector2D rR, Vector2D f) const
Calculates the velocity of a single edge.
vector< Vector2D > & GetAllCM(void)
Returns the center of masses of the cells.
double x
Component in the x direction.
Vector2D zcross(Vector2D const &v)
Cross product of a vector in x,y plane with a unit vector in the z direction.
vector< Vector2D > & ChangeCor(void)
Allows to change the cor.