BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
SampleToCore.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/Model/ToCore/SampleToCore.cpp
6 //! @brief Implements class TransformToCore
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
28 #include "GUI/Util/Error.h"
29 #include "Sample/Aggregate/IInterference.h"
30 #include "Sample/Aggregate/ParticleLayout.h"
31 #include "Sample/Interface/LayerRoughness.h"
32 #include "Sample/Multilayer/Layer.h"
33 #include "Sample/Multilayer/MultiLayer.h"
34 #include "Sample/Particle/IParticle.h"
35 #include "Sample/Particle/MesoCrystal.h"
36 #include "Sample/Particle/Particle.h"
37 #include "Sample/Particle/ParticleCoreShell.h"
38 
39 namespace {
40 
41 std::unique_ptr<MultiLayer> createMultiLayer(const MultiLayerItem& item)
42 {
43  auto sample = std::make_unique<MultiLayer>();
44  double cross_corr_length = item.crossCorrLength();
45  if (cross_corr_length > 0)
46  sample->setCrossCorrLength(cross_corr_length);
47  R3 external_field = item.externalField();
48  sample->setExternalField(external_field);
49  return sample;
50 }
51 
52 std::unique_ptr<Layer> createLayer(const LayerItem& item)
53 {
54  const bool isFirstOrLastLayer = item.isTopLayer() || item.isBottomLayer();
55  auto layer = std::make_unique<Layer>(*item.materialItem()->createMaterial(),
56  isFirstOrLastLayer ? 0.0 : item.thickness());
57  layer->setNumberOfSlices(item.numSlices());
58  return layer;
59 }
60 
61 std::unique_ptr<ParticleLayout> createParticleLayout(const ParticleLayoutItem& item)
62 {
63  auto layout = std::make_unique<ParticleLayout>();
64  double total_density = item.totalDensity();
65  double layout_weight = item.weight();
66  layout->setTotalParticleSurfaceDensity(total_density);
67  layout->setWeight(layout_weight);
68  return layout;
69 }
70 
71 std::unique_ptr<IParticle> createIParticle(const ItemWithParticles& item)
72 {
73  std::unique_ptr<IParticle> particle;
74  if (const auto* particle_item = dynamic_cast<const ParticleItem*>(&item))
75  particle = particle_item->createParticle();
76  else if (const auto* particle_coreshell_item =
77  dynamic_cast<const ParticleCoreShellItem*>(&item))
78  particle = particle_coreshell_item->createParticleCoreShell();
79  else if (const auto* particle_composition_item =
80  dynamic_cast<const ParticleCompositionItem*>(&item))
81  particle = particle_composition_item->createParticleComposition();
82  else if (const auto* mesocrystal_item = dynamic_cast<const MesoCrystalItem*>(&item))
83  particle = mesocrystal_item->createMesoCrystal();
84 
85  return particle;
86 }
87 
88 std::unique_ptr<ParticleLayout> buildParticleLayout(const ParticleLayoutItem& item)
89 {
90  auto layout = createParticleLayout(item);
91  for (auto particleItem : item.particles()) {
92  if (auto particle = createIParticle(*particleItem)) {
93  layout->addParticle(*particle);
94  continue;
95  }
96  ASSERT(0); // case not implemented yet?
97  }
98 
99  if (InterferenceItem* interferenceItem = item.interference().currentItem())
100  if (auto interference = interferenceItem->createInterference())
101  layout->setInterference(*interference);
102  return layout;
103 }
104 
105 std::unique_ptr<Layer> buildLayer(const LayerItem& item)
106 {
107  auto layer = createLayer(item);
108  for (ParticleLayoutItem* layoutItem : item.layouts()) {
109  if (auto layout = buildParticleLayout(*layoutItem))
110  layer->addLayout(*layout);
111  }
112  return layer;
113 }
114 
115 std::unique_ptr<LayerRoughness> itemToLayerRoughness(LayerBasicRoughnessItem* roughness)
116 {
117  if (!roughness)
118  return nullptr;
119  return std::make_unique<LayerRoughness>(roughness->sigma(), roughness->hurst(),
120  roughness->lateralCorrelationLength());
121 }
122 
123 } // namespace
124 
125 std::unique_ptr<MultiLayer> GUI::Transform::ToCore::itemToSample(const MultiLayerItem& sampleItem)
126 {
127  auto sample = createMultiLayer(sampleItem);
128  for (auto* layerItem : sampleItem.layers()) {
129  auto layer = buildLayer(*layerItem);
130  ASSERT(layer);
131  const auto roughnessItem = layerItem->roughness().currentItem();
132  auto roughness = itemToLayerRoughness(roughnessItem);
133  if (roughness && !layerItem->isTopLayer())
134  sample->addLayerWithTopRoughness(*layer, *roughness);
135  else
136  sample->addLayer(*layer);
137  }
138  return sample;
139 }
Defines class DoubleDescriptor.
Defines error class.
Defines InterferenceItems's classes.
Defines class LayerItem.
Defines classes LayerRoughnessItems.
Defines class MaterialItem.
Defines class MesoCrystalItem.
Defines class MultiLayerItem.
Defines class ParticleCompositionItem.
Defines class ParticleCoreShellItem.
Defines class ParticleItem.
Defines class ParticleLayoutItem.
Defines namespace GUI::Transform::ToCore.
Defines class UIntDescriptor.
MaterialItem * materialItem() const
Returns the material item this item links to.
DoubleDescriptor lateralCorrelationLength() const
DoubleDescriptor sigma() const
DoubleDescriptor hurst() const
UIntDescriptor numSlices() const
Definition: LayerItem.cpp:131
bool isTopLayer() const
Definition: LayerItem.cpp:168
bool isBottomLayer() const
Definition: LayerItem.cpp:178
QVector< ParticleLayoutItem * > layouts() const
Definition: LayerItem.cpp:136
DoubleDescriptor thickness() const
Definition: LayerItem.cpp:97
std::unique_ptr< Material > createMaterial() const
QVector< LayerItem * > layers() const
R3 externalField() const
DoubleDescriptor crossCorrLength() const
DoubleDescriptor weight() const
DoubleDescriptor totalDensity() const
The real density.
QVector< ItemWithParticles * > particles() const
The particles this layout contains.
SelectionDescriptor< InterferenceItem * > interference() const
std::unique_ptr< MultiLayer > itemToSample(const MultiLayerItem &item)
std::unique_ptr< GUI::RealSpace::Layer > createLayer(const LayerItem &layerItem, const SceneGeometry &sceneGeometry, const QVector3D &origin={})