Julia S(q,w) Models

Similarly to the Python modules, a S(q,w) Julia module has to define the two functions "TakinInit" and "TakinSqw".

"TakinInit" is called after one or several parameters have changed (for example after each minimisation step in the convolution fitter). It can be used to check if e.g. pre-calculated tables, variables, etc. need to be recalculated.

The "TakinSqw" function receives four floating-point parameters h,k,l, and E and returns a single floating-point value S, the dynamical structure factor. The function is called for every Monte-Carlo point.

All global variables that are defined in an S(q,w) Julia module and that are prefixed with "g_" (for "global") are made available as settable parameters in the convolution dialog and as fit parameters for the convolution fitter.

The minimal interface to Takin is defined as follows (a full example can be found in the subdirectory "examples/sqw_py"):

function TakinInit()
	# reinitialise variables here
end

function TakinSqw(h::Float64, k::Float64, l::Float64, E::Float64)::Float64
	S = 0.
	# calculate S here
	return Float64(S)
end
	


A full example is given below (it can also be found in the subdirectory "examples/sqw_jl" of the source code distribution):

#
# Sample Julia S(q,w) module for ferromagnetic dispersions
# @author Tobias Weber 
# @license GPLv2
# @date dec-2016
#


# TODO: import constant
kB = 1.23


# example dispersion
function disp_ferro(q, D, offs)
	return D*q^2. + offs
end

# Gaussian peak
function gauss(x, x0, sig, amp)
	norm = (sqrt(2.*pi) * sig)
	return amp * exp(-0.5*((x-x0)/sig)^2.) / norm
end


# Bose factor
function bose(E, T)
	n = 1./(exp(abs(E)/(kB*T)) - 1.)
	if E >= 0.
		n += 1.
	end
	return n
end

# Bose factor which is cut off below Ecut
function bose_cutoff(E, T, Ecut=0.02)
	Ecut = abs(Ecut)

	b = 0.
	if abs(E) < Ecut
		b = bose(sign(E)*Ecut, T)
	else
		b = bose(E, T)
	end

	return b
end



# -----------------------------------------------------------------------------

#
# global variables which can be accessed / changed by Takin
#
g_G = vec([1., 1., 0.])		# Bragg peak
g_D = 50.			# magnon stiffness
g_offs = 0.			# energy gap
g_sig = 0.02			# linewidth
g_S0 = 10.			# intensity

g_inc_sig = 0.02		# incoherent width
g_inc_amp = 10.			# incoherent intensity

g_T = 100.			# temperature
g_bose_cut = 0.02		# Bose cutoff



# -----------------------------------------------------------------------------

#
# the init function is called after Takin has changed a global variable (optional)
#
function TakinInit()
	println("Calling TakinInit")
end


#
# dispersion E(Q) and weight factor (optional)
#
function TakinDisp(h::Float64, k::Float64, l::Float64)
	# momentum
	Q = vec([h,k,l])
	# reduced momentum
	q = vecnorm(Q - g_G)

	# energy
	E_peak = disp_ferro(q, g_D, g_offs)
	# weight
	w_peak = 1.
	return [[E_peak, -E_peak], [w_peak, w_peak]]
end


#
# called for every Monte-Carlo point
#
function TakinSqw(h::Float64, k::Float64, l::Float64, E::Float64)::Float64
	#println("Calling TakinSqw(", h, ", ", k, ", ", l, ", ", E, ") -> ", S)
	Es, ws = TakinDisp(h,k,l)

	S_p = gauss(E, Es[1], g_sig, g_S0*ws[1])
	S_m = gauss(E, Es[2], g_sig, g_S0*ws[2])
	incoh = gauss(E, 0., g_inc_sig, g_inc_amp)

	b = 1.
	#b = bose_cutoff(E, g_T, g_bose_cut)
	S = (S_p + S_m)*b + incoh
	return Float64(S)
end



# -----------------------------------------------------------------------------
# test
#
#println(TakinSqw(1., 1., 0., 0.))
#