44 void setRotationInformation(
const IParticle* particle, std::string
name, std::ostringstream& result)
49 double alpha, beta, gamma;
51 result <<
indent() <<
name <<
"_rotation = ba.RotationEuler("
75 result <<
indent() <<
name <<
".setRotation(" <<
name <<
"_rotation)\n";
79 void setPositionInformation(
const IParticle* particle, std::string
name, std::ostringstream& result)
87 result <<
indent() <<
name <<
".setPosition(" <<
name <<
"_position)\n";
110 m_objs->insertModel(
"sample", &multilayer);
111 for (
const auto* x : node_progeny::AllDescendantsOfType<Layer>(multilayer))
112 m_objs->insertModel(
"layer", x);
113 for (
const auto* x : node_progeny::AllDescendantsOfType<LayerRoughness>(multilayer))
114 m_objs->insertModel(
"roughness", x);
115 for (
const auto* x : node_progeny::AllDescendantsOfType<ParticleLayout>(multilayer))
116 m_objs->insertModel(
"layout", x);
117 for (
const auto* x : node_progeny::AllDescendantsOfType<IFormFactor>(multilayer))
118 m_objs->insertModel(
"ff", x);
119 for (
const auto* x : node_progeny::AllDescendantsOfType<IInterferenceFunction>(multilayer))
120 m_objs->insertModel(
"iff", x);
121 for (
const auto* x : node_progeny::AllDescendantsOfType<Particle>(multilayer))
122 m_objs->insertModel(
"particle", x);
123 for (
const auto* x : node_progeny::AllDescendantsOfType<ParticleComposition>(multilayer))
124 m_objs->insertModel(
"particle", x);
125 for (
const auto* x : node_progeny::AllDescendantsOfType<ParticleCoreShell>(multilayer))
126 m_objs->insertModel(
"particle", x);
127 for (
const auto* x : node_progeny::AllDescendantsOfType<MesoCrystal>(multilayer))
128 m_objs->insertModel(
"particle", x);
129 for (
const auto* x : node_progeny::AllDescendantsOfType<ParticleDistribution>(multilayer))
130 m_objs->insertModel(
"particle_distrib", x);
131 for (
const auto* x : node_progeny::AllDescendantsOfType<Lattice2D>(multilayer))
132 m_objs->insertModel(
"lattice", x);
133 for (
const auto* x : node_progeny::AllDescendantsOfType<Lattice3D>(multilayer))
134 m_objs->insertModel(
"lattice", x);
135 for (
const auto* x : node_progeny::AllDescendantsOfType<Crystal>(multilayer))
136 m_objs->insertModel(
"crystal", x);
161 std::ostringstream result;
162 result << std::setprecision(12);
163 result <<
indent() <<
"# Define materials\n";
164 std::set<std::string> visitedMaterials;
165 for (
auto it : themap) {
166 const std::string& key = it.first;
167 if (visitedMaterials.find(key) != visitedMaterials.end())
169 visitedMaterials.insert(key);
170 const Material* p_material = it.second;
173 throw std::runtime_error(
174 "Error in ExportToPython::defineMaterials(): unknown material type");
178 << factory_name->second <<
"(\"" << p_material->
getName() <<
"\", "
183 result <<
indent() <<
"magnetic_field = kvector_t(" << magnetic_field.
x() <<
", "
184 << magnetic_field.
y() <<
", " << magnetic_field.
z() <<
")\n";
186 << factory_name->second <<
"(\"" << p_material->
getName();
189 <<
"magnetic_field)\n";
197 std::vector<const Layer*> v =
m_objs->objectsOfType<
Layer>();
200 std::ostringstream result;
201 result <<
"\n" <<
indent() <<
"# Define layers\n";
202 result << std::setprecision(12);
203 for (
const auto* s : v) {
204 const std::string& key =
m_objs->obj2key(s);
205 result <<
indent() << key <<
" = ba.Layer(" <<
m_materials->mat2key(s->material());
206 if (s->thickness() != 0)
209 if (s->numberOfSlices() != 1)
210 result <<
indent() << key <<
".setNumberOfSlices(" << s->numberOfSlices() <<
")\n";
211 for (
const auto* layout : s->layouts())
212 result <<
indent() << key <<
".addLayout(" <<
m_objs->obj2key(layout) <<
")\n";
222 std::ostringstream result;
223 result << std::setprecision(12);
224 result <<
"\n" <<
indent() <<
"# Define roughness\n";
225 for (
const auto* s : v) {
226 const std::string& key =
m_objs->obj2key(s);
237 std::ostringstream result;
238 result <<
"\n" <<
indent() <<
"# Define form factors\n";
239 result << std::setprecision(12);
240 for (
const auto* s : v) {
241 const std::string& key =
m_objs->obj2key(s);
242 result <<
indent() << key <<
" = ba.FormFactor" << s->getName() <<
"("
253 std::ostringstream result;
254 result << std::setprecision(12);
255 result <<
"\n" <<
indent() <<
"# Define interference functions\n";
256 for (
const auto* s : v) {
257 const std::string& key =
m_objs->obj2key(s);
260 result <<
indent() << key <<
" = ba.InterferenceFunctionNone()\n";
263 result <<
indent() << key <<
" = ba.InterferenceFunction1DLattice("
267 const auto* pdf = node_progeny::OnlyChildOfType<IFTDecayFunction1D>(*iff);
269 if (pdf->decayLength() != 0.0)
270 result <<
indent() << key <<
"_pdf = ba." << pdf->getName() <<
"("
272 <<
indent() << key <<
".setDecayFunction(" << key <<
"_pdf)\n";
274 }
else if (
const auto* iff =
276 result <<
indent() << key <<
" = ba.InterferenceFunctionRadialParaCrystal("
280 if (iff->kappa() != 0.0)
284 if (iff->domainSize() != 0.0)
285 result <<
indent() << key <<
".setDomainSize("
288 const auto* pdf = node_progeny::OnlyChildOfType<IFTDistribution1D>(*iff);
290 if (pdf->omega() != 0.0)
291 result <<
indent() << key <<
"_pdf = ba." << pdf->getName() <<
"("
293 <<
indent() << key <<
".setProbabilityDistribution(" << key <<
"_pdf)\n";
296 const auto* lattice = node_progeny::OnlyChildOfType<Lattice2D>(*iff);
298 result <<
indent() << key <<
" = ba.InterferenceFunction2DLattice("
299 <<
m_objs->obj2key(lattice) <<
")\n";
301 const auto* pdf = node_progeny::OnlyChildOfType<IFTDecayFunction2D>(*iff);
303 result <<
indent() << key <<
"_pdf = ba." << pdf->getName() <<
"("
305 <<
indent() << key <<
".setDecayFunction(" << key <<
"_pdf)\n";
307 if (iff->integrationOverXi() ==
true)
308 result <<
indent() << key <<
".setIntegrationOverXi(True)\n";
311 const auto* lattice = node_progeny::OnlyChildOfType<Lattice2D>(*iff);
313 result <<
indent() << key <<
" = ba.InterferenceFunctionFinite2DLattice("
314 <<
m_objs->obj2key(lattice) <<
", " << iff->numberUnitCells1() <<
", "
315 << iff->numberUnitCells2() <<
")\n";
317 if (iff->integrationOverXi() ==
true)
318 result <<
indent() << key <<
".setIntegrationOverXi(True)\n";
321 const auto* lattice = node_progeny::OnlyChildOfType<Lattice2D>(*iff);
322 std::vector<double> domainSize = iff->domainSizes();
324 result <<
indent() << key <<
" = ba.InterferenceFunction2DParaCrystal("
329 if (iff->integrationOverXi() ==
true)
330 result <<
indent() << key <<
".setIntegrationOverXi(True)\n";
332 const auto pdf_vector = node_progeny::ChildNodesOfType<IFTDistribution2D>(*iff);
333 if (pdf_vector.size() != 2)
337 result <<
indent() << key <<
"_pdf_1 = ba." << pdf->
getName() <<
"("
342 result <<
indent() << key <<
"_pdf_2 = ba." << pdf->
getName() <<
"("
344 result <<
indent() << key <<
".setProbabilityDistributions(" << key <<
"_pdf_1, " << key
348 result <<
indent() << key <<
" = ba.InterferenceFunctionHardDisk("
353 throw std::runtime_error(
354 "Bug: ExportToPython::defineInterferenceFunctions() called with unexpected "
355 "IInterferenceFunction "
358 if (s->positionVariance() > 0.0) {
359 result <<
indent() << key <<
".setPositionVariance("
371 std::ostringstream result;
372 result << std::setprecision(12);
373 result <<
"\n" <<
indent() <<
"# Define particle layouts\n";
374 for (
const auto* s : v) {
375 const std::string& key =
m_objs->obj2key(s);
376 result <<
indent() << key <<
" = ba.ParticleLayout()\n";
377 const auto particles = node_progeny::ChildNodesOfType<IAbstractParticle>(*s);
378 for (
const auto* particle : particles) {
379 double abundance = particle->
abundance();
380 result <<
indent() << key <<
".addParticle(" <<
m_objs->obj2key(particle) <<
", "
383 if (
const auto* iff = node_progeny::OnlyChildOfType<IInterferenceFunction>(*s))
384 result <<
indent() << key <<
".setInterferenceFunction(" <<
m_objs->obj2key(iff)
386 result <<
indent() << key <<
".setWeight(" << s->weight() <<
")\n";
387 result <<
indent() << key <<
".setTotalParticleSurfaceDensity("
388 << s->totalParticleSurfaceDensity() <<
")\n";
395 std::vector<const Particle*> v =
m_objs->objectsOfType<
Particle>();
398 std::ostringstream result;
399 result << std::setprecision(12);
400 result <<
"\n" <<
indent() <<
"# Define particles\n";
401 for (
const auto* s : v) {
402 const std::string& key =
m_objs->obj2key(s);
403 const auto* ff = node_progeny::OnlyChildOfType<IFormFactor>(*s);
405 result <<
indent() << key <<
" = ba.Particle(" <<
m_materials->mat2key(s->material())
406 <<
", " <<
m_objs->obj2key(ff) <<
")\n";
407 setRotationInformation(s, key, result);
408 setPositionInformation(s, key, result);
418 std::ostringstream result;
419 result << std::setprecision(12);
420 result <<
"\n" <<
indent() <<
"# Define core shell particles\n";
421 for (
const auto* s : v) {
422 const std::string& key =
m_objs->obj2key(s);
423 result <<
indent() << key <<
" = ba.ParticleCoreShell("
424 <<
m_objs->obj2key(s->shellParticle()) <<
", " <<
m_objs->obj2key(s->coreParticle())
426 setRotationInformation(s, key, result);
427 setPositionInformation(s, key, result);
437 std::ostringstream result;
438 result << std::setprecision(12);
439 result <<
"\n" <<
indent() <<
"# Define particles with parameter following a distribution\n";
441 for (
const auto* s : v) {
442 const std::string& key =
m_objs->obj2key(s);
443 const std::string units = s->mainUnits();
446 std::string s_distr =
"distr_" + std::to_string(index);
447 result <<
indent() << s_distr <<
" = "
451 std::string s_par_distr =
"par_distr_" + std::to_string(index);
453 result <<
indent() << s_par_distr <<
" = "
458 if (!linked_pars.empty()) {
459 result <<
indent() << s_par_distr;
460 for (
size_t i = 0; i < linked_pars.size(); ++i)
461 result <<
".linkParameter(\"" << linked_pars[i] <<
"\")";
465 auto particle = node_progeny::OnlyChildOfType<IParticle>(*s);
468 result <<
indent() << key <<
" = ba.ParticleDistribution(" <<
m_objs->obj2key(particle)
469 <<
", " << s_par_distr <<
")\n";
480 std::ostringstream result;
481 result << std::setprecision(12);
482 result <<
"\n" <<
indent() <<
"# Define composition of particles at specific positions\n";
483 for (
const auto* s : v) {
484 const std::string& key =
m_objs->obj2key(s);
485 result <<
indent() << key <<
" = ba.ParticleComposition()\n";
486 const auto particle_list = node_progeny::ChildNodesOfType<IParticle>(*s);
487 for (
const auto* particle : particle_list) {
488 result <<
indent() << key <<
".addParticle(" <<
m_objs->obj2key(particle) <<
")\n";
490 setRotationInformation(s, key, result);
491 setPositionInformation(s, key, result);
501 std::ostringstream result;
502 result << std::setprecision(12);
503 result <<
"\n" <<
indent() <<
"# Define mesocrystals\n";
504 for (
const auto* s : v) {
505 const std::string& key =
m_objs->obj2key(s);
506 auto crystal = node_progeny::OnlyChildOfType<Crystal>(*s);
507 auto outer_shape = node_progeny::OnlyChildOfType<IFormFactor>(*s);
508 if (!crystal || !outer_shape)
510 result <<
indent() << key <<
" = ba.MesoCrystal(";
511 result <<
m_objs->obj2key(crystal) <<
", ";
512 result <<
m_objs->obj2key(outer_shape) <<
")\n";
513 setRotationInformation(s, key, result);
514 setPositionInformation(s, key, result);
524 std::ostringstream result;
525 result << std::setprecision(12);
526 result <<
"\n" <<
indent() <<
"# Define 2D lattices\n";
527 for (
const auto* s : v) {
528 const std::string& key =
m_objs->obj2key(s);
529 result <<
indent() << key <<
" = ba.BasicLattice2D(\n";
542 std::ostringstream result;
543 result << std::setprecision(12);
544 result <<
"\n" <<
indent() <<
"# Define 3D lattices\n";
545 for (
const auto* s : v) {
546 const std::string& key =
m_objs->obj2key(s);
550 result <<
indent() << key <<
" = ba.Lattice3D(\n";
563 std::vector<const Crystal*> v =
m_objs->objectsOfType<
Crystal>();
566 std::ostringstream result;
567 result << std::setprecision(12);
568 result <<
"\n" <<
indent() <<
"# Define crystals\n";
569 for (
const auto* s : v) {
570 const std::string& key =
m_objs->obj2key(s);
571 const auto* lattice = node_progeny::OnlyChildOfType<Lattice3D>(*s);
572 const auto* basis = node_progeny::OnlyChildOfType<IParticle>(*s);
573 if (!lattice || !basis)
575 result <<
indent() << key <<
" = ba.Crystal(";
576 result <<
m_objs->obj2key(basis) <<
", ";
577 result <<
m_objs->obj2key(lattice) <<
")\n";
587 std::ostringstream result;
588 result << std::setprecision(12);
590 result <<
"\n" <<
indent() <<
"# Define sample\n";
591 for (
const auto* s : v) {
592 const std::string& key =
m_objs->obj2key(s);
593 result <<
indent() << key <<
" = ba.MultiLayer()\n";
594 double ccl = s->crossCorrLength();
596 result <<
indent() << key <<
".setCrossCorrLength(" << ccl <<
")\n";
597 auto external_field = s->externalField();
598 if (external_field.mag() > 0.0) {
599 std::string field_name = key +
"_external_field";
600 result <<
indent() << field_name <<
" = kvector_t("
604 result <<
indent() << key <<
".setExternalField(" << field_name <<
")\n";
606 size_t numberOfLayers = s->numberOfLayers();
607 if (numberOfLayers) {
608 result <<
indent() << key <<
".addLayer(" <<
m_objs->obj2key(s->layer(0)) <<
")\n";
610 size_t layerIndex = 1;
611 while (layerIndex != numberOfLayers) {
612 const LayerInterface* layerInterface = s->layerInterface(layerIndex - 1);
614 result <<
indent() << key <<
".addLayerWithTopRoughness("
615 <<
m_objs->obj2key(s->layer(layerIndex)) <<
", "
616 <<
m_objs->obj2key(rough) <<
")\n";
618 result <<
indent() << key <<
".addLayer("
619 <<
m_objs->obj2key(s->layer(layerIndex)) <<
")\n";
623 result <<
"\n" <<
indent() <<
"return " << key <<
"\n";
Defines the macro ASSERT.
#define ASSERT(condition)
std::complex< double > complex_t
Defines class ComponentKeyHandler.
Includes all interference function definitions.
Defines class LayerInterface.
Defines class LayerRoughness.
Defines class MaterialKeyHandler.
Defines class MesoCrystal.
Defines class MultiLayer.
Defines namespace node_progeny.
Defines class ParticleComposition.
Defines ParticleCoreShell.
Defines class ParticleDistribution.
Defines class ParticleLayout.
Defines namespace pyfmt2.
Defines functions in namespace pyfmt.
const std::map< MATERIAL_TYPES, std::string > factory_names
Defines class SampleToPython.
BasicVector3D< double > kvector_t
T z() const
Returns z-component in cartesian coordinate system.
T y() const
Returns y-component in cartesian coordinate system.
T x() const
Returns x-component in cartesian coordinate system.
Stores IComponent instances, associates them with given tag, and provides unique keys.
A crystal structure, defined by a Bravais lattice, a basis, and a position variance.
Interface for two-dimensional distributions in Fourier space.
Abstract base class of interference functions.
const std::string & getName() const
Abstract base class for Particle, ParticleComposition, ParticleCoreShell, MesoCrystal.
kvector_t position() const
Returns particle position.
const IRotation * rotation() const
Returns rotation object.
virtual Transform3D getTransform3D() 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.
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 * getRoughness() const
Returns roughness of the interface.
A roughness of interface between two layers.
A layer in a MultiLayer sample.
Stores Material instances, associates them with given tag, and provides unique keys.
A wrapper for underlying material implementation.
kvector_t magnetization() const
Get the magnetization (in A/m)
bool isScalarMaterial() const
Indicates whether the interaction with the material is scalar.
std::string getName() const
Returns the name of material.
MATERIAL_TYPES typeID() const
Returns the type of underlying material implementation.
complex_t materialData() const
Returns underlying material data.
A particle with an internal structure of smaller particles.
Our sample model: a stack of layers one below the other.
A parametric distribution function, for use with any model parameter.
const IDistribution1D * getDistribution() const
std::vector< std::string > getLinkedParameterNames() const
get list of linked parameter names
A composition of particles at fixed positions.
A particle with a core/shell geometry.
A particle type that is a parametric distribution of IParticle's.
Decorator class that adds particles to ISampleNode objects.
A particle with a form factor and refractive index.
std::string defineLayers() const
std::string defineGetSample() const
std::string defineFormFactors() const
std::string defineMaterials() const
std::string defineLattices3D() const
std::string defineMesoCrystals() const
void initLabels(const MultiLayer &multilayer)
std::string defineCrystals() const
std::string defineParticles() const
std::string defineParticleCompositions() const
std::string defineParticleDistributions() const
std::unique_ptr< ComponentKeyHandler > m_objs
std::string defineLattices2D() const
std::string defineParticleLayouts() const
std::string defineCoreShellParticles() const
std::string defineInterferenceFunctions() const
std::string defineMultiLayers() const
std::string defineRoughnesses() const
std::string sampleCode(const MultiLayer &multilayer)
std::unique_ptr< MaterialKeyHandler > m_materials
QString const & name(EShape k)
std::string printParameterDistribution(const ParameterDistribution &par_distr, const std::string &distVarName, const std::string &units)
std::string printDistribution(const IDistribution1D &par_distr, const std::string &units)
Prints distribution with constructor parameters in given units.
std::string argumentList(const IParametricComponent *ip)
Returns comma-separated list of parameter values, including unit multiplicator (like "* nm").
std::string printNm(double input)
std::string printNm2(double input)
std::string printDegrees(double input)
std::string printDouble(double input)
std::string printScientificDouble(double input)
std::string indent(size_t width)
Returns a string of blanks with given width.