From 6a40b9fc7e954fd7731a99f4e02b0e0305c138cb Mon Sep 17 00:00:00 2001
From: Walter Van Herck <w.van.herck@fz-juelich.de>
Date: Tue, 15 Jan 2019 15:21:37 +0100
Subject: [PATCH] Add usage of Debye-Waller factor in SSCA

---
 Core/Aggregate/IInterferenceFunction.h       |  2 +-
 Core/Multilayer/SSCApproximationStrategy.cpp |  8 ++--
 auto/Wrap/libBornAgainCore.py                |  5 +++
 auto/Wrap/libBornAgainCore_wrap.cpp          | 40 ++++++++++++++++++++
 4 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/Core/Aggregate/IInterferenceFunction.h b/Core/Aggregate/IInterferenceFunction.h
index 6281d6b4d42..4eb6d544da3 100644
--- a/Core/Aggregate/IInterferenceFunction.h
+++ b/Core/Aggregate/IInterferenceFunction.h
@@ -48,10 +48,10 @@ public:
     //! Indicates if this interference function can be used with a multilayer (DWBA mode)
     virtual bool supportsMultilayer() const { return true; }
 
-protected:
     //! Evaluates the Debye-Waller factor for a given wavevector transfer
     double DWfactor(kvector_t q) const;
 
+protected:
     //! Calculates the structure factor in the absence of extra inner structure
     double iff_no_inner(const kvector_t q, double outer_iff) const;
 
diff --git a/Core/Multilayer/SSCApproximationStrategy.cpp b/Core/Multilayer/SSCApproximationStrategy.cpp
index 87f775b50ef..6df6bb542e8 100644
--- a/Core/Multilayer/SSCApproximationStrategy.cpp
+++ b/Core/Multilayer/SSCApproximationStrategy.cpp
@@ -49,8 +49,9 @@ double SSCApproximationStrategy::scalarCalculation(const SimulationElement& sim_
                                                              m_formfactor_wrappers);
     complex_t p2kappa = m_helper.getCharacteristicSizeCoupling(qp, m_formfactor_wrappers);
     complex_t omega = m_helper.getCharacteristicDistribution(qp, mP_iff.get());
-    double interference_intensity = 2.0 * (mean_ff_norm * omega / (1.0 - p2kappa * omega)).real();
-    return diffuse_intensity + interference_intensity;
+    double iff = 2.0 * (mean_ff_norm * omega / (1.0 - p2kappa * omega)).real();
+    double dw_factor = mP_iff->DWfactor(sim_element.getMeanQ());
+    return diffuse_intensity + dw_factor * iff;
 }
 
 //! This is the polarized version
@@ -76,5 +77,6 @@ double SSCApproximationStrategy::polarizedCalculation(const SimulationElement& s
     Eigen::Matrix2cd diffuse_matrix2 = polarization_handler.getAnalyzerOperator() * diffuse_matrix;
     double interference_trace = std::abs(interference_matrix.trace());
     double diffuse_trace = std::abs(diffuse_matrix2.trace());
-    return diffuse_trace + interference_trace;
+    double dw_factor = mP_iff->DWfactor(sim_element.getMeanQ());
+    return diffuse_trace + dw_factor * interference_trace;
 }
diff --git a/auto/Wrap/libBornAgainCore.py b/auto/Wrap/libBornAgainCore.py
index 1a48c266bf6..1688d8da2d3 100644
--- a/auto/Wrap/libBornAgainCore.py
+++ b/auto/Wrap/libBornAgainCore.py
@@ -18713,6 +18713,11 @@ class IInterferenceFunction(ISample):
         """
         return _libBornAgainCore.IInterferenceFunction_supportsMultilayer(self)
 
+
+    def DWfactor(self, q):
+        """DWfactor(IInterferenceFunction self, kvector_t q) -> double"""
+        return _libBornAgainCore.IInterferenceFunction_DWfactor(self, q)
+
     def __disown__(self):
         self.this.disown()
         _libBornAgainCore.disown_IInterferenceFunction(self)
diff --git a/auto/Wrap/libBornAgainCore_wrap.cpp b/auto/Wrap/libBornAgainCore_wrap.cpp
index 22b3cda5d7a..c2869b109c0 100644
--- a/auto/Wrap/libBornAgainCore_wrap.cpp
+++ b/auto/Wrap/libBornAgainCore_wrap.cpp
@@ -85797,6 +85797,45 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_IInterferenceFunction_DWfactor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IInterferenceFunction *arg1 = (IInterferenceFunction *) 0 ;
+  kvector_t arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:IInterferenceFunction_DWfactor",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IInterferenceFunction, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IInterferenceFunction_DWfactor" "', argument " "1"" of type '" "IInterferenceFunction const *""'"); 
+  }
+  arg1 = reinterpret_cast< IInterferenceFunction * >(argp1);
+  {
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IInterferenceFunction_DWfactor" "', argument " "2"" of type '" "kvector_t""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IInterferenceFunction_DWfactor" "', argument " "2"" of type '" "kvector_t""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
+  }
+  result = (double)((IInterferenceFunction const *)arg1)->DWfactor(arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_disown_IInterferenceFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IInterferenceFunction *arg1 = (IInterferenceFunction *) 0 ;
@@ -127092,6 +127131,7 @@ static PyMethodDef SwigMethods[] = {
 		"Indicates if this interference function can be used with a multilayer (DWBA mode) \n"
 		"\n"
 		""},
+	 { (char *)"IInterferenceFunction_DWfactor", _wrap_IInterferenceFunction_DWfactor, METH_VARARGS, (char *)"IInterferenceFunction_DWfactor(IInterferenceFunction self, kvector_t q) -> double"},
 	 { (char *)"disown_IInterferenceFunction", _wrap_disown_IInterferenceFunction, METH_VARARGS, NULL},
 	 { (char *)"IInterferenceFunction_swigregister", IInterferenceFunction_swigregister, METH_VARARGS, NULL},
 	 { (char *)"delete_ILayout", _wrap_delete_ILayout, METH_VARARGS, (char *)"\n"
-- 
GitLab