Skip to content
Snippets Groups Projects
Commit 98bce903 authored by Van Herck, Walter's avatar Van Herck, Walter
Browse files

Implemented cloneInvertB() on ISample classes and use a MultiLayer with...

Implemented cloneInvertB() on ISample classes and use a MultiLayer with inverted magnetic field for the outgoing scattering states if necessary; refactored MagneticCoefficientsMap
parent fd59a874
No related branches found
No related tags found
No related merge requests found
Showing
with 214 additions and 51 deletions
......@@ -24,6 +24,8 @@
#include "MessageService.h"
#include "MagneticCoefficientsMap.h"
#include <boost/scoped_ptr.hpp>
MultiLayerDWBASimulation::MultiLayerDWBASimulation(
const MultiLayer* p_multi_layer)
......@@ -100,6 +102,8 @@ void MultiLayerDWBASimulation::run()
doubleFresnelPair_t;
std::vector<doubleFresnelPair_t> doubleFresnel_buffer;
std::set<double> alpha_set = getAlphaList();
// also add incoming alpha
alpha_set.insert(-m_alpha_i);
doubleFresnel_buffer.reserve(alpha_set.size());
double angle;
......@@ -165,8 +169,7 @@ void MultiLayerDWBASimulation::runMagnetic()
double lambda = 2*M_PI/m_ki_real.mag();
// collect all (alpha, phi) angles and calculate Fresnel coefficients
// TODO: reverse B-field for k_f
// (also one set of coefficients for the incoming wavevector)
typedef Utils::UnorderedMap<double, SpecularMagnetic::MultiLayerCoeff_t>
container_phi_t;
typedef Utils::UnorderedMap<double, container_phi_t> container_t;
......@@ -179,6 +182,10 @@ void MultiLayerDWBASimulation::runMagnetic()
kvector_t kvec;
container_phi_t phi_coeffs;
SpecularMagnetic::MultiLayerCoeff_t coeffs;
// the coefficients for the incoming wavevector are calculated on the
// sample with inverted magnetic field:
boost::scoped_ptr<MultiLayer> P_inverted_B_multi_layer(
mp_multi_layer->cloneInvertB());
for (std::set<double>::const_iterator it_alpha =
alpha_set.begin(); it_alpha != alpha_set.end(); ++it_alpha) {
alpha = *it_alpha;
......@@ -186,14 +193,17 @@ void MultiLayerDWBASimulation::runMagnetic()
for (std::set<double>::const_iterator it_phi =
phi_set.begin(); it_phi != phi_set.end(); ++it_phi) {
phi = *it_phi;
kvec.setLambdaAlphaPhi(lambda, -alpha, -phi);
specularCalculator.execute(*mp_multi_layer, kvec, coeffs);
kvec.setLambdaAlphaPhi(lambda, alpha, phi);
specularCalculator.execute(*P_inverted_B_multi_layer, -kvec, coeffs);
phi_coeffs[phi] = coeffs;
}
multi_layer_coeff_buffer[alpha] = phi_coeffs;
}
// the coefficients for the incoming wavevector are calculated on the
// original sample
specularCalculator.execute(*mp_multi_layer, m_ki_real, coeffs);
// run through layers and add DWBA calculated from these layers
// run through layers and add DWBA from each layer
MagneticCoefficientsMap::container_phi_t phi_layer_coeffs;
for(size_t i_layer=0;
i_layer<mp_multi_layer->getNumberOfLayers(); ++i_layer) {
......@@ -201,6 +211,7 @@ void MultiLayerDWBASimulation::runMagnetic()
"-> Layer " << i_layer;
MagneticCoefficientsMap coeff_map;
// construct the reflection/transmission coefficients for this layer
for(Utils::UnorderedMap<double, container_phi_t>::const_iterator
it_alpha = multi_layer_coeff_buffer.begin();
it_alpha!=multi_layer_coeff_buffer.end(); ++it_alpha) {
......@@ -217,6 +228,8 @@ void MultiLayerDWBASimulation::runMagnetic()
}
coeff_map[alpha] = phi_layer_coeffs;
}
// add reflection/transmission coeffs from incoming beam
coeff_map.incomingCoeff() = coeffs[i_layer];
// layer DWBA simulation
std::map<size_t, LayerDWBASimulation*>::const_iterator pos =
......@@ -241,8 +254,6 @@ std::set<double> MultiLayerDWBASimulation::getAlphaList() const
result.insert(alpha_bin.getMidPoint());
result.insert(alpha_bin.m_upper);
}
// Also add input angle
result.insert(-m_alpha_i);
return result;
}
......@@ -256,7 +267,5 @@ std::set<double> MultiLayerDWBASimulation::getPhiList() const
result.insert(phi_bin.getMidPoint());
result.insert(phi_bin.m_upper);
}
// Also add input angle
result.insert(0.0);
return result;
}
......@@ -25,12 +25,15 @@
class Crystal : public IClusteredParticles
{
public:
public:
Crystal(const LatticeBasis& lattice_basis, const Lattice& lattice);
~Crystal();
virtual Crystal *clone() const;
//! Returns a clone with inverted magnetic fields
virtual Crystal *cloneInvertB() const;
//! Calls the ISampleVisitor's visit method
virtual void accept(ISampleVisitor *p_visitor) const { p_visitor->visit(this); }
......@@ -51,7 +54,9 @@ class Crystal : public IClusteredParticles
virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(
const ParticleInfo& parent_info) const;
private:
private:
Crystal(LatticeBasis *p_lattice_basis, const Lattice& lattice);
Lattice m_lattice;
LatticeBasis *mp_lattice_basis;
double m_dw_factor;
......
......@@ -26,36 +26,49 @@
class IClusteredParticles : public ICompositeSample
{
public:
public:
IClusteredParticles() {}
virtual ~IClusteredParticles() {}
//! clone method to allow for polymorphic copying
virtual IClusteredParticles *clone() const { throw NotImplementedException("IClusteredParticles::clone() -> Error! Not implemented exception"); }
virtual void setAmbientMaterial(const IMaterial *p_ambient_material)=0;
//! @brief create a total form factor for the mesocrystal with a specific shape and content
//! @param meso_crystal_form_factor the form factor describing the shape of the mesocrystal
//! @param ambient_refractive_index the refractive index of the ambient material
//! The bulk content of the mesocrystal is encapsulated by the IClusteredParticles object itself
// virtual IFormFactor *createTotalFormFactor(const IFormFactor& meso_crystal_form_factor,
// complex_t ambient_refractive_index) const=0;
virtual IClusteredParticles *clone() const {
throw NotImplementedException("IClusteredParticles::clone() -> Error! "
"Not implemented exception");
}
// virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(const ParticleInfo& parent_info) const=0;
//! Returns a clone with inverted magnetic fields
virtual IClusteredParticles *cloneInvertB() const {
throw NotImplementedException("IClusteredParticles::cloneInvertB() -> "
"Error! Not implemented exception");
}
virtual void setAmbientMaterial(const IMaterial *p_ambient_material)=0;
virtual IFormFactor *createTotalFormFactor(const IFormFactor& meso_crystal_form_factor,
const IMaterial *p_ambient_material) const
//! @brief create a total form factor for the mesocrystal with a specific
//! shape and content
//! @param meso_crystal_form_factor the form factor describing the shape
//! of the mesocrystal
//! @param ambient_refractive_index the refractive index of the
//! ambient material
//! The bulk content of the mesocrystal is encapsulated by the
//! IClusteredParticles object itself
virtual IFormFactor *createTotalFormFactor(
const IFormFactor& meso_crystal_form_factor,
const IMaterial *p_ambient_material) const
{
(void)meso_crystal_form_factor;
(void)p_ambient_material;
throw NotImplementedException("IClusteredParticles::createTotalFormFactor() -> NotImplementedException");
throw NotImplementedException(
"IClusteredParticles::createTotalFormFactor() "
"-> NotImplementedException");
}
virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(const ParticleInfo& parent_info) const
virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(
const ParticleInfo& parent_info) const
{
(void)parent_info;
throw NotImplementedException("IClusteredParticles::createDiffuseParticleInfo() -> NotImplementedException");
throw NotImplementedException(
"IClusteredParticles::createDiffuseParticleInfo() "
"-> NotImplementedException");
}
};
......
......@@ -34,6 +34,9 @@ class IDecoration : public ICompositeSample
virtual IDecoration *clone() const=0;
//! Returns a clone with inverted magnetic fields
virtual IDecoration *cloneInvertB() const=0;
//! Returns number of particles
virtual size_t getNumberOfParticles() const=0;
......
......@@ -37,6 +37,9 @@ class BA_CORE_API_ ISample : public IParameterized, public ICloneable
virtual ISample *clone() const;
//! Returns a clone with inverted magnetic fields
virtual ISample *cloneInvertB() const;
//! Calls the ISampleVisitor's visit method
virtual void accept(ISampleVisitor *p_visitor) const = 0;
......
......@@ -22,13 +22,16 @@
class LatticeBasis : public Particle
{
public:
public:
LatticeBasis();
LatticeBasis(const Particle& particle);
LatticeBasis(const Particle& particle, std::vector<kvector_t > positions);
virtual ~LatticeBasis();
virtual LatticeBasis *clone() const;
//! Returns a clone with inverted magnetic fields
virtual LatticeBasis *cloneInvertB() const;
//! Calls the ISampleVisitor's visit method
virtual void accept(ISampleVisitor *p_visitor) const { p_visitor->visit(this); }
......@@ -57,10 +60,13 @@ class LatticeBasis : public Particle
//! Creates vector of size/shape distributed particles corresponding to the particle with index i
std::vector<DiffuseParticleInfo *> createDiffuseParticleInfos() const;
private:
private:
//! Checks index
inline size_t check_index(size_t index) const { return index < m_positions_vector.size() ? index : throw OutOfBoundsException("LatticeBasis::check_index() -> Index is out of bounds"); }
//! For internal use in cloneInvertB():
void addParticle(Particle *p_particle, std::vector<kvector_t > positions);
std::vector<Particle *> m_particles;
std::vector<std::vector<kvector_t> > m_positions_vector;
};
......
......@@ -40,6 +40,9 @@ class BA_CORE_API_ Layer : public ICompositeSample
virtual Layer *clone() const { return new Layer(*this); }
//! Returns a clone with inverted magnetic fields
virtual Layer *cloneInvertB() const;
//! Calls the ISampleVisitor's visit method
virtual void accept(ISampleVisitor *p_visitor) const { p_visitor->visit(this); }
......
......@@ -42,12 +42,12 @@ class BA_CORE_API_ MaterialManager: public ISingleton<MaterialManager>
static const IMaterial *getMaterial(const std::string& name)
{ return instance().this_getMaterial(name); }
//! Adds material to database.
//! Adds and returns material to database.
static const IMaterial *getHomogeneousMaterial(
const std::string& name, const complex_t& refractive_index)
{ return instance().this_getHomogeneousMaterial(name, refractive_index); }
//! Adds material to database.
//! Adds and returns material to database.
static const IMaterial *getHomogeneousMaterial(
const std::string& name,
double refractive_index_delta,
......@@ -55,14 +55,14 @@ class BA_CORE_API_ MaterialManager: public ISingleton<MaterialManager>
{ return instance().this_getHomogeneousMaterial(
name, refractive_index_delta, refractive_index_beta); }
//! Adds magnetic material to database.
//! Adds and returns magnetic material to database.
static const IMaterial *getHomogeneousMagneticMaterial(
const std::string& name, const complex_t& refractive_index,
const kvector_t &magnetic_field)
{ return instance().this_getHomogeneousMagneticMaterial(name,
refractive_index, magnetic_field); }
//! Adds magnetic material to database.
//! Adds and returns magnetic material to database.
static const IMaterial *getHomogeneousMagneticMaterial(
const std::string& name,
double refractive_index_delta,
......@@ -72,6 +72,12 @@ class BA_CORE_API_ MaterialManager: public ISingleton<MaterialManager>
name, refractive_index_delta, refractive_index_beta,
magnetic_field); }
//! Adds and returns material with inverted magnetic field (if present) to
//! database. The new material is based on the material with the given name
static const IMaterial *getInvertedMaterial(
const std::string& name)
{ return instance().this_getInvertedMaterial(name); }
//! returns number of materials
static int getNumberOfMaterials() { return instance().
this_getNumberOfMaterials(); }
......@@ -122,6 +128,8 @@ class BA_CORE_API_ MaterialManager: public ISingleton<MaterialManager>
const std::string& name,
double refractive_index_delta, double refractive_index_beta,
const kvector_t &magnetic_field);
const IMaterial *this_getInvertedMaterial(
const std::string& name);
int this_getNumberOfMaterials() const { return (int)m_materials.size(); }
void check_refractive_index(const complex_t &index);
......
......@@ -31,6 +31,9 @@ class MesoCrystal : public Particle
virtual ~MesoCrystal();
virtual MesoCrystal *clone() const;
//! Returns a clone with inverted magnetic fields
virtual MesoCrystal *cloneInvertB() const;
//! Calls the ISampleVisitor's visit method
virtual void accept(ISampleVisitor *p_visitor) const { p_visitor->visit(this); }
......
......@@ -83,9 +83,13 @@ class BA_CORE_API_ MultiLayer : public ICompositeSample
//! Destructs allocated objects
void clear();
//! Returns alone of multilayer with clones of all layers and recreated interfaces between layers
//! Returns alone of multilayer with clones of all layers and recreated
//! interfaces between layers
virtual MultiLayer *clone() const;
//! Returns a clone with inverted magnetic fields
virtual MultiLayer *cloneInvertB() const;
//! Sets cross correlation length of roughnesses between interfaces
inline void setCrossCorrLength(double crossCorrLength)
{
......@@ -100,7 +104,8 @@ class BA_CORE_API_ MultiLayer : public ICompositeSample
///! correlation function of roughnesses between the interfaces
//double getCrossCorrFun(const kvector_t& k, int j, int k) const;
//! Fourier transform of the correlation function of roughnesses between the interfaces
//! Fourier transform of the correlation function of roughnesses between
//! the interfaces
double getCrossCorrSpectralFun(
const kvector_t& kvec, size_t j, size_t k) const;
......@@ -111,7 +116,8 @@ class BA_CORE_API_ MultiLayer : public ICompositeSample
friend std::ostream& operator << (std::ostream& ostr, const MultiLayer& m)
{ m.print(ostr); return ostr; }
//! look for the presence of DWBA terms (e.g. included particles) and return ISimulation if needed
//! look for the presence of DWBA terms (e.g. included particles) and return
//! ISimulation if needed
virtual MultiLayerDWBASimulation *createDWBASimulation() const;
protected:
......
......@@ -35,6 +35,9 @@ class BA_CORE_API_ Particle : public ICompositeSample
virtual ~Particle();
virtual Particle *clone() const;
//! Returns a clone with inverted magnetic fields
virtual Particle *cloneInvertB() const;
//! calls the ISampleVisitor's visit method
virtual void accept(ISampleVisitor *visitor) const { visitor->visit(this); }
......
......@@ -22,15 +22,22 @@
class ParticleCoreShell : public Particle
{
public:
ParticleCoreShell(const Particle& shell, const Particle& core, kvector_t relative_core_position);
public:
ParticleCoreShell(const Particle& shell, const Particle& core,
kvector_t relative_core_position);
virtual ~ParticleCoreShell();
virtual ParticleCoreShell *clone() const;
//! Returns a clone with inverted magnetic fields
virtual ParticleCoreShell *cloneInvertB() const;
//! Calls the ISampleVisitor's visit method
virtual void accept(ISampleVisitor *p_visitor) const { p_visitor->visit(this); }
virtual void accept(ISampleVisitor *p_visitor) const {
p_visitor->visit(this);
}
//! Sets the refractive index of the ambient material (which influences its scattering power)
//! Sets the refractive index of the ambient material (which influences
//! its scattering power)
virtual void setAmbientMaterial(const IMaterial *p_material)
{
mp_ambient_material = p_material;
......@@ -40,7 +47,8 @@ class ParticleCoreShell : public Particle
virtual IFormFactor* createFormFactor() const;
//! Sets the formfactor of the particle (not including scattering factor from refractive index)
//! Sets the formfactor of the particle (not including scattering factor
//! from refractive index)
virtual void setSimpleFormFactor(IFormFactor* p_form_factor)
{
if (p_form_factor != mp_form_factor) {
......@@ -51,16 +59,21 @@ class ParticleCoreShell : public Particle
}
}
//! Returns formfactor of the particle (not including scattering factor from refractive index)
virtual const IFormFactor *getSimpleFormFactor() const { return mp_form_factor;}
//! Returns formfactor of the particle (not including scattering factor
//! from refractive index)
virtual const IFormFactor *getSimpleFormFactor() const {
return mp_form_factor;
}
//! Creates list of contained particles for diffuse calculations
virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(const ParticleInfo& parent_info) const {
virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(
const ParticleInfo& parent_info) const {
(void)parent_info;
return 0;
}
protected:
protected:
ParticleCoreShell(kvector_t relative_core_position);
Particle *mp_shell;
Particle *mp_core;
kvector_t m_relative_core_position;
......
......@@ -56,6 +56,9 @@ class BA_CORE_API_ ParticleDecoration : public IDecoration
virtual ParticleDecoration *clone() const;
//! Returns a clone with inverted magnetic fields
virtual ParticleDecoration *cloneInvertB() const;
//! calls the ISampleVisitor's visit method
virtual void accept(ISampleVisitor *visitor) const { visitor->visit(this); }
......
......@@ -44,6 +44,13 @@ class ParticleInfo : public ICompositeSample
mp_particle->clone(), mP_transform, m_depth, m_abundance);
}
//! Returns a clone with inverted magnetic fields
virtual ParticleInfo *cloneInvertB() const
{
return new ParticleInfo(
mp_particle->cloneInvertB(), mP_transform, m_depth, m_abundance);
}
//! calls the ISampleVisitor's visit method
virtual void accept(ISampleVisitor *visitor) const { visitor->visit(this); }
......
......@@ -41,6 +41,14 @@ Crystal* Crystal::clone() const
return p_new;
}
Crystal* Crystal::cloneInvertB() const
{
Crystal *p_new = new Crystal(mp_lattice_basis->cloneInvertB(), m_lattice);
p_new->setDWFactor(m_dw_factor);
p_new->setName(getName() + "_inv");
return p_new;
}
IFormFactor* Crystal::createTotalFormFactor(
const IFormFactor& meso_crystal_form_factor,
const IMaterial *p_ambient_material) const
......@@ -82,4 +90,11 @@ std::vector<DiffuseParticleInfo*>* Crystal::createDiffuseParticleInfo(
return p_result;
}
Crystal::Crystal(LatticeBasis* p_lattice_basis, const Lattice& lattice)
: m_lattice(lattice)
, m_dw_factor(0.0)
{
setName("Crystal");
mp_lattice_basis = p_lattice_basis;
registerChild(mp_lattice_basis);
}
......@@ -27,6 +27,13 @@ ISample *ISample::clone() const
//! Adds params from local to external pool and recurses over direct children.
ISample* ISample::cloneInvertB() const
{
throw NotImplementedException(
"ISample::cloneInvertB() -> "
"Error! Method is not implemented");
}
std::string ISample::addParametersToExternalPool(
std::string path, ParameterPool *external_pool, int copy_number) const
{
......
......@@ -16,6 +16,7 @@
#include "LatticeBasis.h"
#include "FormFactors.h"
#include "DiffuseParticleInfo.h"
#include "MaterialManager.h"
LatticeBasis::LatticeBasis()
{
......@@ -55,6 +56,20 @@ LatticeBasis* LatticeBasis::clone() const
return p_new;
}
LatticeBasis* LatticeBasis::cloneInvertB() const
{
LatticeBasis *p_new = new LatticeBasis();
for (size_t index=0; index<m_particles.size(); ++index) {
p_new->addParticle(m_particles[index]->cloneInvertB(),
m_positions_vector[index]);
}
p_new->setName(getName() + "_inv");
const IMaterial *p_ambient_material = MaterialManager::getInvertedMaterial(
this->mp_ambient_material->getName());
p_new->mp_ambient_material = p_ambient_material;
return p_new;
}
void LatticeBasis::addParticle(const Particle& particle, std::vector<kvector_t > positions)
{
Particle *np = particle.clone();
......@@ -99,4 +114,10 @@ std::vector<DiffuseParticleInfo *> LatticeBasis::createDiffuseParticleInfos() co
return result;
}
void LatticeBasis::addParticle(Particle* p_particle,
std::vector<kvector_t> positions)
{
registerChild(p_particle);
m_particles.push_back(p_particle);
m_positions_vector.push_back(positions);
}
......@@ -16,6 +16,7 @@
#include "Layer.h"
#include "Exceptions.h"
#include "DecoratedLayerDWBASimulation.h"
#include "MaterialManager.h"
#include <iomanip>
......@@ -71,6 +72,21 @@ Layer::~Layer()
}
Layer* Layer::cloneInvertB() const
{
Layer *p_clone = new Layer();
p_clone->mp_material = MaterialManager::getInvertedMaterial(this->mp_material->getName());
p_clone->mp_decoration = 0;
if(this->getDecoration()) {
p_clone->setDecoration(this->getDecoration()->cloneInvertB());
}
p_clone->m_thickness = this->m_thickness;
std::string clone_name = this->getName() + "_inv";
p_clone->setName(clone_name);
p_clone->init_parameters();
return p_clone;
}
void Layer::init_parameters()
{
clearParameterPool();
......@@ -121,7 +137,6 @@ void Layer::setDecoration(const IDecoration &decoration)
setDecoration(decoration.clone());
}
//! Prints description.
void Layer::print(std::ostream& ostr) const
{
......
......@@ -153,8 +153,21 @@ const IMaterial* MaterialManager::this_getHomogeneousMagneticMaterial(
magnetic_field);
}
//! Dump this to stream.
const IMaterial* MaterialManager::this_getInvertedMaterial(
const std::string& name)
{
const IMaterial *p_orig_material = getMaterial(name);
if (!p_orig_material) return 0;
const HomogeneousMagneticMaterial *p_magn_material =
dynamic_cast<const HomogeneousMagneticMaterial *>(p_orig_material);
if (!p_magn_material) return p_orig_material;
std::string new_name = name + "_inv";
return this_getHomogeneousMagneticMaterial(new_name,
p_magn_material->getRefractiveIndex(),
-p_magn_material->getMagneticField());
}
//! Dump this to stream.
void MaterialManager::print(std::ostream& ostr) const
{
ostr << typeid(*this).name() << " " << this <<
......
......@@ -43,7 +43,14 @@ MesoCrystal::~MesoCrystal()
MesoCrystal* MesoCrystal::clone() const
{
return new MesoCrystal(mp_particle_structure->clone(), mp_meso_form_factor->clone());
return new MesoCrystal(mp_particle_structure->clone(),
mp_meso_form_factor->clone());
}
MesoCrystal* MesoCrystal::cloneInvertB() const
{
return new MesoCrystal(mp_particle_structure->cloneInvertB(),
mp_meso_form_factor->clone());
}
std::vector<DiffuseParticleInfo*>* MesoCrystal::createDiffuseParticleInfo(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment