42 static const std::map<int, char>
axisChar{{0,
'X'}, {1,
'Y'}, {2,
'Z'}};
46 void setRotationInformation(
const IParticle* particle, std::string name, std::ostringstream& result)
55 for (
int iAxis = 0; iAxis < 3; ++iAxis) {
58 result <<
indent() << name <<
"_rotation = ba.Rotation" <<
axisChar.at(iAxis) <<
"("
60 result <<
indent() << name <<
".setRotation(" << name <<
"_rotation)\n";
66 result <<
indent() << name <<
"_rotation = ba.RotationEuler("
69 result <<
indent() << name <<
".setRotation(" << name <<
"_rotation)\n";
72 void setPositionInformation(
const IParticle* particle, std::string name, std::ostringstream& result)
80 result <<
indent() << name <<
".setParticlePosition(" << name <<
"_position)\n";
97 m_objs = std::make_unique<ComponentKeyHandler>();
98 m_materials = std::make_unique<MaterialKeyHandler>();
103 m_objs->insertModel(
"sample", &sample);
104 for (
const auto* x : NodeUtils::AllDescendantsOfType<Layer>(sample))
105 m_objs->insertModel(
"layer", x);
106 for (
const auto* x : NodeUtils::AllDescendantsOfType<LayerRoughness>(sample))
107 m_objs->insertModel(
"roughness", x);
108 for (
const auto* x : NodeUtils::AllDescendantsOfType<ParticleLayout>(sample))
109 m_objs->insertModel(
"layout", x);
110 for (
const auto* x : NodeUtils::AllDescendantsOfType<IFormFactor>(sample))
111 m_objs->insertModel(
"ff", x);
112 for (
const auto* x : NodeUtils::AllDescendantsOfType<IInterference>(sample))
113 m_objs->insertModel(
"iff", x);
114 for (
const auto* x : NodeUtils::AllDescendantsOfType<Particle>(sample))
115 m_objs->insertModel(
"particle", x);
116 for (
const auto* x : NodeUtils::AllDescendantsOfType<ParticleComposition>(sample))
117 m_objs->insertModel(
"particle", x);
118 for (
const auto* x : NodeUtils::AllDescendantsOfType<ParticleCoreShell>(sample))
119 m_objs->insertModel(
"particle", x);
120 for (
const auto* x : NodeUtils::AllDescendantsOfType<MesoCrystal>(sample))
121 m_objs->insertModel(
"particle", x);
122 for (
const auto* x : NodeUtils::AllDescendantsOfType<Lattice2D>(sample))
123 m_objs->insertModel(
"lattice", x);
124 for (
const auto* x : NodeUtils::AllDescendantsOfType<Lattice3D>(sample))
125 m_objs->insertModel(
"lattice", x);
126 for (
const auto* x : NodeUtils::AllDescendantsOfType<Crystal>(sample))
127 m_objs->insertModel(
"crystal", x);
152 std::ostringstream result;
153 result << std::setprecision(12);
154 result <<
indent() <<
"# Define materials\n";
155 std::set<std::string> visitedMaterials;
156 for (
const auto& it : themap) {
157 const std::string& key = it.first;
158 if (visitedMaterials.find(key) != visitedMaterials.end())
160 visitedMaterials.insert(key);
161 const Material* p_material = it.second;
164 throw std::runtime_error(
165 "Error in Py::Export::defineMaterials(): unknown material type");
166 const complex_t& material_data = p_material->
materialData();
169 << factory_name->second <<
"(\"" << p_material->
materialName() <<
"\", "
174 result <<
indent() <<
"magnetic_field = R3(" << magnetic_field.x() <<
", "
175 << magnetic_field.y() <<
", " << magnetic_field.z() <<
")\n";
177 << factory_name->second <<
"(\"" << p_material->
materialName();
180 <<
"magnetic_field)\n";
188 std::vector<const Layer*> v =
m_objs->objectsOfType<
Layer>();
191 std::ostringstream result;
192 result <<
"\n" <<
indent() <<
"# Define layers\n";
193 result << std::setprecision(12);
194 for (
const auto* s : v) {
195 const std::string& key =
m_objs->obj2key(s);
196 result <<
indent() << key <<
" = ba.Layer(" <<
m_materials->mat2key(s->material());
197 if (s->thickness() != 0)
200 if (s->numberOfSlices() != 1)
201 result <<
indent() << key <<
".setNumberOfSlices(" << s->numberOfSlices() <<
")\n";
202 for (
const auto* layout : s->layouts())
203 result <<
indent() << key <<
".addLayout(" <<
m_objs->obj2key(layout) <<
")\n";
213 std::ostringstream result;
214 result << std::setprecision(12);
215 result <<
"\n" <<
indent() <<
"# Define roughness\n";
216 for (
const auto* s : v) {
217 const std::string& key =
m_objs->obj2key(s);
218 result <<
indent() << key <<
" = ba." << s->pythonConstructor() <<
"\n";
225 std::vector<const IFormFactor*> formfactors =
m_objs->objectsOfType<
IFormFactor>();
226 if (formfactors.empty())
228 std::ostringstream result;
229 result <<
"\n" <<
indent() <<
"# Define form factors\n";
230 result << std::setprecision(12);
231 for (
const auto* s : formfactors) {
232 const std::string& key =
m_objs->obj2key(s);
233 result <<
indent() << key <<
" = ba." << s->pythonConstructor() <<
"\n";
244 std::ostringstream result;
245 result << std::setprecision(12);
246 result <<
"\n" <<
indent() <<
"# Define interference functions\n";
247 for (
const auto* s : v) {
248 const std::string& key =
m_objs->obj2key(s);
251 result <<
indent() << key <<
" = ba.InterferenceNone()\n";
254 result <<
indent() << key <<
" = ba.Interference1DLattice("
258 const auto* pdf = NodeUtils::OnlyChildOfType<IProfile1D>(*iff);
260 if (pdf->decayLength() != 0.0)
261 result <<
indent() << key <<
"_pdf = ba." << pdf->pythonConstructor() <<
"\n"
262 <<
indent() << key <<
".setDecayFunction(" << key <<
"_pdf)\n";
264 result <<
indent() << key <<
" = ba.InterferenceRadialParaCrystal("
268 if (iff->kappa() != 0.0)
272 if (iff->domainSize() != 0.0)
273 result <<
indent() << key <<
".setDomainSize("
276 const auto* pdf = NodeUtils::OnlyChildOfType<IProfile1D>(*iff);
278 if (pdf->omega() != 0.0)
279 result <<
indent() << key <<
"_pdf = ba." << pdf->pythonConstructor() <<
"\n"
280 <<
indent() << key <<
".setProbabilityDistribution(" << key <<
"_pdf)\n";
282 const auto* lattice = NodeUtils::OnlyChildOfType<Lattice2D>(*iff);
284 result <<
indent() << key <<
" = ba.Interference2DLattice(" <<
m_objs->obj2key(lattice)
287 const auto* pdf = NodeUtils::OnlyChildOfType<IProfile2D>(*iff);
289 result <<
indent() << key <<
"_pdf = ba." << pdf->pythonConstructor() <<
"\n"
290 <<
indent() << key <<
".setDecayFunction(" << key <<
"_pdf)\n";
292 if (iff->integrationOverXi())
293 result <<
indent() << key <<
".setIntegrationOverXi(True)\n";
295 const auto* lattice = NodeUtils::OnlyChildOfType<Lattice2D>(*iff);
297 result <<
indent() << key <<
" = ba.InterferenceFinite2DLattice("
298 <<
m_objs->obj2key(lattice) <<
", " << iff->numberUnitCells1() <<
", "
299 << iff->numberUnitCells2() <<
")\n";
301 if (iff->integrationOverXi())
302 result <<
indent() << key <<
".setIntegrationOverXi(True)\n";
304 const auto* lattice = NodeUtils::OnlyChildOfType<Lattice2D>(*iff);
305 std::vector<double> domainSize = iff->domainSizes();
307 result <<
indent() << key <<
" = ba.Interference2DParaCrystal("
312 if (iff->integrationOverXi())
313 result <<
indent() << key <<
".setIntegrationOverXi(True)\n";
315 const auto pdf_vector = NodeUtils::ChildNodesOfType<IProfile2D>(*iff);
316 if (pdf_vector.size() != 2)
325 result <<
indent() << key <<
".setProbabilityDistributions(" << key <<
"_pdf_1, " << key
328 result <<
indent() << key <<
" = ba.InterferenceHardDisk("
334 if (s->positionVariance() > 0.0) {
335 result <<
indent() << key <<
".setPositionVariance("
347 std::ostringstream result;
348 result << std::setprecision(12);
349 result <<
"\n" <<
indent() <<
"# Define particle layouts\n";
350 for (
const auto* s : v) {
351 const std::string& key =
m_objs->obj2key(s);
352 result <<
indent() << key <<
" = ba.ParticleLayout()\n";
353 const auto particles = NodeUtils::ChildNodesOfType<IParticle>(*s);
354 for (
const auto* particle : particles) {
355 double abundance = particle->
abundance();
356 result <<
indent() << key <<
".addParticle(" <<
m_objs->obj2key(particle) <<
", "
359 if (
const auto* iff = NodeUtils::OnlyChildOfType<IInterference>(*s))
360 result <<
indent() << key <<
".setInterference(" <<
m_objs->obj2key(iff) <<
")\n";
361 result <<
indent() << key <<
".setWeight(" << s->weight() <<
")\n";
362 result <<
indent() << key <<
".setTotalParticleSurfaceDensity("
363 << s->totalParticleSurfaceDensity() <<
")\n";
370 std::vector<const Particle*> v =
m_objs->objectsOfType<
Particle>();
373 std::ostringstream result;
374 result << std::setprecision(12);
375 result <<
"\n" <<
indent() <<
"# Define particles\n";
376 for (
const auto* s : v) {
377 const std::string& key =
m_objs->obj2key(s);
378 const auto*
ff = NodeUtils::OnlyChildOfType<IFormFactor>(*s);
380 result <<
indent() << key <<
" = ba.Particle(" <<
m_materials->mat2key(s->material())
381 <<
", " <<
m_objs->obj2key(
ff) <<
")\n";
382 setRotationInformation(s, key, result);
383 setPositionInformation(s, key, result);
393 std::ostringstream result;
394 result << std::setprecision(12);
395 result <<
"\n" <<
indent() <<
"# Define core shell particles\n";
396 for (
const auto* s : v) {
397 const std::string& key =
m_objs->obj2key(s);
398 result <<
indent() << key <<
" = ba.ParticleCoreShell("
399 <<
m_objs->obj2key(s->shellParticle()) <<
", " <<
m_objs->obj2key(s->coreParticle())
401 setRotationInformation(s, key, result);
402 setPositionInformation(s, key, result);
412 std::ostringstream result;
413 result << std::setprecision(12);
414 result <<
"\n" <<
indent() <<
"# Define composition of particles at specific positions\n";
415 for (
const auto* s : v) {
416 const std::string& key =
m_objs->obj2key(s);
417 result <<
indent() << key <<
" = ba.ParticleComposition()\n";
418 const auto particle_list = NodeUtils::ChildNodesOfType<IParticle>(*s);
419 for (
const auto* particle : particle_list)
420 result <<
indent() << key <<
".addParticle(" <<
m_objs->obj2key(particle) <<
")\n";
421 setRotationInformation(s, key, result);
422 setPositionInformation(s, key, result);
432 std::ostringstream result;
433 result << std::setprecision(12);
434 result <<
"\n" <<
indent() <<
"# Define mesocrystals\n";
435 for (
const auto* s : v) {
436 const std::string& key =
m_objs->obj2key(s);
437 const auto* crystal = NodeUtils::OnlyChildOfType<Crystal>(*s);
438 const auto* outer_shape = NodeUtils::OnlyChildOfType<IFormFactor>(*s);
439 if (!crystal || !outer_shape)
441 result <<
indent() << key <<
" = ba.MesoCrystal(";
442 result <<
m_objs->obj2key(crystal) <<
", ";
443 result <<
m_objs->obj2key(outer_shape) <<
")\n";
444 setRotationInformation(s, key, result);
445 setPositionInformation(s, key, result);
455 std::ostringstream result;
456 result << std::setprecision(12);
457 result <<
"\n" <<
indent() <<
"# Define 2D lattices\n";
458 for (
const auto* s : v) {
459 const std::string& key =
m_objs->obj2key(s);
460 result <<
indent() << key <<
" = ba.BasicLattice2D(\n";
473 std::ostringstream result;
474 result << std::setprecision(12);
475 result <<
"\n" <<
indent() <<
"# Define 3D lattices\n";
476 for (
const auto* s : v) {
477 const std::string& key =
m_objs->obj2key(s);
478 R3 bas_a = s->basisVectorA();
479 R3 bas_b = s->basisVectorB();
480 R3 bas_c = s->basisVectorC();
481 result <<
indent() << key <<
" = ba.Lattice3D(\n";
494 std::vector<const Crystal*> v =
m_objs->objectsOfType<
Crystal>();
497 std::ostringstream result;
498 result << std::setprecision(12);
499 result <<
"\n" <<
indent() <<
"# Define crystals\n";
500 for (
const auto* s : v) {
501 const std::string& key =
m_objs->obj2key(s);
502 const auto* lattice = NodeUtils::OnlyChildOfType<Lattice3D>(*s);
503 const auto* basis = NodeUtils::OnlyChildOfType<IParticle>(*s);
504 if (!lattice || !basis)
506 result <<
indent() << key <<
" = ba.Crystal(";
507 result <<
m_objs->obj2key(basis) <<
", ";
508 result <<
m_objs->obj2key(lattice) <<
")\n";
518 std::ostringstream result;
519 result << std::setprecision(12);
521 result <<
"\n" <<
indent() <<
"# Define sample\n";
522 for (
const auto* s : v) {
523 const std::string& key =
m_objs->obj2key(s);
524 result <<
indent() << key <<
" = ba.MultiLayer()\n";
525 double ccl = s->crossCorrLength();
527 result <<
indent() << key <<
".setCrossCorrLength(" << ccl <<
")\n";
528 auto external_field = s->externalField();
529 if (external_field.mag() > 0.0) {
530 std::string field_name = key +
"_external_field";
531 result <<
indent() << field_name <<
" = R3("
535 result <<
indent() << key <<
".setExternalField(" << field_name <<
")\n";
537 size_t numberOfLayers = s->numberOfLayers();
538 if (numberOfLayers) {
539 result <<
indent() << key <<
".addLayer(" <<
m_objs->obj2key(s->layer(0)) <<
")\n";
542 while (i_layer != numberOfLayers) {
543 const LayerInterface* layerInterface = s->layerInterface(i_layer - 1);
545 result <<
indent() << key <<
".addLayerWithTopRoughness("
546 <<
m_objs->obj2key(s->layer(i_layer)) <<
", " <<
m_objs->obj2key(rough)
549 result <<
indent() << key <<
".addLayer(" <<
m_objs->obj2key(s->layer(i_layer))
554 result <<
"\n" <<
indent() <<
"return " << key <<
"\n";
Defines the macro ASSERT.
#define ASSERT(condition)
Defines class ComponentKeyHandler.
Includes all interference function definitions.
Defines class LayerInterface.
Defines class LayerRoughness.
Defines class MaterialKeyHandler.
Defines class MesoCrystal.
Defines class MultiLayer.
Defines collection of utility functions for INode.
Defines class ParticleComposition.
Defines ParticleCoreShell.
Defines class ParticleLayout.
Defines namespace pyfmt2.
Declares class RotMatrix.
Defines IRotation classes.
const std::map< MATERIAL_TYPES, std::string > factory_names
static const std::map< int, char > axisChar
Defines class SampleToPython.
A crystal structure, defined by a Bravais lattice, a basis, and a position variance.
Abstract base class of interference functions.
Abstract base class for Particle, ParticleComposition, ParticleCoreShell, MesoCrystal....
const IRotation * rotation() const
Returns rotation object.
R3 particlePosition() const
Returns particle position.
Interface for two-dimensional distributions in Fourier space.
virtual std::string pythonConstructor() const
Creates the Python constructor of this class (or derived classes)
virtual RotMatrix rotMatrix() const =0
Returns transformation.
std::vector< const Material * > containedMaterials() const
Returns set of unique materials contained in this ISampleNode.
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.
Percus-Yevick hard disk interference function.
Default interference function (i.e. absence of any interference).
Interference function of radial paracrystal.
A two-dimensional Bravais lattice.
A Bravais lattice, characterized by three basis vectors, and optionally an ISelectionRule.
Interface between two layers, possibly with roughness.
const LayerRoughness * roughness() const
Returns roughness of the interface.
A roughness of interface between two layers.
A layer in a MultiLayer sample.
A wrapper for underlying material implementation.
R3 magnetization() const
Get the magnetization (in A/m)
bool isScalarMaterial() const
Indicates whether the interaction with the material is scalar. This means that different polarization...
std::string materialName() const
Returns the name of material.
MATERIAL_TYPES typeID() const
Returns the type of underlying material implementation.
complex_t materialData() const
Returns delta + i beta.
A particle with a crystalline inner structure, made of smaller particles, and an outer shape describe...
Our sample model: a stack of layers one below the other.
A composition of particles at fixed positions.
A particle with a core/shell geometry.
Decorator class that adds particles to ISampleNode objects.
A particle with a form factor and refractive index.
Rotation matrix in three dimensions. Represents group SO(3). Internal parameterization based on quate...
bool isIdentity() const
Determine if the transformation is trivial (identity)
std::optional< double > angleAroundCoordAxis(int iAxis) const
std::array< double, 3 > zxzEulerAngles() const
Calculates the Euler angles corresponding to the rotation.
std::string defineLayers() const
std::string defineGetSample() const
std::string defineFormFactors() const
std::string defineMaterials() const
std::string defineLattices3D() const
std::string defineMesoCrystals() const
std::string defineCrystals() const
std::string defineParticles() const
std::string defineParticleCompositions() const
std::unique_ptr< ComponentKeyHandler > m_objs
std::string defineLattices2D() const
std::string defineInterferences() const
std::string defineParticleLayouts() const
std::string defineCoreShellParticles() const
std::string sampleCode(const MultiLayer &sample)
void initLabels(const MultiLayer &sample)
std::string defineMultiLayers() const
std::string defineRoughnesses() const
std::unique_ptr< MaterialKeyHandler > m_materials
std::string printDegrees(double input)
std::string printDouble(double input)
std::string printScientificDouble(double input)
std::string printNm(double input)
std::string indent(size_t width)
Returns a string of blanks with given width. By default the width equals standard offset in python fi...
std::string printNm2(double input)