diff --git a/App/App.pro b/App/App.pro index 0a771e19ebccf3d3fc1f39eae13e60de95c66861..43577a37ab067e0e6f28de20aa687c2bca76d115 100644 --- a/App/App.pro +++ b/App/App.pro @@ -11,7 +11,9 @@ SOURCES += \ src/TestDiffuseScattering.cpp \ src/TestFormFactor.cpp \ src/TestRoughness.cpp \ - src/TestDWBAFormFactor.cpp + src/TestDWBAFormFactor.cpp \ + src/SampleFactory.cpp \ + src/StandardSamples.cpp HEADERS += \ inc/DrawHelper.h \ @@ -21,7 +23,9 @@ HEADERS += \ inc/TestDiffuseScattering.h \ inc/TestFormFactor.h \ inc/TestRoughness.h \ - inc/TestDWBAFormFactor.h + inc/TestDWBAFormFactor.h \ + inc/SampleFactory.h \ + inc/StandardSamples.h INCLUDEPATH += ./inc DEPENDPATH += ./inc diff --git a/App/inc/SampleFactory.h b/App/inc/SampleFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..92eb72a48dbc0245113f9278c408e5f03e4ce5ac --- /dev/null +++ b/App/inc/SampleFactory.h @@ -0,0 +1,62 @@ +#ifndef SAMPLEFACTORY_H +#define SAMPLEFACTORY_H +// ******************************************************************** +// * The BornAgain project * +// * Simulation of neutron and x-ray scattering at grazing incidence * +// * * +// * LICENSE AND DISCLAIMER * +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris * +// * eget quam orci. Quisque porta varius dui, quis posuere nibh * +// * mollis quis. Mauris commodo rhoncus porttitor. * +// ******************************************************************** +//! @file SampleFactory.h +//! @brief Definition of SampleFactory class +//! @author Scientific Computing Group at FRM II +//! @date 01.05.2012 + +#include <map> +#include "ISample.h" + + +//- ------------------------------------------------------------------- +//! @class SampleFactory +//! @brief Factory to create standard pre-defined samples +//- ------------------------------------------------------------------- +class SampleFactory +{ +public: + //! access to SampleFactory + static SampleFactory &instance(); + + ISample *createStandard(int i_sample); + + typedef ISample* (*CreateSampleCallback) (); + + bool RegisterSample(int sampleId, CreateSampleCallback CreateFn); + +private: + //! prevents client from creating a copy of singleton + SampleFactory(); + SampleFactory(const SampleFactory &); + SampleFactory &operator=(const SampleFactory &); + + //! reaction on too early destroyed object + static void onDeadReference(); + + //! create single copy of manager + static void create(); + + virtual ~SampleFactory(); + + static SampleFactory *m_instance; + static bool m_destroyed; + + //! holds pointers to function which create sample of given type (which is int) + typedef std::map<int, CreateSampleCallback > SampleCallbackMap_t; + + //! holds pointers to function which create sample of given type (which is int) + SampleCallbackMap_t m_callbacks; +}; + +#endif // SAMPLEFACTORY_H + diff --git a/App/inc/StandardSamples.h b/App/inc/StandardSamples.h new file mode 100644 index 0000000000000000000000000000000000000000..94838496fe66379c700fb2487d596c74e2a3138e --- /dev/null +++ b/App/inc/StandardSamples.h @@ -0,0 +1,27 @@ +#ifndef STANDARDSAMPLES_H +#define STANDARDSAMPLES_H + +#include "ISample.h" +#include "SampleFactory.h" + +//class StandardSample : public ISample +//{ +//public: +// StandardSample(); +//}; + +namespace StandardSamples{ + +ISample *SampleAirOnSubstrate(); +const int Id_AirOnSubstrate = 1; +const bool registered_AirOnSubstrate = SampleFactory::instance().RegisterSample(Id_AirOnSubstrate, SampleAirOnSubstrate); + +ISample *SampleSubstrateOnSubstrate(); +const int Id_SubstrateOnSubstrate = 1; +const bool registered_SubstrateOnSubstrate = SampleFactory::instance().RegisterSample(Id_SubstrateOnSubstrate, SampleSubstrateOnSubstrate); + +} + + + +#endif // STANDARDSAMPLES_H diff --git a/App/inc/TestDiffuseScattering.h b/App/inc/TestDiffuseScattering.h index d1e45d64a41ac3402da9fbf7c728d26a622753b4..c8f3ff996ff0bc9f3f093703163b03598cd0cc04 100644 --- a/App/inc/TestDiffuseScattering.h +++ b/App/inc/TestDiffuseScattering.h @@ -25,7 +25,7 @@ public: void execute(); void test1(const MultiLayer &sample); - void test1_a(const MultiLayer &sample, const kvector_t &ki, const kvector_t &kf); + double test1_a(const MultiLayer &sample, const kvector_t &ki, const kvector_t &kf); }; diff --git a/App/inc/TestFresnelCoeff.h b/App/inc/TestFresnelCoeff.h index 5bf60f682a0116a86ac554383ec0bab44d4464e5..7347c09c2f21dc767450ca4ebb75c02601921b8f 100644 --- a/App/inc/TestFresnelCoeff.h +++ b/App/inc/TestFresnelCoeff.h @@ -34,6 +34,8 @@ public: void execute(); void Draw(const MultiLayer &sample, const MyDataSet_t &data); + + private: }; diff --git a/App/src/SampleFactory.cpp b/App/src/SampleFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..586cc95dc034af0f3f75e3321b6ff9cf4771bbc3 --- /dev/null +++ b/App/src/SampleFactory.cpp @@ -0,0 +1,88 @@ +#include "SampleFactory.h" +#include "Exceptions.h" + +#include <iostream> + +SampleFactory *SampleFactory::m_instance = 0; +bool SampleFactory::m_destroyed = false; + + +SampleFactory::SampleFactory() +{ + +} + + +SampleFactory::~SampleFactory() +{ + std::cout << "SampleFactory::~SampleFactory() -> Info. Deleting SampleFactory" << std::endl; + m_instance = 0; + m_destroyed = true; +} + + +/* ************************************************************************* */ +// access to material manager +/* ************************************************************************* */ +SampleFactory &SampleFactory::instance() +{ + // check if exists, if not, then initialise + if( !m_instance) { + // check for dead reference (i.e. object has been initialised but then somebody managed to delete it) + if( m_destroyed ) { + onDeadReference(); + } else { + // first call initalise + create(); + } + } + std::cout << "SampleFactory::Instance() -> Info. Accesing instance... " << m_instance << std::endl; + return *m_instance; +} + + +/* ************************************************************************* */ +// create single instance of the manager +/* ************************************************************************* */ +void SampleFactory::create() { + std::cout << "MaterialManager::Create() -> Info. Creating material manager" << std::endl; + static SampleFactory theInstance; + m_instance = &theInstance; +} + + +/* ************************************************************************* */ +// Action for abnormal situation when object has been occasionally deleted. +// The possibility to rise object again should be still implemented. +/* ************************************************************************* */ +void SampleFactory::onDeadReference() { + throw DeadReferenceException("Dead reference detected."); +} + + +/* ************************************************************************* */ +// This function is used to automatically register new classes and their +// creaion methods +/* ************************************************************************* */ +bool SampleFactory::RegisterSample(int sampleId, CreateSampleCallback CreateFn) +{ + return m_callbacks.insert( SampleCallbackMap_t::value_type(sampleId, CreateFn)).second; +} + + +/* ************************************************************************* */ +// creation of standard sample of given sampleId type +/* ************************************************************************* */ +ISample *SampleFactory::createStandard(int sampleId) +{ + SampleCallbackMap_t::const_iterator it = m_callbacks.find(sampleId); + if( it == m_callbacks.end() ) { + // sample of such kond have not been registered in the database + throw UnknownClassException("Unknown sampleId"); + } + // invoke the creation function + return (it->second)(); +} + + + diff --git a/App/src/StandardSamples.cpp b/App/src/StandardSamples.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e20d979e25a1668047c76a6d4097c1fa09239f00 --- /dev/null +++ b/App/src/StandardSamples.cpp @@ -0,0 +1,72 @@ +#include "StandardSamples.h" +#include "MultiLayer.h" +#include "MaterialManager.h" + + +/* ************************************************************************* */ +// 10 nm of ambience on top of substrate. +/* ************************************************************************* */ +ISample *StandardSamples::SampleAirOnSubstrate() +{ + MaterialManager &matManager = MaterialManager::instance(); + const IMaterial *mAmbience = matManager.addHomogeneousMaterial("ambience",complex_t(1.0, 0.0) ); + const IMaterial *mAir = matManager.addHomogeneousMaterial("air",complex_t(1.0, 0.0) ); + const IMaterial *mSubstrate = matManager.addHomogeneousMaterial("substrate", complex_t(1.0-15e-6, 0) ); + + MultiLayer *mySample = new MultiLayer; + + Layer lAmbience; + lAmbience.setMaterial(mAmbience, 0); + mySample->addLayer(lAmbience); + + Layer lAir; + lAir.setMaterial(mAir, 10); + mySample->addLayer(lAir); + + Layer lSubstrate; + lSubstrate.setMaterial(mSubstrate,0); + + LayerRoughness roughness; + roughness.setSigma(1.0); + roughness.setHurstParameter(0.3); + roughness.setLatteralCorrLength(5000.); + + mySample->addLayerWithTopRoughness(lSubstrate, roughness); + + return mySample; +} + + +/* ************************************************************************* */ +// 10 nm of substrate on top of substrate. +/* ************************************************************************* */ +ISample *StandardSamples::SampleSubstrateOnSubstrate() +{ + MaterialManager &matManager = MaterialManager::instance(); + const IMaterial *mAmbience = matManager.addHomogeneousMaterial("ambience",complex_t(1.0, 0.0) ); + const IMaterial *mSubstrate = matManager.addHomogeneousMaterial("substrate", complex_t(1.0-15e-6, 0) ); + + MultiLayer *mySample = new MultiLayer; + + Layer lAmbience; + lAmbience.setMaterial(mAmbience, 0); + mySample->addLayer(lAmbience); + + Layer likeSubstrate; + likeSubstrate.setMaterial(mSubstrate, 10); + mySample->addLayer(likeSubstrate); + + Layer lSubstrate; + lSubstrate.setMaterial(mSubstrate,0); + + LayerRoughness roughness; + roughness.setSigma(1.0); + roughness.setHurstParameter(0.3); + roughness.setLatteralCorrLength(5000.); + + mySample->addLayerWithTopRoughness(lSubstrate, roughness); + + return mySample; +} + + diff --git a/App/src/TestDiffuseScattering.cpp b/App/src/TestDiffuseScattering.cpp index 3e44ed5d6e7a2123de9510f81b92e8e37a70ab44..592b9c4d60c40ebdad79da641a5763f01682fb61 100644 --- a/App/src/TestDiffuseScattering.cpp +++ b/App/src/TestDiffuseScattering.cpp @@ -3,7 +3,9 @@ #include "TCanvas.h" #include "TGraph.h" #include "TH1F.h" +#include "TH2F.h" #include "TApplication.h" +#include "TStyle.h" #include "Layer.h" #include "MultiLayer.h" @@ -27,99 +29,143 @@ void TestDiffuseScattering::execute() std::cout << "TestDiffuseScattering::execute() -> Info." << std::endl; // creation of materials +// MaterialManager &matManager = MaterialManager::instance(); +// const IMaterial *mAmbience = matManager.addHomogeneousMaterial("ambience",complex_t(1.0, 0.0) ); +// const IMaterial *mAg1 = matManager.addHomogeneousMaterial( "air",complex_t(0.99999653774962993, 0) ); +// const IMaterial *mCr1 = matManager.addHomogeneousMaterial("Cr1",complex_t(0.99999701914797656, 0) ); +// const IMaterial *mSubstrate = matManager.addHomogeneousMaterial("substrate", complex_t(0.99999692440971188, 0) ); +// matManager.print(); +// // create layers +// MultiLayer mySample; +// Layer lAmbience; +// lAmbience.setMaterial(mAmbience, 0); +// Layer lAg1; +// lAg1.setMaterial(mAg1, 1500.0); +// Layer lCr1; +// lCr1.setMaterial(mCr1, 1200.0); +// Layer lSubstrate; +// lSubstrate.setMaterial(mSubstrate, 0); +// // adding layers +// mySample.addLayer(lAmbience); +// const unsigned nrepetitions = 4; +// for(unsigned i=0; i<nrepetitions; ++i) { +// mySample.addLayerWithTopRoughness(lAg1, LayerRoughness(3.0, 0.3, 1.0) ); // (double sigma, double hurstParameter, double latteralCorrLength +// mySample.addLayerWithTopRoughness(lCr1, LayerRoughness(3.0, 0.3, 1.0) ); +// } +// mySample.addLayerWithTopRoughness(lSubstrate, LayerRoughness(3.0, 0.3, 1.0)); +// mySample.print(); +// std::cout << "--- Attempt to clone MultiLayer" << std::endl; +// MultiLayer *newSample = mySample.clone(); +// newSample->print(); +// MultiLayer *newSample2 = newSample->clone(); +// delete newSample; +// newSample2->print(); + + MaterialManager &matManager = MaterialManager::instance(); const IMaterial *mAmbience = matManager.addHomogeneousMaterial("ambience",complex_t(1.0, 0.0) ); - const IMaterial *mAg1 = matManager.addHomogeneousMaterial( "Ag1",complex_t(0.99999653774962993, 0) ); - const IMaterial *mCr1 = matManager.addHomogeneousMaterial("Cr1",complex_t(0.99999701914797656, 0) ); - const IMaterial *mSubstrate = matManager.addHomogeneousMaterial("substrate", complex_t(0.99999692440971188, 0) ); - matManager.print(); + const IMaterial *mAir = matManager.addHomogeneousMaterial("air",complex_t(1.0, 0.0) ); + const IMaterial *mSubstrate = matManager.addHomogeneousMaterial("substrate", complex_t(1.0-15e-6, 0) ); - // create layers MultiLayer mySample; - Layer lAmbience; lAmbience.setMaterial(mAmbience, 0); + mySample.addLayer(lAmbience); - Layer lAg1; - lAg1.setMaterial(mAg1, 1500.0); - - Layer lCr1; - lCr1.setMaterial(mCr1, 1200.0); + Layer lAir; + lAir.setMaterial(mAir, 10); + mySample.addLayer(lAir); Layer lSubstrate; - lSubstrate.setMaterial(mSubstrate, 0); + lSubstrate.setMaterial(mSubstrate,0); - // adding layers - mySample.addLayer(lAmbience); + LayerRoughness roughness; + roughness.setSigma(1.0); + roughness.setHurstParameter(0.3); + roughness.setLatteralCorrLength(5000.); - const unsigned nrepetitions = 4; - for(unsigned i=0; i<nrepetitions; ++i) { - mySample.addLayerWithTopRoughness(lAg1, LayerRoughness(3.0, 0.3, 1.0) ); // (double sigma, double hurstParameter, double latteralCorrLength - mySample.addLayerWithTopRoughness(lCr1, LayerRoughness(3.0, 0.3, 1.0) ); - } - mySample.addLayerWithTopRoughness(lSubstrate, LayerRoughness(3.0, 0.3, 1.0)); + mySample.addLayerWithTopRoughness(lSubstrate, roughness); mySample.print(); -// std::cout << "--- Attempt to clone MultiLayer" << std::endl; -// MultiLayer *newSample = mySample.clone(); -// newSample->print(); -// MultiLayer *newSample2 = newSample->clone(); -// delete newSample; -// newSample2->print(); - test1(mySample); } -// dSigma/dOmega void TestDiffuseScattering::test1(const MultiLayer &sample) { - const size_t npoints = 1000.; - double alphaMin(0), alphaMax(0.5*M_PI/180.); - - for(size_t i=0; i<npoints; i++) { - double alpha_i = i*(alphaMax-alphaMin)/double(npoints); - kvector_t ki; - ki.setLambdaAlphaPhi(23.0, alpha_i, 0.0); + const size_t npoints = 100.; + double alphaMin(0), alphaMax(2.*M_PI/180.); + double d_alpha = (alphaMax-alphaMin)/double(npoints-1); - kvector_t kf; - kf.setLambdaAlphaPhi(23.0, alpha_i+180.0, 0.0); - - test1_a(sample, ki, kf); - - - } + double lambda = 1.54; + TH2F *h2 = new TH2F("h2","h2", npoints, alphaMin-d_alpha/2., alphaMax+d_alpha/2., npoints, alphaMin-d_alpha/2., alphaMax+d_alpha/2.); + h2->SetContour(50); + h2->SetMinimum(0.001); + for(size_t i=1; i<npoints; i++) { + double alpha_i = i*d_alpha; + kvector_t ki; + ki.setLambdaAlphaPhi(lambda, -alpha_i, 0.0); + for(size_t f=1; f<npoints; f++) { + double alpha_f = f*d_alpha; + kvector_t kf; + kf.setLambdaAlphaPhi(lambda, alpha_f, 0.0); + double cs = test1_a(sample, ki, kf); + std::cout << " i:" << i << " " << alpha_i << " f:" << f << " alpha_f:" << alpha_f << " cs:" << cs << std::endl; + h2->Fill(alpha_i, alpha_f,cs); + } // k + } // i + + TCanvas *c1 = new TCanvas("c1","c1",1024, 768); + c1->cd(); gPad->SetRightMargin(0.2); + gStyle->SetPalette(1); + gPad->SetLogz(); + h2->Draw("CONT4 Z"); } -void TestDiffuseScattering::test1_a(const MultiLayer &sample, const kvector_t &ki, const kvector_t &kf) +double TestDiffuseScattering::test1_a(const MultiLayer &sample, const kvector_t &ki, const kvector_t &kf) { - (void)sample; - (void)ki; - (void)kf; // calculation -// OpticalFresnel::MultiLayerCoeff_t iniFresnelCoeffs; -// OpticalFresnel::execute(sample, ki, iniFresnelCoeffs); - -// OpticalFresnel::MultiLayerCoeff_t finFresnelCoeffs; -// OpticalFresnel::execute(sample, kf, finFresnelCoeffs); - - //const double S = 1.0; - //double CS = S*ki.mag2()/16./M_PI; - -// for(size_t i=0; i<sample.getNumberOfLayers()-1; i++){ -// complex_t n1 = sample.getLayer(i)->getRefractiveIndex(); -// complex_t n2 = sample.getLayer(i+1)->getRefractiveIndex(); - //const LayerRoughness &m_roughness = sample.getLayerBottomInterface(i)->getRoughness(); - //double corr = m_roughness.getPowerSpectralDensity(ki); - -// } - - + OpticalFresnel::MultiLayerCoeff_t c_f; + OpticalFresnel::execute(sample, ki, c_f); + + OpticalFresnel::MultiLayerCoeff_t c_i; + OpticalFresnel::execute(sample, kf, c_i); + + +// MultiLayerCoeff x(OpticalFresnel::execute, sample); +// x.setSample(sample); +// x.evaluate(sample, q); +// x.getR(i); +// x. + + + double sum(0); + for(size_t i=0; i<sample.getNumberOfLayers()-1; i++){ + complex_t n1 = sample.getLayer(i)->getRefractiveIndex(); + complex_t n2 = sample.getLayer(i+1)->getRefractiveIndex(); + const LayerRoughness &rough = sample.getLayerBottomInterface(i)->getRoughness(); + double sigma = rough.getSigma(); + + kvector_t q = ki - kf; + double qz1 = ki.z() + kf.z(); + double qz2 = -ki.z() - kf.z(); + double qz3 = ki.z() - kf.z(); + double qz4 = -ki.z() + kf.z(); + complex_t term1 = c_i[i+1].T*c_f[i+1].T * std::exp( -0.5*std::pow(sigma * qz1 ,2) ); + complex_t term2 = c_i[i+1].R*c_f[i+1].T * std::exp( -0.5*std::pow(sigma * qz2 ,2) ); + complex_t term3 = c_i[i+1].T*c_f[i+1].R * std::exp( -0.5*std::pow(sigma * qz3 ,2) ); + complex_t term4 = c_i[i+1].R*c_f[i+1].T * std::exp( -0.5*std::pow(sigma * qz4 ,2) ); + + sum += std::norm( std::pow(n1,2)-std::pow(n2,2) ) * std::norm(term1 + term2 + term3 + term4) * rough.getSpectralFun(q); + } + const double S = 1.0; + double CS = sum*S*ki.mag2()/16./M_PI; + return CS; } diff --git a/Core/inc/Exceptions.h b/Core/inc/Exceptions.h index 5791539a3a451b45179f6cb39c3c261666867c5a..ef2b5b463c77396e9ed6ec75733c52447286e3c3 100644 --- a/Core/inc/Exceptions.h +++ b/Core/inc/Exceptions.h @@ -54,4 +54,12 @@ public: DeadReferenceException(const std::string& message); }; +class UnknownClassException : public std::runtime_error +{ +public: + UnknownClassException(const std::string& message); +}; + + + #endif // EXCEPTIONS_H diff --git a/Core/inc/NamedVector.h b/Core/inc/NamedVector.h index 0a7d731d692214aa99864580bf9f48050b601b84..de2789c22a1861ec67a4d3d14f3ada0ccaa88961 100644 --- a/Core/inc/NamedVector.h +++ b/Core/inc/NamedVector.h @@ -35,7 +35,7 @@ template <class T> class NamedVector : public NamedVectorBase { public: NamedVector(std::string name) : NamedVectorBase(name) {} - NamedVector(std::string name, T start, T step, size_t size); + NamedVector(std::string name, T start, T end, size_t size); ~NamedVector(); size_t getSize() { return m_value_vector.size(); } diff --git a/Core/src/Exceptions.cpp b/Core/src/Exceptions.cpp index 3e7daca3072b60c68cfdbc42456237c8d9b923b0..3113ad2d2bbdcd8658031cd247220f6e0b4fb1ba 100644 --- a/Core/src/Exceptions.cpp +++ b/Core/src/Exceptions.cpp @@ -29,3 +29,8 @@ DeadReferenceException::DeadReferenceException(const std::string &message) : std::runtime_error(message) { } + +UnknownClassException::UnknownClassException(const std::string &message) + : std::runtime_error(message) +{ +}