Native S(q,w) Models

Takin can load S(q,w) plugins via native shared libraries (SO or DLL files). C++ examples to build upon are given in the subdirectory "examples/sqw_module".

The minimal example using the native interface to Takin is given in the following.
Header file "sqwmod.h":

/**
 * S(q,w) module example
 * @author Tobias Weber 
 * @date 2016
 * @license GPLv2
 */

#ifndef __MCONV_SQW_MOD_H__
#define __MCONV_SQW_MOD_H__

#include "tools/monteconvo/sqwbase.h"
#include "tlibs/math/linalg.h"

class SqwMod : public SqwBase
{
	public:
		using SqwBase::t_var;
		using t_real = t_real_reso;
		using t_vec = tl::ublas::vector;

	protected:
		// temperature for Bose factor
		t_real m_dT = t_real(100);

		// peak width for creation and annihilation
		t_real m_dSigma[2] = { t_real(0.05), t_real(0.05) };
		bool m_bUseSingleSigma = 0;

		// S(q,E) scaling factor
		t_real m_dS0 = t_real(1.);

		// incoherent amplitude and width
		t_real m_dIncAmp = t_real(0.);
		t_real m_dIncSigma = t_real(0.05);

		// Brillouin zone centre
		t_vec m_vecG;

	public:
		SqwMod();
		SqwMod(const std::string& strCfgFile);
		virtual ~SqwMod();

		virtual std::tuple, std::vector>
			disp(t_real dh, t_real dk, t_real dl) const override;
		virtual t_real operator()(t_real dh, t_real dk, t_real dl, t_real dE) const override;

		virtual std::vector GetVars() const override;
		virtual void SetVars(const std::vector&) override;
		virtual bool SetVarIfAvail(const std::string& strKey, const std::string& strNewVal) override;

		virtual SqwBase* shallow_copy() const override;
};
#endif
	

C++ implementation file "sqwmod.cpp":
/**
 * S(q,w) module example
 * @author Tobias Weber 
 * @date 2016
 * @license GPLv2
 *
 * compile with:
 * g++ -std=c++11 -I. -shared -fPIC -o plugins/sqwmod.so sqwmod.cpp tools/monteconvo/sqwbase.cpp tlibs/log/log.cpp
 */

#include "sqwmod.h"

#include "libs/version.h"
#include "tlibs/string/string.h"
#include "tlibs/math/math.h"
#include "tlibs/phys/neutrons.h"

#include 


using t_real = typename SqwMod::t_real;


// ----------------------------------------------------------------------------
// constructors

SqwMod::SqwMod() : m_vecG(tl::make_vec({1,0,0}))
{
	SqwBase::m_bOk = 1;
}

SqwMod::SqwMod(const std::string& strCfgFile) : SqwMod()
{
	tl::log_info("Config file: \"", strCfgFile, "\".");
	SqwBase::m_bOk = 1;
}

SqwMod::~SqwMod()
{
}


// ----------------------------------------------------------------------------
// dispersion, spectral weight and structure factor

std::tuple, std::vector>
	SqwMod::disp(t_real dh, t_real dk, t_real dl) const
{
	t_real dEp = 0;		// energy (boson creation)
	t_real dwp = 1;		// spectral weight (boson creation)
	t_real dEm = -dEp;	// energy (boson annihilation)
	t_real dwm = dwp;	// spectral weight (boson annihilation)

	// TODO: calculate dispersion relation

	return std::make_tuple(std::vector({dEp, dEm}),
		std::vector({dwp, dwm}));
}

t_real SqwMod::operator()(t_real dh, t_real dk, t_real dl, t_real dE) const
{
	t_real dcut = t_real(0.02);

	std::vector vecE, vecW;
	std::tie(vecE, vecW) = disp(dh, dk, dl);

	t_real dInc=0, dS_p=0, dS_m=0;
	if(!tl::float_equal(m_dIncAmp, t_real(0)))
		dInc = tl::gauss_model(dE, t_real(0), m_dIncSigma, m_dIncAmp, t_real(0));

	t_real dS = 0;
	for(std::size_t iE=0; iE SqwMod::GetVars() const
{
	std::vector vecVars;

	vecVars.push_back(SqwBase::t_var{"T", "real", tl::var_to_str(m_dT)});
	vecVars.push_back(SqwBase::t_var{"sigma_create", "real", tl::var_to_str(m_dSigma[0])});
	vecVars.push_back(SqwBase::t_var{"sigma_annihilate", "real", tl::var_to_str(m_dSigma[1])});
	vecVars.push_back(SqwBase::t_var{"single_sigma", "bool", tl::var_to_str(m_bUseSingleSigma)});
	vecVars.push_back(SqwBase::t_var{"inc_amp", "real", tl::var_to_str(m_dIncAmp)});
	vecVars.push_back(SqwBase::t_var{"inc_sigma", "real", tl::var_to_str(m_dIncSigma)});
	vecVars.push_back(SqwBase::t_var{"S0", "real", tl::var_to_str(m_dS0)});
	vecVars.push_back(SqwBase::t_var{"G", "vector", vec_to_str(m_vecG)});

	return vecVars;
}

void SqwMod::SetVars(const std::vector& vecVars)
{
	if(!vecVars.size()) return;

	for(const SqwBase::t_var& var : vecVars)
	{
		const std::string& strVar = std::get<0>(var);
		const std::string& strVal = std::get<2>(var);

		if(strVar == "T") m_dT = tl::str_to_var(strVal);
		else if(strVar == "sigma_create") m_dSigma[0] = tl::str_to_var(strVal);
		else if(strVar == "sigma_annihilate") m_dSigma[1] = tl::str_to_var(strVal);
		else if(strVar == "single_sigma") m_bUseSingleSigma = tl::str_to_var(strVal);
		else if(strVar == "inc_amp") m_dIncAmp = tl::str_to_var(strVal);
		else if(strVar == "inc_sigma") m_dIncSigma = tl::str_to_var(strVal);
		else if(strVar == "S0") m_dS0 = tl::str_to_var(strVal);
		else if(strVar == "G") m_vecG = str_to_vec(strVal);
	}
}

bool SqwMod::SetVarIfAvail(const std::string& strKey, const std::string& strNewVal)
{
	return SqwBase::SetVarIfAvail(strKey, strNewVal);
}


// ----------------------------------------------------------------------------
// copy

SqwBase* SqwMod::shallow_copy() const
{
	SqwMod *pMod = new SqwMod();

	pMod->m_dT = this->m_dT;
	pMod->m_dSigma[0] = this->m_dSigma[0];
	pMod->m_dSigma[1] = this->m_dSigma[1];
	pMod->m_bUseSingleSigma = this->m_bUseSingleSigma;
	pMod->m_dIncAmp = this->m_dIncAmp;
	pMod->m_dIncSigma = this->m_dIncSigma;
	pMod->m_vecG = this->m_vecG;
	pMod->m_dS0 = this->m_dS0;

	return pMod;
}



// ----------------------------------------------------------------------------
// SO interface

static const char* pcModIdent = "tstmod";
static const char* pcModName = "Test Module";

std::tuple sqw_info()
{
	tl::log_info("In ", __func__, ".");

	return std::make_tuple(TAKIN_VER, pcModIdent, pcModName);
}

std::shared_ptr sqw_construct(const std::string& strCfgFile)
{
	tl::log_info("In ", __func__, ".");

	return std::make_shared(strCfgFile);
}


// exports from so file
BOOST_DLL_ALIAS(sqw_info, takin_sqw_info);
BOOST_DLL_ALIAS(sqw_construct, takin_sqw);