22 std::vector<std::vector<double>> Generate2DLatticePoints(
double l1,
double l2,
double alpha,
23 double xi,
unsigned n1,
unsigned n2);
35 std::random_device rd;
36 std::mt19937 gen(rd());
37 std::normal_distribution<double> dis(0.0, std::sqrt(pos_var));
38 for (
auto& position : positions) {
39 for (
auto& coordinate : position)
40 coordinate += dis(gen);
52 std::vector<double> origin = {0.0, 0.0};
68 std::vector<std::vector<double>> lattice_positions;
69 std::vector<double> position;
73 int num_particles =
static_cast<int>(density * (2 * layer_size) * (2 * layer_size));
76 std::random_device rd;
77 std::mt19937 gen(rd());
78 std::uniform_real_distribution<double> dis(0.0, 1.0);
80 for (
int i = 1; i <= num_particles; ++i) {
82 position.push_back(dis(gen) * 2 * layer_size - layer_size);
83 position.push_back(dis(gen) * 2 * layer_size - layer_size);
85 lattice_positions.push_back(position);
88 return lattice_positions;
97 : m_iff(p_iff->clone())
106 const double length =
m_iff->getLength();
107 const double xi =
m_iff->getXi();
112 length == 0.0 ? 2 :
static_cast<unsigned>(2.0 * layer_size * std::sqrt(2.0) / length);
114 return Generate2DLatticePoints(length, 0.0, 0.0, xi, n1, 1u);
119 return m_iff->positionVariance();
123 : m_iff(p_iff->clone())
132 auto& lattice =
m_iff->lattice();
133 double l1 = lattice.length1();
134 double l2 = lattice.length2();
135 double alpha = lattice.latticeAngle();
136 double xi = lattice.rotationAngle();
141 double sina = std::abs(std::sin(alpha));
143 n1 = l1 == 0.0 ? 2 :
static_cast<unsigned>(2.0 * layer_size * std::sqrt(2.0) / l1);
144 n2 = l2 == 0.0 ? 2 :
static_cast<unsigned>(2.0 * layer_size * std::sqrt(2.0) / l2);
146 n1 = l1 == 0.0 ? 2 :
static_cast<unsigned>(2.0 * layer_size * std::sqrt(2.0) / l1 / sina);
147 n2 = l2 == 0.0 ? 2 :
static_cast<unsigned>(2.0 * layer_size * std::sqrt(2.0) / l2 / sina);
149 return Generate2DLatticePoints(l1, l2, alpha, xi, n1, n2);
154 return m_iff->positionVariance();
159 : m_iff(p_iff->clone())
165 std::vector<std::vector<double>>
174 return m_iff->positionVariance();
179 : m_iff(p_iff->clone())
185 std::vector<std::vector<double>>
188 auto& lattice =
m_iff->lattice();
189 double l1 = lattice.length1();
190 double l2 = lattice.length2();
191 double alpha = lattice.latticeAngle();
192 double xi = lattice.rotationAngle();
195 double sina = std::abs(std::sin(alpha));
197 n1 = l1 == 0.0 ? 2 :
static_cast<unsigned>(2.0 * layer_size * std::sqrt(2.0) / l1);
198 n2 = l2 == 0.0 ? 2 :
static_cast<unsigned>(2.0 * layer_size * std::sqrt(2.0) / l2);
200 n1 = l1 == 0.0 ? 2 :
static_cast<unsigned>(2.0 * layer_size * std::sqrt(2.0) / l1 / sina);
201 n2 = l2 == 0.0 ? 2 :
static_cast<unsigned>(2.0 * layer_size * std::sqrt(2.0) / l2 / sina);
203 n1 = std::min(n1,
m_iff->numberUnitCells1());
204 n2 = std::min(n2,
m_iff->numberUnitCells2());
206 return Generate2DLatticePoints(l1, l2, alpha, xi, n1, n2);
211 return m_iff->positionVariance();
216 : m_iff(p_iff->clone())
222 std::vector<std::vector<double>>
225 std::vector<std::vector<double>> lattice_positions;
227 double distance =
m_iff->peakDistance();
231 int n = distance <= 0.0 ? 1 :
static_cast<int>(layer_size * std::sqrt(2.0) / distance);
233 lattice_positions.resize(
static_cast<size_t>(2 * n + 1));
234 for (
auto& it : lattice_positions) {
238 lattice_positions[0][0] = 0.0;
239 lattice_positions[0][1] = 0.0;
241 for (
int i = 1; i <= n; ++i) {
243 unsigned i_left =
static_cast<unsigned>(std::max(0, 2 * i - 3));
245 double offset =
m_iff->randomSample();
246 lattice_positions[
static_cast<size_t>(2 * i - 1)][0] =
247 lattice_positions[i_left][0] + distance + offset;
248 lattice_positions[
static_cast<size_t>(2 * i - 1)][1] = 0.0;
251 unsigned i_right =
static_cast<unsigned>(2 * (i - 1));
253 offset =
m_iff->randomSample();
254 lattice_positions[
static_cast<size_t>(2 * i)][0] =
255 lattice_positions[i_right][0] - distance + offset;
256 lattice_positions[
static_cast<size_t>(2 * i)][1] = 0.0;
258 return lattice_positions;
263 return m_iff->positionVariance();
267 std::vector<std::vector<double>> Generate2DLatticePoints(
double l1,
double l2,
double alpha,
268 double xi,
unsigned n1,
unsigned n2)
270 std::vector<std::vector<double>> lattice_positions;
271 std::vector<double> position;
273 unsigned nn1 = std::max(1u, n1);
274 unsigned nn2 = std::max(1u, n2);
275 int n1m = -
static_cast<int>((nn1 - 1) / 2);
276 int n1M =
static_cast<int>(nn1 / 2);
277 int n2m = -
static_cast<int>((nn2 - 1) / 2);
278 int n2M =
static_cast<int>(nn2 / 2);
280 for (
int i = n1m; i <= n1M; ++i) {
281 for (
int j = n2m; j <= n2M; ++j) {
284 position.push_back(i * l1 * std::cos(xi)
285 + j * l2 * std::cos(alpha + xi));
286 position.push_back(i * l1 * std::sin(xi)
287 + j * l2 * std::sin(alpha + xi));
289 lattice_positions.push_back(position);
293 return lattice_positions;
Declares interface IPositionBuilder and subclasses.
Includes all interference function definitions.
Defines RealSpaceBuilderUtils namespace.
std::vector< std::vector< double > > generatePositionsImpl(double layer_size, double density=0.0) const override
double positionVariance() const override
~DefaultPositionBuilder() override
std::unique_ptr< InterferenceFunctionFinite2DLattice > m_iff
std::vector< std::vector< double > > generatePositionsImpl(double layer_size, double density=0.0) const override
Finite2DLatticePositionBuilder(const InterferenceFunctionFinite2DLattice *p_iff)
~Finite2DLatticePositionBuilder() override
double positionVariance() const override
virtual ~IPositionBuilder()
virtual std::vector< std::vector< double > > generatePositionsImpl(double layer_size, double density=0.0) const =0
std::vector< std::vector< double > > generatePositions(double layer_size, double density=0.0) const
virtual double positionVariance() const =0
Interference function of a 1D lattice.
Interference function of a 2D lattice.
Interference function of a 2D paracrystal.
Interference function of a finite 2D lattice.
Interference function of radial paracrystal.
std::unique_ptr< InterferenceFunction1DLattice > m_iff
Lattice1DPositionBuilder(const InterferenceFunction1DLattice *p_iff)
~Lattice1DPositionBuilder() override
std::vector< std::vector< double > > generatePositionsImpl(double layer_size, double density=0.0) const override
double positionVariance() const override
~Lattice2DPositionBuilder() override
Lattice2DPositionBuilder(const InterferenceFunction2DLattice *p_iff)
std::unique_ptr< InterferenceFunction2DLattice > m_iff
std::vector< std::vector< double > > generatePositionsImpl(double layer_size, double density=0.0) const override
double positionVariance() const override
double positionVariance() const override
std::vector< std::vector< double > > generatePositionsImpl(double layer_size, double density=0.0) const override
~ParaCrystal2DPositionBuilder() override
std::unique_ptr< InterferenceFunction2DParaCrystal > m_iff
ParaCrystal2DPositionBuilder(const InterferenceFunction2DParaCrystal *p_iff)
std::unique_ptr< InterferenceFunctionRadialParaCrystal > m_iff
RadialParacrystalPositionBuilder(const InterferenceFunctionRadialParaCrystal *p_iff)
std::vector< std::vector< double > > generatePositionsImpl(double layer_size, double density=0.0) const override
double positionVariance() const override
~RadialParacrystalPositionBuilder() override
~RandomPositionBuilder() override
std::vector< std::vector< double > > generatePositionsImpl(double layer_size, double density=0.0) const override
double positionVariance() const override
std::vector< std::vector< double > > Compute2DParacrystalLatticePositions(const InterferenceFunction2DParaCrystal *, double layer_size)