mesh_generator.cpp
1 #include "mesh_generator.hpp"
2 
3 using namespace std;
4 typedef boost::mt19937_64 base_generator_type;
5 
6 std::vector<Vector2D> RandSquare(int PointNum, Vector2D const& lowerleft, Vector2D const& upperright)
7 {
8  return RandSquare(PointNum, lowerleft.x, upperright.x, lowerleft.y, upperright.y);
9 }
10 
11 vector<Vector2D> RandPointsRmax(int PointNum, double Rmin, double Rmax,
12  double xc, double yc)
13 {
14  double ran[2];
15  int counter = 0;
16  vector<Vector2D> res;
17  Vector2D point;
18  base_generator_type generator;
19  boost::random::uniform_real_distribution<> dist;
20  while (counter < PointNum)
21  {
22  ran[0] = dist(generator);
23  ran[1] = dist(generator);
24  point.x = ((Rmax - Rmin)*ran[0] + Rmin)*cos(ran[1] * 2 * M_PI) + xc;
25  point.y = ((Rmax - Rmin)*ran[0] + Rmin)*sin(ran[1] * 2 * M_PI) + yc;
26  res.push_back(point);
27  ++counter;
28  }
29  return res;
30 }
31 
32 vector<Vector2D> RandSquare(int PointNum, double xl, double xr, double yd,
33  double yu)
34 {
35  double ran[2];
36  double xc = xr - xl;
37  double yc = yu - yd;
38  vector<Vector2D> res;
39  Vector2D point;
40  base_generator_type generator;
41  boost::random::uniform_real_distribution<> dist;
42  for (int i = 0; i < PointNum; ++i)
43  {
44  ran[0] = dist(generator);
45  ran[1] = dist(generator);
46  point.x = ran[0] * xc + xl;
47  point.y = ran[1] * yc + yd;
48  res.push_back(point);
49  }
50  return res;
51 }
52 
53 vector<Vector2D> RandSquare(int PointNum, boost::random::mt19937 &eng, double xl, double xr, double yd,
54  double yu)
55 {
56  double ran[2];
57  double xc = xr - xl;
58  double yc = yu - yd;
59  vector<Vector2D> res;
60  Vector2D point;
61  boost::random::uniform_real_distribution<> dist;
62  for (int i = 0; i < PointNum; ++i)
63  {
64  ran[0] = dist(eng);
65  ran[1] = dist(eng);
66  point.x = ran[0] * xc + xl;
67  point.y = ran[1] * yc + yd;
68  res.push_back(point);
69  }
70  return res;
71 }
72 
73 vector<Vector2D> RandPointsRa(int PointNum, double Rmin, double Rmax, double alpha,
74  Vector2D const& lowerleft, Vector2D const& upperright, Vector2D const& center)
75 {
76  base_generator_type generator;
77  boost::random::uniform_real_distribution<> dist;
78  double ran[2];
79  double A = pow(Rmax*Rmin, alpha)*(alpha - 1) / (pow(Rmax, alpha)*Rmin - Rmax*pow(Rmin, alpha));
80  int counter = 0;
81  vector<Vector2D> res;
82  Vector2D point;
83  res.reserve(static_cast<size_t>(PointNum));
84  while (counter < PointNum)
85  {
86  ran[0] = pow(pow(Rmin, 1 - alpha) - dist(generator)*(alpha - 1) / A, 1.0 / (1 - alpha));
87  ran[1] = dist(generator);
88  point.x = ran[0] * cos(ran[1] * 2 * M_PI) + center.x;
89  point.y = ran[0] * sin(ran[1] * 2 * M_PI) + center.y;
90  if ((point.x<upperright.x) && (point.x>lowerleft.x) && (point.y < upperright.y)
91  && (point.y > lowerleft.y))
92  {
93  res.push_back(point);
94  ++counter;
95  }
96  }
97  return res;
98 }
99 
100 vector<Vector2D> RandPointsR(int PointNum, double xl, double xr, double yd,
101  double yu, double minR, double xc, double yc)
102 {
103  double ran[2];
104  int counter = 0;
105  double maxR = sqrt(2.0)*max(max(max(xr - xc, yu - yc), yc - yd), xc - xl);
106  vector<Vector2D> res;
107  Vector2D point;
108  base_generator_type generator;
109  boost::random::uniform_real_distribution<> dist;
110  while (counter < PointNum)
111  {
112  ran[0] = dist(generator);
113  ran[1] = dist(generator);
114  point.x = maxR*ran[0] * cos(ran[1] * 2 * M_PI) + xc;
115  point.y = maxR*ran[0] * sin(ran[1] * 2 * M_PI) + yc;
116  if (abs(point) > minR)
117  {
118  if (point.x > xl&&point.x<xr)
119  if (point.y>yd&&point.y < yu)
120  {
121  res.push_back(point);
122  ++counter;
123  }
124  }
125  }
126  return res;
127 }
128 
129 vector<Vector2D> CirclePointsRmax_1(int PointNum, double Rmin, double Rmax,
130  double xc, double yc, double xmax, double ymax, double xmin, double ymin)
131 {
132  const double Nphid = sqrt(PointNum * 2 * M_PI / log(Rmax / Rmin));
133  const int Nr = static_cast<int>(Nphid*log(Rmax / Rmin) / (2 * M_PI));
134  const int Nphi = static_cast<int>(floor(Nphid + 0.5));
135  const double dphi = 2 * M_PI / Nphi;
136  vector<Vector2D> res;
137  for (int i = 0; i < Nr; ++i)
138  {
139  const double r = Rmin*exp(2 * M_PI*i / Nphi);
140  for (int j = 0; j < Nphi; ++j)
141  {
142  const Vector2D pos(r*cos(dphi*j) + xc, r*sin(dphi*j) + yc);
143  if (pos.x<xmax&&pos.x>xmin && pos.y<ymax&&pos.y>ymin)
144  res.push_back(pos);
145  }
146  }
147  return res;
148 }
149 
150 vector<Vector2D> CirclePointsRmax_2(int PointNum, double Rmin, double Rmax,
151  double xc, double yc, double xmax, double ymax, double xmin, double ymin)
152 {
153  const double x = sqrt(Rmin / Rmax);
154  const int Nr = int(sqrt(2 * PointNum*(1 - x) / (1 + x) / M_PI));
155  const double A = 4 * pow(1 / sqrt(Rmin) - 1 / sqrt(Rmax), 2) / (Nr*Nr);
156  vector<Vector2D> res;
157  for (int i = 0; i < Nr; ++i)
158  {
159  const double r = 4 * Rmin / pow(2 - sqrt(A*Rmin)*i, 2);
160  const double Nphi = int(2 * M_PI / sqrt(A*r));
161  const double dphi = double(2 * M_PI / Nphi);
162  for (int j = 0; j < Nphi; ++j)
163  {
164  const Vector2D pos(r*cos(dphi*j) + xc, r*sin(dphi*j) + yc);
165  if (pos.x<xmax&&pos.x>xmin && pos.y<ymax&&pos.y>ymin)
166  res.push_back(pos);
167  }
168  }
169  return res;
170 }
171 
172 vector<Vector2D> CirclePointsRmax(int PointNum, double Rmin, double Rmax,
173  double xmax, double ymax, double xmin, double ymin, double xc, double yc)
174 {
175  const double A = sqrt(M_PI*(Rmax*Rmax - Rmin*Rmin) / PointNum);
176  const int Nr = int((Rmax - Rmin) / A);
177  const double dr = (Rmax - Rmin) / Nr;
178  vector<Vector2D> res;
179  for (int i = 0; i < Nr; ++i)
180  {
181  const double r = Rmin + i*dr;
182  const int Nphi = int(2 * M_PI*r / A);
183  const double dphi = A / r;
184  for (int j = 0; j < Nphi; ++j)
185  {
186  const Vector2D pos(r*cos(dphi*j) + xc, r*sin(dphi*j) + yc);
187  if (pos.x<xmax&&pos.x>xmin && pos.y<ymax&&pos.y>ymin)
188  res.push_back(pos);
189  }
190  }
191  return res;
192 }
193 
194 vector<Vector2D> cartesian_mesh(int nx, int ny,
195  Vector2D const& lower_left,
196  Vector2D const& upper_right)
197 {
198  assert(nx > 0);
199  assert(ny > 0);
200  assert(upper_right.x > lower_left.x);
201  assert(upper_right.y > lower_left.y);
202 
203  vector<Vector2D> res;
204  const double dx = (upper_right.x - lower_left.x) /
205  static_cast<double>(nx);
206  const double dy = (upper_right.y - lower_left.y) /
207  static_cast<double>(ny);
208  for (double x = lower_left.x + 0.5*dx; x < upper_right.x; x += dx){
209  for (double y = lower_left.y + 0.5*dy; y < upper_right.y; y += dy)
210  res.push_back(Vector2D(x, y));
211  }
212  return res;
213 }
214 
215 vector<Vector2D> circle_circumference
216 (size_t point_number,
217 double radius,
218 Vector2D const& center, double angle_start, double angle_end)
219 {
220  vector<Vector2D> res(point_number);
221  for (size_t i = 0; i < point_number; ++i)
222  {
223  const double angle = (angle_end - angle_start) * double(i) / double(point_number) + angle_start;
224  res[i] = center + pol2cart(radius, angle);
225  }
226  return res;
227 }
228 
229 vector<Vector2D> Line(int PointNum, double xmin, double xmax, double ymin, double ymax)
230 {
231  double dy = ymax - ymin, dx = xmax - xmin;
232  double angle = atan2(dy, dx);
233  double length = sqrt(dy*dy + dx*dx);
234  double dl = length / PointNum;
235 
236  vector<Vector2D> res;
237  Vector2D temp;
238 
239  for (int i = 0; i < PointNum; ++i)
240  {
241  temp.Set(xmin + dl*(i + 0.5)*cos(angle), ymin + dl*(i + 0.5)*sin(angle));
242  res.push_back(temp);
243  }
244  return res;
245 }
246 
247 vector<Vector2D> CirclePointsRmax_a(int PointNum,
248  double Rmin,
249  double Rmax,
250  double xc,
251  double yc,
252  double xmax,
253  double ymax,
254  double xmin,
255  double ymin,
256  double alpha, double angle_start, double angle_end)
257 {
258  const double N0 = sqrt(PointNum * 4 * M_PI*(alpha + 1) /
259  (pow(Rmax, 2 * (alpha + 1)) -
260  pow(Rmin, 2 * (alpha + 1))));
261  const int Nr = int(floor((pow(Rmax, alpha + 1) -
262  pow(Rmin, alpha + 1))*N0 / (2 * M_PI*(alpha + 1))));
263  vector<Vector2D> res;
264  for (int i = 0; i < Nr; ++i)
265  {
266  const double r = pow(2 * M_PI*i*(alpha + 1) / N0 +
267  pow(Rmin, alpha + 1), 1.0 / (alpha + 1));
268  const int Nphi = int(floor(N0*pow(r, 1 + alpha) + 1.5));
269  const double dphi = 2 * M_PI / Nphi;
270  double cur_phi = angle_start;
271  while(cur_phi < angle_end)
272  {
273  const Vector2D pos(r*cos(cur_phi) + xc, r*sin(cur_phi) + yc);
274  if (pos.x<xmax&&pos.x>xmin && pos.y<ymax&&pos.y>ymin)
275  res.push_back(pos);
276  cur_phi += dphi;
277  }
278  }
279  return res;
280 }
std::vector< Vector2D > Line(int PointNum, double xmin, double xmax, double ymin, double ymax)
Creates a line of evenly spaced points y=slope*x+b.
std::vector< Vector2D > CirclePointsRmax_2(int PointNum, double Rmin, double Rmax, double xc=0, double yc=0, double xmax=1, double ymax=1, double xmin=-1, double ymin=1)
Generates a round grid with 1/r^2 point density confined to a rectangle given by xmin,xmax,ymin and ymax.
boost::mt19937_64 base_generator_type
Alias for random number generator.
std::vector< Vector2D > circle_circumference(size_t point_number, double radius, Vector2D const &center, double angle_start=0, double angle_end=2 *M_PI)
Creates a circle of evenly spaced points.
std::vector< Vector2D > CirclePointsRmax_1(int PointNum, double Rmin, double Rmax, double xc=0, double yc=0, double xmax=1, double ymax=1, double xmin=-1, double ymin=-1)
Generates a round grid with 1/r point density confined to a rectangle given by xmin,xmax,ymin and ymax.
std::vector< Vector2D > RandPointsR(int PointNum, double xl=-0.5, double xr=0.5, double yd=-0.5, double yu=0.5, double minR=0, double xc=0, double yc=0)
Generates a rectangular grid with random 1/r point density.
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
Vector2D pol2cart(double radius, double angle)
Converts from polar coordinates to cartesian coordinates.
Definition: geometry.cpp:150
Set of functions to generate points.
std::vector< Vector2D > CirclePointsRmax_a(int PointNum, double Rmin, double Rmax, double xc, double yc, double xmax, double ymax, double xmin, double ymin, double alpha, double angle_start=0, double angle_end=2 *M_PI)
Generates a round grid with r^alpha point density confined to a rectangle given by xmin...
void Set(double ix, double iy)
Set vector components.
Definition: geometry.cpp:39
std::vector< Vector2D > RandPointsRa(int PointNum, double Rmin, double Rmax, double alpha, Vector2D const &lowerleft, Vector2D const &upperright, Vector2D const &center=Vector2D(0, 0))
Generates a random round grid with r^(1-a) point density.
std::vector< Vector2D > cartesian_mesh(int nx, int ny, Vector2D const &lower_left, Vector2D const &upper_right)
Generates a cartesian mesh.
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 abs(Vector3D const &v)
Norm of a vector.
Definition: Vector3D.cpp:44
std::vector< Vector2D > RandPointsRmax(int PointNum, double Rmin, double Rmax, double xc=0, double yc=0)
Generates a random round grid with 1/r point density.
2D Mathematical vector
Definition: geometry.hpp:15
std::vector< Vector2D > CirclePointsRmax(int PointNum, double Rmin, double Rmax, double xmax, double ymax, double xmin, double ymin, double xc=0, double yc=0)
Generates a round grid with constant point density.
double x
Component in the x direction.
Definition: geometry.hpp:45