diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/DiffRotDiscreteCircle.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/DiffRotDiscreteCircle.h index 0e711510bc02..9ae2af98d07c 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/DiffRotDiscreteCircle.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/DiffRotDiscreteCircle.h @@ -53,6 +53,9 @@ class DLLExport ElasticDiffRotDiscreteCircle : public DeltaFunction /// overwrite IFunction base class methods virtual std::string name()const{ return "ElasticDiffRotDiscreteCircle"; } + /// overwrite IFunction base class method, which declare function parameters + virtual void init(); + /// A rescaling of the peak intensity double HeightPrefactor() const; @@ -74,13 +77,15 @@ class DLLExport InelasticDiffRotDiscreteCircle : public API::ParamFunction, publ virtual std::string name() const { return "InelasticDiffRotDiscreteCircle"; } + virtual void init(); + protected: virtual void function1D( double * out, const double* xValues, const size_t nData ) const; private: - const double m_t2e; // converstion from picosec to mili-eV, or from nanosec to micro-eV + const double m_h; // Plank constant, in meV*THz (or ueV*PHz) }; @@ -93,9 +98,6 @@ class DLLExport DiffRotDiscreteCircle : public API::ImmutableCompositeFunction { public: - /// Constructor - DiffRotDiscreteCircle(); - /// Destructor ~DiffRotDiscreteCircle() {}; @@ -105,6 +107,8 @@ class DLLExport DiffRotDiscreteCircle : public API::ImmutableCompositeFunction virtual int version() const { return 1; } + virtual void init(); + /// Propagate an attribute to member functions virtual void trickleDownAttribute( const std::string &name ); diff --git a/Code/Mantid/Framework/CurveFitting/src/DiffRotDiscreteCircle.cpp b/Code/Mantid/Framework/CurveFitting/src/DiffRotDiscreteCircle.cpp index 2de63a6fc38b..c7d323e8a900 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DiffRotDiscreteCircle.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DiffRotDiscreteCircle.cpp @@ -17,7 +17,7 @@ The Decay fitting parameter \tau is the inverse of the transition r
\tau_l^{-1} = 4 \tau^{-1} sin^2(\frac{\pi l}{N})
-If the unit of \omega is energy, and the energy unit is \mueV, then \tau is expressed in nano-seconds. If E-unit is meV then \tau is expressed in pico-seconds. The conversion equation used between the jump transition rate k, expressed in energy units, and \tau is: k\cdot \tau=4.136\, meV\cdot ps=4.136\, \mu eV\cdot ns +The transition rate, expressed in units of energy is h\tau^{-1}, with h = 4.135665616 meV THz. == Example: Methyl Rotations == Methyl Rotations can be modelled setting N=3. In this case, the inelastic part reduces to a single Lorentzian: @@ -26,10 +26,10 @@ Methyl Rotations can be modelled setting N=3. In this case, the inelastic part r If, alternatively, one models these dynamics using the [[Lorentzian]] function provided in Mantid: -
S(Q,E) = A \delta (\omega) + \frac{B}{\pi} \left( \frac{\frac{\Gamma}{2}}{(\frac{\Gamma}{2})^2 + \omega^2}\right)
-Then the following equalities hold: -
B = 2\,A_1
-
\Gamma = 6\cdot 4.126/\tau
+
S(Q,E) = A \delta (\omega) + \frac{B}{\pi} \left( \frac{\frac{\Gamma}{2}}{(\frac{\Gamma}{2})^2 + (\hbar\omega)^2}\right)
+Then: +
B = \frac{1}{\pi}h A_1
+
\Gamma = \frac{3}{\pi} h\tau^{-1} = 3.949269754 meV\cdot THz \cdot \tau^{-1}
== Properties == @@ -55,7 +55,6 @@ Then the following equalities hold: |inverse of the transition rate (ps if energy in meV; ns if energy in \mueV) |} - [[Category:Fit_functions]] *WIKI*/ @@ -81,17 +80,18 @@ DECLARE_FUNCTION(DiffRotDiscreteCircle); ElasticDiffRotDiscreteCircle::ElasticDiffRotDiscreteCircle(){ //declareParameter("Height", 1.0); //parameter "Height" already declared in constructor of base class DeltaFunction declareParameter( "Radius", 1.0, "Circle radius [Angstroms] " ); + declareAttribute( "Q", API::IFunction::Attribute(0.5) ); + declareAttribute( "N", API::IFunction::Attribute(3) ); +} +void ElasticDiffRotDiscreteCircle::init() +{ // Ensure positive values for Height and Radius BoundaryConstraint* HeightConstraint = new BoundaryConstraint( this, "Height", std::numeric_limits::epsilon(), true ); addConstraint( HeightConstraint ); BoundaryConstraint* RadiusConstraint = new BoundaryConstraint( this, "Radius", std::numeric_limits::epsilon(), true ); addConstraint( RadiusConstraint ); - - declareAttribute( "Q", API::IFunction::Attribute(0.5) ); - declareAttribute( "N", API::IFunction::Attribute(3) ); - } double ElasticDiffRotDiscreteCircle::HeightPrefactor() const{ @@ -108,7 +108,7 @@ double ElasticDiffRotDiscreteCircle::HeightPrefactor() const{ return aN / N; } -InelasticDiffRotDiscreteCircle::InelasticDiffRotDiscreteCircle() : m_t2e(4.136) +InelasticDiffRotDiscreteCircle::InelasticDiffRotDiscreteCircle() : m_h(4.135665616) { declareParameter( "Intensity",1.0, "scaling factor [arbitrary units]" ); declareParameter( "Radius", 1.0, "Circle radius [Angstroms]" ); @@ -116,7 +116,10 @@ InelasticDiffRotDiscreteCircle::InelasticDiffRotDiscreteCircle() : m_t2e(4.136) declareAttribute( "Q", API::IFunction::Attribute( 0.5 ) ); declareAttribute( "N", API::IFunction::Attribute( 3 ) ); +} +void InelasticDiffRotDiscreteCircle::init() +{ // Ensure positive values for Intensity, Radius, and decay BoundaryConstraint* IntensityConstraint = new BoundaryConstraint( this, "Intensity", std::numeric_limits< double >::epsilon(), true ); addConstraint(IntensityConstraint); @@ -126,15 +129,13 @@ InelasticDiffRotDiscreteCircle::InelasticDiffRotDiscreteCircle() : m_t2e(4.136) BoundaryConstraint* DecayConstraint = new BoundaryConstraint( this, "Decay", std::numeric_limits< double >::epsilon(), true ); addConstraint( DecayConstraint ); - } - void InelasticDiffRotDiscreteCircle::function1D( double *out, const double* xValues, const size_t nData ) const { const double I = getParameter( "Intensity" ); const double R = getParameter( "Radius" ); - const double rate = m_t2e / getParameter( "Decay" ); // micro-eV or mili-eV + const double rate = m_h / getParameter( "Decay" ); // micro-eV or mili-eV const double Q = getAttribute( "Q" ).asDouble(); const int N = getAttribute( "N" ).asInt(); @@ -206,26 +207,27 @@ void DiffRotDiscreteCircle::setAttribute( const std::string& name, const Attribu trickleDownAttribute( name ); } -DiffRotDiscreteCircle::DiffRotDiscreteCircle() +//DiffRotDiscreteCircle::DiffRotDiscreteCircle() +void DiffRotDiscreteCircle::init() { m_elastic = boost::dynamic_pointer_cast( API::FunctionFactory::Instance().createFunction( "ElasticDiffRotDiscreteCircle" ) ); addFunction( m_elastic ); m_inelastic = boost::dynamic_pointer_cast( API::FunctionFactory::Instance().createFunction( "InelasticDiffRotDiscreteCircle" ) ); addFunction( m_inelastic ); - this->setAttributeValue( "NumDeriv", true ); + setAttributeValue( "NumDeriv", true ); - this->declareAttribute( "Q", API::IFunction::Attribute( 0.5 ) ); - this->declareAttribute( "N", API::IFunction::Attribute( 3 ) ); + declareAttribute( "Q", API::IFunction::Attribute( 0.5 ) ); + declareAttribute( "N", API::IFunction::Attribute( 3 ) ); //Set the aliases - this->setAlias( "f1.Intensity", "Intensity" ); - this->setAlias( "f1.Radius", "Radius" ); - this->setAlias( "f1.Decay", "Decay" ); + setAlias( "f1.Intensity", "Intensity" ); + setAlias( "f1.Radius", "Radius" ); + setAlias( "f1.Decay", "Decay" ); //Set the ties between Elastic and Inelastic parameters - this->addDefaultTies( "f0.Height=f1.Intensity,f0.Radius=f1.Radius" ); - this->applyTies(); + addDefaultTies( "f0.Height=f1.Intensity,f0.Radius=f1.Radius" ); + applyTies(); } diff --git a/Code/Mantid/Framework/CurveFitting/test/DiffRotDiscreteCircleTest.h b/Code/Mantid/Framework/CurveFitting/test/DiffRotDiscreteCircleTest.h index b39bdfefccd3..66414510910a 100644 --- a/Code/Mantid/Framework/CurveFitting/test/DiffRotDiscreteCircleTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/DiffRotDiscreteCircleTest.h @@ -189,6 +189,7 @@ class DiffRotDiscreteCircleTest : public CxxTest::TestSuite const double Q = 0.7; const int N = 4; Mantid::CurveFitting::DiffRotDiscreteCircle func; + func.init(); func.setParameter( "f1.Intensity", I ); func.setParameter( "f1.Radius" , R ); func.setParameter( "f1.Decay", tao ); @@ -221,6 +222,7 @@ class DiffRotDiscreteCircleTest : public CxxTest::TestSuite // This should set parameters of the inelastic part Mantid::CurveFitting::DiffRotDiscreteCircle func; + func.init(); func.setParameter( "Intensity", I ); func.setParameter( "Radius", R ); func.setParameter( "Decay", tao ); @@ -338,7 +340,8 @@ class DiffRotDiscreteCircleTest : public CxxTest::TestSuite */ Mantid::DataObjects::Workspace2D_sptr generateN3Workspace( const double & I, const double & R, const double & tao, const double & Q ) { - const double rate = 4.136 / tao; // conversion from picosec to mili-eV, or from nanosec to micro-eV + const double h = 4.135665616; // plank constant in meV*THz (or ueV*PHz) + const double rate = h / tao; // conversion from picosec to mili-eV, or from nanosec to micro-eV // calculate prefix A1. Better be verbose for clarity const double x = Q * R * sqrt( 3.0 );