Skip to content

Commit

Permalink
Merge remote branch 'origin/feature/8631_DiffRotDiscreteCircle_init'
Browse files Browse the repository at this point in the history
  • Loading branch information
RussellTaylor committed Dec 20, 2013
2 parents 6447656 + 1e040ef commit e0f10f1
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 28 deletions.
Expand Up @@ -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;

Expand All @@ -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)
};


Expand All @@ -93,9 +98,6 @@ class DLLExport DiffRotDiscreteCircle : public API::ImmutableCompositeFunction
{
public:

/// Constructor
DiffRotDiscreteCircle();

/// Destructor
~DiffRotDiscreteCircle() {};

Expand All @@ -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 );

Expand Down
48 changes: 25 additions & 23 deletions Code/Mantid/Framework/CurveFitting/src/DiffRotDiscreteCircle.cpp
Expand Up @@ -17,7 +17,7 @@ The Decay fitting parameter <math>\tau</math> is the inverse of the transition r
<center><math> \tau_l^{-1} = 4 \tau^{-1} sin^2(\frac{\pi l}{N}) </math></center>
If the unit of <math>\omega</math> is energy, and the energy unit is <math>\mu</math>eV, then <math>\tau</math> is expressed in nano-seconds. If E-unit is meV then <math>\tau</math> is expressed in pico-seconds. The conversion equation used between the jump transition rate <math>k</math>, expressed in energy units, and <math>\tau</math> is: <math>k\cdot \tau=4.136\, meV\cdot ps=4.136\, \mu eV\cdot ns</math>
The transition rate, expressed in units of energy is <math>h\tau^{-1}</math>, 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:
Expand All @@ -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:
<center><math> S(Q,E) = A \delta (\omega) + \frac{B}{\pi} \left( \frac{\frac{\Gamma}{2}}{(\frac{\Gamma}{2})^2 + \omega^2}\right) </math></center>
Then the following equalities hold:
<center><math>B = 2\,A_1</math></center>
<center><math>\Gamma = 6\cdot 4.126/\tau</math></center>
<center><math> S(Q,E) = A \delta (\omega) + \frac{B}{\pi} \left( \frac{\frac{\Gamma}{2}}{(\frac{\Gamma}{2})^2 + (\hbar\omega)^2}\right) </math></center>
Then:
<center><math>B = \frac{1}{\pi}h A_1</math></center>
<center><math>\Gamma = \frac{3}{\pi} h\tau^{-1} = 3.949269754 meV\cdot THz \cdot \tau^{-1}</math></center>
== Properties ==
Expand All @@ -55,7 +55,6 @@ Then the following equalities hold:
|inverse of the transition rate (ps if energy in meV; ns if energy in <math>\mu</math>eV)
|}
[[Category:Fit_functions]]
*WIKI*/

Expand All @@ -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<double>::epsilon(), true );
addConstraint( HeightConstraint );

BoundaryConstraint* RadiusConstraint = new BoundaryConstraint( this, "Radius", std::numeric_limits<double>::epsilon(), true );
addConstraint( RadiusConstraint );

declareAttribute( "Q", API::IFunction::Attribute(0.5) );
declareAttribute( "N", API::IFunction::Attribute(3) );

}

double ElasticDiffRotDiscreteCircle::HeightPrefactor() const{
Expand All @@ -108,15 +108,18 @@ 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]" );
declareParameter( "Decay", 1.0, "Inverse of transition rate, in nanoseconds if energy in micro-ev, or picoseconds if energy in mili-eV" );

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);
Expand All @@ -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();

Expand Down Expand Up @@ -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<ElasticDiffRotDiscreteCircle>( API::FunctionFactory::Instance().createFunction( "ElasticDiffRotDiscreteCircle" ) );
addFunction( m_elastic );
m_inelastic = boost::dynamic_pointer_cast<InelasticDiffRotDiscreteCircle>( 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();

}

Expand Down
Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down

0 comments on commit e0f10f1

Please sign in to comment.