20 void ResizeLatticePositions(std::vector<std::vector<double>>& lattice_positions,
double l1,
21 double l2,
double layer_size);
22 void FindLatticePositionsIndex(
size_t& index,
size_t& index_prev,
int i,
int j,
int size,
24 std::pair<double, double> ComputePositionAlongPositiveLatticeVector(
25 const size_t index_prev, std::vector<std::vector<double>>& lattice_positions,
27 std::pair<double, double> ComputePositionAlongNegativeLatticeVector(
28 const size_t index_prev, std::vector<std::vector<double>>& lattice_positions,
30 std::pair<double, double>
31 ComputeLatticePosition(
const size_t index_prev,
int i,
int j,
32 std::vector<std::vector<double>>& lattice_positions,
34 void ComputePositionsAlongLatticeVectorAxes(std::vector<std::vector<double>>& lattice_positions,
37 void ComputePositionsInsideLatticeQuadrants(std::vector<std::vector<double>>& lattice_positions,
40 double l_xi,
double l_alpha);
46 auto& lattice = p_iff->
lattice();
48 double l2 = lattice.length2();
49 double alpha = lattice.latticeAngle();
50 double xi = lattice.rotationAngle();
52 std::vector<std::vector<double>> lattice_positions;
53 ResizeLatticePositions(lattice_positions, l1, l2, layer_size);
55 ComputePositionsAlongLatticeVectorAxes(lattice_positions, p_iff->
pdf1(), l1, xi, 0);
57 ComputePositionsAlongLatticeVectorAxes(lattice_positions, p_iff->
pdf2(), l2, xi, alpha);
59 ComputePositionsInsideLatticeQuadrants(lattice_positions, p_iff->
pdf1(), p_iff->
pdf2(), l1, l2,
62 return lattice_positions;
66 void ResizeLatticePositions(std::vector<std::vector<double>>& lattice_positions,
double l1,
67 double l2,
double layer_size)
72 n1 = l1 == 0.0 ? 2 :
static_cast<int>(layer_size * 2 / l1);
73 n2 = l2 == 0.0 ? 2 :
static_cast<int>(layer_size * 2 / l2);
75 n1 = std::max(n1, n2);
77 lattice_positions.resize(
static_cast<size_t>((2 * n1 + 1) * (2 * n1 + 1)));
78 for (
auto& it : lattice_positions) {
82 lattice_positions[0][0] = 0.0;
83 lattice_positions[0][1] = 0.0;
86 void FindLatticePositionsIndex(
size_t& index,
size_t& index_prev,
int i,
int j,
int size,
89 index =
static_cast<size_t>(i * (2 * size + 1) + j);
91 if (std::sin(l_alpha) == 0)
95 index_prev =
static_cast<size_t>(i * (2 * size + 1));
97 index_prev = index - 2;
101 index_prev =
static_cast<size_t>(j);
103 index_prev = index -
static_cast<size_t>(2 * (2 * size + 1));
107 std::pair<double, double> ComputePositionAlongPositiveLatticeVector(
108 const size_t index_prev, std::vector<std::vector<double>>& lattice_positions,
111 double gamma_pdf = pdf->
gamma();
112 std::pair<double, double> sampleXYpdf = pdf->
createSampler()->randomSample();
114 double offset_x_pdf = sampleXYpdf.first;
115 double offset_y_pdf = sampleXYpdf.second;
117 double x = lattice_positions[index_prev][0] + l * std::cos(l_xi + l_alpha)
118 + offset_x_pdf * std::cos(gamma_pdf + l_xi)
119 + offset_y_pdf * std::cos(
M_PI_2 + gamma_pdf + l_xi);
120 double y = lattice_positions[index_prev][1] + l * std::sin(l_xi + l_alpha)
121 + offset_x_pdf * std::sin(gamma_pdf + l_xi)
122 + offset_y_pdf * std::sin(
M_PI_2 + gamma_pdf + l_xi);
124 return std::make_pair(x, y);
127 std::pair<double, double> ComputePositionAlongNegativeLatticeVector(
128 const size_t index_prev, std::vector<std::vector<double>>& lattice_positions,
131 double gamma_pdf = pdf->
gamma();
132 std::pair<double, double> sampleXYpdf = pdf->
createSampler()->randomSample();
134 double offset_x_pdf = sampleXYpdf.first;
135 double offset_y_pdf = sampleXYpdf.second;
137 double x = lattice_positions[index_prev][0] - l * std::cos(l_xi + l_alpha)
138 + offset_x_pdf * std::cos(gamma_pdf + l_xi)
139 + offset_y_pdf * std::cos(
M_PI_2 + gamma_pdf + l_xi);
140 double y = lattice_positions[index_prev][1] - l * std::sin(l_xi + l_alpha)
141 + offset_x_pdf * std::sin(gamma_pdf + l_xi)
142 + offset_y_pdf * std::sin(
M_PI_2 + gamma_pdf + l_xi);
144 return std::make_pair(x, y);
147 std::pair<double, double>
148 ComputeLatticePosition(
const size_t index_prev,
int i,
int j,
149 std::vector<std::vector<double>>& lattice_positions,
152 if (std::sin(l_alpha) == 0) {
154 return ComputePositionAlongPositiveLatticeVector(index_prev, lattice_positions, pdf, l,
157 return ComputePositionAlongNegativeLatticeVector(index_prev, lattice_positions, pdf, l,
161 return ComputePositionAlongPositiveLatticeVector(index_prev, lattice_positions, pdf, l,
164 return ComputePositionAlongNegativeLatticeVector(index_prev, lattice_positions, pdf, l,
169 void ComputePositionsAlongLatticeVectorAxes(std::vector<std::vector<double>>& lattice_positions,
173 int n =
static_cast<int>((std::sqrt(lattice_positions.size()) - 1) / 2);
176 size_t index_prev = 0;
178 std::pair<double, double> xy;
180 for (
int iter = 1; iter <= 2 * n; ++iter) {
184 if (std::sin(l_alpha) == 0) {
198 FindLatticePositionsIndex(index, index_prev, iterl2, iterl1, n, l_alpha);
199 xy = ComputeLatticePosition(index_prev, iterl2, iterl1, lattice_positions, pdf, l, l_xi,
202 lattice_positions[index][0] = xy.first;
203 lattice_positions[index][1] = xy.second;
207 void ComputePositionsInsideLatticeQuadrants(std::vector<std::vector<double>>& lattice_positions,
210 double l_xi,
double l_alpha)
212 int n =
static_cast<int>((std::sqrt(lattice_positions.size()) - 1) / 2);
215 size_t index_prev = 0;
217 std::pair<double, double> xy_l1, xy_l2;
219 for (
int i = 1; i <= 2 * n; ++i) {
220 for (
int j = 1; j <= 2 * n; ++j) {
221 FindLatticePositionsIndex(index, index_prev, i, j, n, 0);
222 xy_l1 = ComputeLatticePosition(index_prev, i, j, lattice_positions, pdf1, l1, l_xi, 0);
224 FindLatticePositionsIndex(index, index_prev, i, j, n, l_alpha);
225 xy_l2 = ComputeLatticePosition(index_prev, i, j, lattice_positions, pdf2, l2, l_xi,
228 lattice_positions[index][0] = (xy_l1.first + xy_l2.first) / 2;
229 lattice_positions[index][1] = (xy_l1.second + xy_l2.second) / 2;
Defines class InterferenceFunction2DParaCrystal.
Defines RealSpaceBuilderUtils namespace.
Defines class RealSpaceCanvas.
Interface for two-dimensional distributions in Fourier space.
virtual std::unique_ptr< IDistribution2DSampler > createSampler() const =0
Interference function of a 2D paracrystal.
const IFTDistribution2D * pdf1() const
const IFTDistribution2D * pdf2() const
const Lattice2D & lattice() const
virtual double length1() const =0
std::vector< std::vector< double > > Compute2DParacrystalLatticePositions(const InterferenceFunction2DParaCrystal *, double layer_size)