MeshPointsMPI.cpp
1 #include "MeshPointsMPI.hpp"
2 #include "../misc/mesh_generator.hpp"
3 #ifdef RICH_MPI
4 #include <mpi.h>
5 typedef boost::mt19937_64 gen_type;
6 
7 namespace
8 {
9  // result it : minx, maxx, miny, maxy
10  boost::array<double,4> FindMaxEdges(Tessellation const& tess)
11  {
12  int rank;
13  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
14  const vector<int>& edge_index=tess.GetCellEdges(rank);
15  const int n=static_cast<int>(edge_index.size());
16  boost::array<double,4> res;
17  res[0]=min(tess.GetEdge(edge_index[0]).vertices.first.x,
18  tess.GetEdge(edge_index[0]).vertices.second.x);
19  res[1]=max(tess.GetEdge(edge_index[0]).vertices.first.x,
20  tess.GetEdge(edge_index[0]).vertices.second.x);
21  res[2]=min(tess.GetEdge(edge_index[0]).vertices.first.y,
22  tess.GetEdge(edge_index[0]).vertices.second.y);
23  res[3]=max(tess.GetEdge(edge_index[0]).vertices.first.y,
24  tess.GetEdge(edge_index[0]).vertices.second.y);
25  for(size_t i=1;i<static_cast<size_t>(n);++i)
26  {
27  res[0]=min(min(tess.GetEdge(edge_index[i]).vertices.first.x,
28  tess.GetEdge(edge_index[i]).vertices.second.x),res[0]);
29  res[1]=max(max(tess.GetEdge(edge_index[i]).vertices.first.x,
30  tess.GetEdge(edge_index[i]).vertices.second.x),res[1]);
31  res[2]=min(min(tess.GetEdge(edge_index[i]).vertices.first.y,
32  tess.GetEdge(edge_index[i]).vertices.second.y),res[2]);
33  res[3]=max(max(tess.GetEdge(edge_index[i]).vertices.first.y,
34  tess.GetEdge(edge_index[i]).vertices.second.y),res[3]);
35  }
36  return res;
37  }
38 
39  //returns minr,maxr,minangle,maxangle
40  boost::array<double,4> GetBindingArc(vector<Vector2D> const& cpoints,
41  Vector2D const& center,Vector2D const& procpoint)
42  {
43  Edge etemp;
44  etemp.vertices.first=cpoints[0];
45  etemp.vertices.second=cpoints[1];
46  double mincellR=abs(cpoints[0]-center);
47  double maxcellR(mincellR);
48  mincellR=min(mincellR,DistanceToEdge(center,etemp));
49  int npoints=static_cast<int>(cpoints.size());
50  for(size_t i=1;i<static_cast<size_t>(npoints);++i)
51  {
52  double temp=abs(cpoints[i]-center);
53  maxcellR=max(maxcellR,temp);
54  etemp.vertices.first=cpoints[i];
55  etemp.vertices.second=cpoints[(i+1)%static_cast<size_t>(npoints)];
56  mincellR=min(min(mincellR,temp),DistanceToEdge(center,etemp));
57  }
58  // Get the maximum and minimum angles
59  double maxangle,minangle;
60  if(PointInCell(cpoints,center))
61  {
62  mincellR=0;
63  maxangle=2*M_PI;
64  minangle=0;
65  }
66  else
67  {
68  const Vector2D tocenter=procpoint-center;
69  const double Rcenter=abs(tocenter);
70  boost::array<Vector2D,3> tocheck;
71  tocheck[0]=center;
72  tocheck[1]=procpoint;
73  double minusval=0,plusval=0;
74  int minusloc=0,plusloc=0;
75  for(size_t i=0;i<static_cast<size_t>(npoints);++i)
76  {
77  tocheck[2]=cpoints[i];
78  const Vector2D tocpoint=cpoints[i]-center;
79  const double angle=acos(ScalarProd(tocenter,tocpoint)/(abs(tocpoint)*Rcenter));
81  procpoint,
82  cpoints[i]))>0)
83  {
84  if(angle>plusval)
85  {
86  plusloc=static_cast<int>(i);
87  plusval=angle;
88  }
89  }
90  else
91  {
92  if(angle>minusval)
93  {
94  minusloc=static_cast<int>(i);
95  minusval=angle;
96  }
97  }
98  }
99  minangle=atan2(cpoints[static_cast<size_t>(minusloc)].y-center.y,cpoints[static_cast<size_t>(minusloc)].x-center.x);
100  minangle=(minangle<0) ? (minangle+2*M_PI) : minangle;
101  maxangle=atan2(cpoints[static_cast<size_t>(plusloc)].y-center.y,cpoints[static_cast<size_t>(plusloc)].x-center.x);
102  maxangle=(maxangle<0) ? (maxangle+2*M_PI) : maxangle;
103  if(maxangle<minangle)
104  minangle-=2*M_PI;
105  }
106  boost::array<double,4> res;
107  res[0]=mincellR;
108  res[1]=maxcellR;
109  res[2]=minangle;
110  res[3]=maxangle;
111  return res;
112  }
113 }
114 
115 vector<Vector2D> RandSquare(int npoints,Tessellation const& tess,
116  Vector2D const& lowerleft,Vector2D const& upperright)
117 {
118  boost::array<double,4> tessEdges=FindMaxEdges(tess);
119  if (tessEdges[0]>upperright.x || tessEdges[1]<lowerleft.x || tessEdges[2]>upperright.y ||
120  tessEdges[3] < lowerleft.y)
121  return vector<Vector2D>();
122  int rank;
123  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
124  const double myarea = tess.GetVolume(rank);
125  const double Area = (upperright.x - lowerleft.x)*(upperright.y - lowerleft.y);
126  int mypoints=static_cast<int>(floor(npoints*myarea/Area+0.5));
127  vector<Vector2D> res;
128  res.reserve(static_cast<size_t>(mypoints));
129  vector<std::pair<Vector2D, Vector2D> > cpoints;
130  ConvexHull(cpoints,tess,rank);
131  double ran[2];
132  gen_type gen(static_cast<size_t>(rank));
133  boost::random::uniform_real_distribution<> dist;
134  // change aboev to have seed==rank
135  while(static_cast<int>(res.size())<mypoints)
136  {
137  ran[0]=dist(gen)*(tessEdges[1]-tessEdges[0])+tessEdges[0];
138  ran[1]=dist(gen)*(tessEdges[3]-tessEdges[2])+tessEdges[2];
139  Vector2D p(ran[0],ran[1]);
140  if(PointInCell(cpoints,p))
141  res.push_back(p);
142  }
143  return res;
144 }
145 
146 vector<Vector2D> SquareMeshM(int nx,int ny,Tessellation const& tess,
147  Vector2D const&lowerleft,Vector2D const&upperright)
148 {
149  const double widthx = (upperright.x-lowerleft.x)/static_cast<double>(nx);
150  const double widthy = (upperright.y-lowerleft.y)/static_cast<double>(ny);
151  const boost::array<double,4> tessEdges=FindMaxEdges(tess);
152  nx=static_cast<int>(floor((tessEdges[1]-tessEdges[0])/widthx+2));
153  ny=static_cast<int>(floor((tessEdges[3]-tessEdges[2])/widthy+2));
154  vector<Vector2D> res;
155  res.reserve(static_cast<size_t>(nx*ny));
156  const int nx0=static_cast<int>(floor((tessEdges[0]-lowerleft.x)/widthx-0.5));
157  const int ny0=static_cast<int>(floor((tessEdges[2]-lowerleft.y)/widthy-0.5));
158  Vector2D point;
159  int rank;
160  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
161  vector< std::pair<Vector2D, Vector2D> > cpoints;
162  ConvexHull(cpoints,tess,rank);
163  for(int i=0;i<nx;i++)
164  {
165  for(int j=0;j<ny;j++)
166  {
167  point.x = (static_cast<double>(i)+0.5+nx0)*widthx+lowerleft.x;
168  point.y = (static_cast<double>(j)+0.5+ny0)*widthy+lowerleft.y;
169  if((point.x<lowerleft.x)||(point.x>upperright.x)||
170  (point.y<lowerleft.y)||(point.y>upperright.y))
171  continue;
172  if(PointInCell(cpoints,point))
173  res.push_back(point);
174  }
175  }
176  return res;
177 }
178 
179 vector<Vector2D> CirclePointsRmaxM(int PointNum,double Rmin,double Rmax,
180  Vector2D const& /*bottomleft*/,
181  Vector2D const& /*topright*/,
182  Tessellation const& tess,double xc,double yc)
183 {
184  double A=sqrt(M_PI*(Rmax*Rmax-Rmin*Rmin)/PointNum);
185  int Nr=int((Rmax-Rmin)/A);
186  double dr=(Rmax-Rmin)/Nr;
187  int rank;
188  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
189  vector< std::pair < Vector2D, Vector2D> >cpoints;
190  vector<Vector2D> cpoints2;
191  ConvexHull(cpoints,tess,rank);
192  ConvexHull(cpoints2, tess, rank);
193  boost::array<double,4> arc=GetBindingArc(cpoints2,Vector2D(xc,yc),
194  tess.GetMeshPoint(rank));
195  double mincellR=max(min(arc[0],Rmax),Rmin);
196  double maxcellR=max(min(arc[1],Rmax),Rmin);
197  double minangle=arc[2];
198  double maxangle=arc[3];
199  int nrmin=static_cast<int>((mincellR-Rmin)/dr);
200  int nrmax=static_cast<int>((maxcellR-Rmin)/dr+0.5);
201  vector<Vector2D> res;
202  for(int i=nrmin;i<nrmax;++i)
203  {
204  double r=Rmin+i*dr;
205  double dphi=A/r;
206  int phimin=static_cast<int>(minangle/dphi);
207  int phimax=static_cast<int>(maxangle/dphi+0.5);
208  for(int j=phimin;j<phimax;++j)
209  {
210  Vector2D temp(Vector2D(r*cos(dphi*j)+xc,r*sin(dphi*j)+yc));
211  if(PointInCell(cpoints,temp))
212  res.push_back(temp);
213  }
214  }
215  return res;
216 }
217 
218 vector<Vector2D> CirclePointsRmax_aM(int PointNum,double Rmin,double Rmax,
219  double xc,double yc,double alpha,Tessellation const& tess)
220 {
221  double N0=sqrt(PointNum*4*M_PI*(alpha+1)/(pow(Rmax,2*(alpha+1))-
222  pow(Rmin,2*(alpha+1))));
223  Vector2D pos;
224  vector<Vector2D> res;
225  int rank;
226  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
227  vector< std::pair < Vector2D, Vector2D> >cpoints;
228  vector<Vector2D> cpoints2;
229  ConvexHull(cpoints, tess, rank);
230  ConvexHull(cpoints2, tess, rank);
231  boost::array<double, 4> arc = GetBindingArc(cpoints2, Vector2D(xc, yc),
232  tess.GetMeshPoint(rank));
233  double mincellR=max(min(arc[0],Rmax),Rmin);
234  double maxcellR=max(min(arc[1],Rmax),Rmin);
235  double minangle=arc[2];
236  double maxangle=arc[3];
237  int nrmin=static_cast<int>((pow(max(mincellR,Rmin),alpha+1)-pow(Rmin,alpha+1))/(2*M_PI*(alpha+1)/N0));
238  int nrmax=static_cast<int>((pow(min(maxcellR,Rmax),alpha+1)-pow(Rmin,alpha+1))/(2*M_PI*(alpha+1)/N0)+0.5);
239  for(int i=nrmin;i<nrmax;++i)
240  {
241  const double r=pow(2*M_PI*i*(alpha+1)/N0+pow(Rmin,alpha+1),1.0/(alpha+1));
242  const int Nphi=int(floor(N0*pow(r,1+alpha)+1.5));
243  const double dphi=2*M_PI/Nphi;
244  int phimin=static_cast<int>(minangle/dphi);
245  int phimax=static_cast<int>(maxangle/dphi+1);
246  for(int j=phimin;j<phimax;++j)
247  {
248  pos.Set(r*cos(dphi*j)+xc,r*sin(dphi*j)+yc);
249  if(PointInCell(cpoints,pos))
250  res.push_back(pos);
251  }
252  }
253  return res;
254 }
255 
256 vector<Vector2D> circle_circumferenceM(int point_number,double radius,
257  Vector2D const& center,Tessellation const& tproc)
258 {
259  vector<Vector2D> res;
260  int rank;
261  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
262  vector<std::pair<Vector2D, Vector2D> > cpoints;
263  ConvexHull(cpoints,tproc,rank);
264  for(int i=0;i<point_number;++i)
265  {
266  const double angle = 2*M_PI*double(i)/double(point_number);
267  Vector2D temp= center+pol2cart(radius,angle);
268  if(PointInCell(cpoints,temp))
269  res.push_back(temp);
270  }
271  return res;
272 }
273 
274 #endif
Generates grids for parallel simulations.
vector< Vector2D > CirclePointsRmaxM(int PointNum, double Rmin, double Rmax, Vector2D const &bottomleft, Vector2D const &topright, Tessellation const &tess, double xc=0, double yc=0)
Generates a round grid with constant point density.
vector< Vector2D > SquareMeshM(int nx, int ny, Tessellation const &tess, Vector2D const &lower_left, Vector2D const &upper_right)
Creates a cartesian mesh for MPI.
Abstract class for tessellation.
bool PointInCell(vector< Vector2D > const &cpoints, Vector2D const &vec)
Checks if a point is inside a Voronoi cell.
vector< Vector2D > CirclePointsRmax_aM(int PointNum, double Rmin, double Rmax, double xc, double yc, double alpha, Tessellation const &tess)
Generates a round grid with r^alpha point density.
Interface between two cells.
Definition: Edge.hpp:13
virtual Vector2D GetMeshPoint(int index) const =0
Returns Position of mesh generating point.
double max(vector< double > const &v)
returns the maximal term in a vector
Definition: utils.cpp:52
double y
Component in the y direction.
Definition: geometry.hpp:48
A collection of three identical references.
Definition: triplet.hpp:12
virtual Edge const & GetEdge(int index) const =0
Returns edge (interface between cells)
vector< Vector2D > circle_circumferenceM(int point_number, double radius, Vector2D const &center, Tessellation const &tproc)
Creates a circle of evenly spaced points.
void ConvexHull(vector< Vector2D > &result, Tessellation const &tess, int index)
Returns the ConvexHull for a set of points.
Definition: ConvexHull.cpp:31
Vector2D pol2cart(double radius, double angle)
Converts from polar coordinates to cartesian coordinates.
Definition: geometry.cpp:150
double ScalarProd(Vector3D const &v1, Vector3D const &v2)
Scalar product of two vectors.
Definition: Vector3D.cpp:185
std::pair< Vector2D, Vector2D > vertices
Points at the ends of the edge.
Definition: Edge.hpp:18
double min(vector< double > const &v)
Returns the minimal term in a vector.
Definition: utils.cpp:44
virtual double GetVolume(int index) const =0
Returns the volume of a cell.
void Set(double ix, double iy)
Set vector components.
Definition: geometry.cpp:39
std::vector< Vector2D > RandSquare(int PointNum, Vector2D const &lowerleft, Vector2D const &upperright)
Generates a random rectangular grid with uniform point density and a constant seed.
double DistanceToEdge(Vector2D const &point, Edge const &edge)
Calculates the distance of a point to an edge.
Definition: Edge.cpp:31
double abs(Vector3D const &v)
Norm of a vector.
Definition: Vector3D.cpp:44
virtual vector< int > const & GetCellEdges(int index) const =0
Returns the indexes of a cell&#39;s edges.
2D Mathematical vector
Definition: geometry.hpp:15
double orient2d(const TripleConstRef< Vector2D > &points)
Checks whether 3 given points are on a counterclockwise circle, clockwise circle or colinear...
Definition: geotests.cpp:76
double x
Component in the x direction.
Definition: geometry.hpp:45