23 std::pair<size_t, size_t> SliceIndexSpan(
const IParticle& particle,
24 const std::vector<Slice>& slices,
double z_ref);
25 size_t TopZToSliceIndex(
double z,
const std::vector<Slice>& slices);
26 size_t BottomZToSliceIndex(
double z,
const std::vector<Slice>& slices);
27 double SliceTopZ(
size_t i,
const std::vector<Slice>& slices);
28 ZLimits SlicesZLimits(
const std::vector<Slice>& slices,
size_t slice_index);
29 void ScaleRegions(std::vector<HomogeneousRegion>& regions,
double factor);
33 const std::vector<Slice>& slices,
38 for (
auto* particle : particles) {
47 auto slice_indices = SliceIndexSpan(particle, slices, z_ref);
48 bool single_layer = (slice_indices.first == slice_indices.second);
49 for (
size_t i = slice_indices.first; i < slice_indices.second + 1; ++i) {
50 double z_top_i = SliceTopZ(i, slices);
51 kvector_t translation(0.0, 0.0, z_ref - z_top_i);
54 ZLimits limits = single_layer ?
ZLimits() : SlicesZLimits(slices, i);
56 m_ff_list.emplace_back(std::move(sliced_particle.m_slicedff), i);
57 double thickness = slices[i].thickness();
59 ScaleRegions(sliced_particle.m_regions, 1 / thickness);
61 sliced_particle.m_regions.end());
74 throw std::out_of_range(
"SlicedFormFactorList::operator[] error: "
75 "index out of range");
85 std::pair<size_t, size_t> SliceIndexSpan(
const IParticle& particle,
86 const std::vector<Slice>& slices,
double z_ref)
89 double zbottom = bottomTopZ.
m_bottom;
90 double ztop = bottomTopZ.m_top;
91 double eps = (ztop - zbottom) * 1e-6;
93 double zmax = ztop + z_ref - eps;
94 double zmin = zbottom + z_ref + eps;
95 size_t top_index = TopZToSliceIndex(zmax, slices);
96 size_t bottom_index = BottomZToSliceIndex(zmin, slices);
97 if (top_index > bottom_index)
98 top_index = bottom_index;
99 return {top_index, bottom_index};
102 size_t TopZToSliceIndex(
double z,
const std::vector<Slice>& slices)
104 auto n_layers = slices.size();
105 if (n_layers < 2 || z > 0.0)
107 double z_layer_bottom = 0.0;
109 while (i_slice + 1 < n_layers) {
111 z_layer_bottom -= slices[i_slice].thickness();
112 if (z > z_layer_bottom)
118 size_t BottomZToSliceIndex(
double z,
const std::vector<Slice>& slices)
120 auto n_layers = slices.size();
121 if (n_layers < 2 || z >= 0.0)
123 double z_layer_bottom = 0.0;
125 while (i_slice + 1 < n_layers) {
127 z_layer_bottom -= slices[i_slice].thickness();
128 if (z >= z_layer_bottom)
134 double SliceTopZ(
size_t i,
const std::vector<Slice>& slices)
139 for (
size_t j = 1; j < i; ++j)
140 top_z -= slices[j].thickness();
144 ZLimits SlicesZLimits(
const std::vector<Slice>& slices,
size_t slice_index)
146 size_t N = slices.size();
149 if (slice_index == 0)
150 return ZLimits({
false, 0}, {
true, 0});
151 if (slice_index == N - 1)
152 return ZLimits({
true, 0}, {
false, 0});
153 double thickness = slices[slice_index].thickness();
154 return ZLimits(-thickness, 0.0);
157 void ScaleRegions(std::vector<HomogeneousRegion>& regions,
double factor)
159 for (
auto& region : regions)
160 region.m_volume *= factor;
Defines interface IParticle.
Defines IRotation classes.
Defines class SlicedParticle.
Abstract base class for Particle, ParticleComposition, ParticleCoreShell, MesoCrystal.
virtual SafePointerVector< IParticle > decompose() const
Decompose in constituent IParticle objects.
virtual SlicedParticle createSlicedParticle(ZLimits limits) const
Creates a sliced form factor for this particle.
virtual ParticleLimits bottomTopZ() const
Top and bottom z-coordinate.
void translate(kvector_t translation) final
Translates the particle.
Class that contains upper and lower limits of the z-coordinate for the slicing of form factors.