From 25e36fd3c9a08762ed58a1820c478b06d5cb3196 Mon Sep 17 00:00:00 2001
From: Celine Durniak <c.durniak@fz-juelich.de>
Date: Tue, 26 Nov 2013 12:49:40 +0100
Subject: [PATCH] New form factor of Tetrahedron

---
 Core/FormFactors/inc/FormFactorTetrahedron.h  |  18 ++-
 .../FormFactors/src/FormFactorTetrahedron.cpp | 148 +++++++++++++-----
 2 files changed, 122 insertions(+), 44 deletions(-)

diff --git a/Core/FormFactors/inc/FormFactorTetrahedron.h b/Core/FormFactors/inc/FormFactorTetrahedron.h
index 768007db82c..93acaffd1b3 100644
--- a/Core/FormFactors/inc/FormFactorTetrahedron.h
+++ b/Core/FormFactors/inc/FormFactorTetrahedron.h
@@ -19,19 +19,21 @@
 
 #include "IFormFactorBorn.h"
 #include "IStochasticParameter.h"
+//#include "MemberComplexFunctionIntegrator.h"
+
 
 //! Form factor of tetrahedron.
 
 class BA_CORE_API_ FormFactorTetrahedron : public IFormFactorBorn
 {
 public:
-    //! @brief tetrahedron constructor
-    //! @param height of tetrahedron
-    //! @param half_side half of tetrahedron's base
+    //! @brief Tetrahedron constructor
+    //! @param height of Tetrahedron
+    //! @param half_side: half of Tetrahedron's base
     //! @param angle in radians between base and facet
-    FormFactorTetrahedron(double height, double half_side, double alpha);
-
+    FormFactorTetrahedron(double half_side, double height, double alpha);
     ~FormFactorTetrahedron() {}
+
     virtual FormFactorTetrahedron *clone() const;
 
     virtual void accept(ISampleVisitor *visitor) const { visitor->visit(this); }
@@ -53,10 +55,16 @@ protected:
     virtual void init_parameters();
 
 private:
+
+    //complex_t Integrand(double Z, void* params) const;
+
     double m_height;
     double m_half_side;
     double m_alpha;
     double m_root3; // Cached value of square root of 3
+   // mutable cvector_t m_q;
+
+   // MemberComplexFunctionIntegrator<FormFactorTetrahedron> *m_integrator;
 };
 
 #endif // FORMFACTORTETRAHEDRON_H
diff --git a/Core/FormFactors/src/FormFactorTetrahedron.cpp b/Core/FormFactors/src/FormFactorTetrahedron.cpp
index d94b557de3c..a7e245e60e8 100644
--- a/Core/FormFactors/src/FormFactorTetrahedron.cpp
+++ b/Core/FormFactors/src/FormFactorTetrahedron.cpp
@@ -18,7 +18,7 @@
 #include "MathFunctions.h"
 
 FormFactorTetrahedron::FormFactorTetrahedron(
-    double height, double half_side, double alpha)
+   double half_side, double height, double alpha)
 {
     setName("FormFactorTetrahedron");
     m_height = height;
@@ -26,6 +26,11 @@ FormFactorTetrahedron::FormFactorTetrahedron(
     m_alpha = alpha;
     m_root3 = std::sqrt(3.0);
     init_parameters();
+
+  /*  MemberComplexFunctionIntegrator<FormFactorTetrahedron>::mem_function p_mf =
+       & FormFactorTetrahedron::Integrand;
+    m_integrator =
+        new MemberComplexFunctionIntegrator<FormFactorTetrahedron>(p_mf, this);*/
 }
 
 void FormFactorTetrahedron::init_parameters()
@@ -39,64 +44,129 @@ void FormFactorTetrahedron::init_parameters()
 FormFactorTetrahedron* FormFactorTetrahedron::clone() const
 {
     FormFactorTetrahedron *result =
-        new FormFactorTetrahedron(m_height, m_half_side, m_alpha);
+        new FormFactorTetrahedron(m_half_side, m_height, m_alpha);
     result->setName(getName());
     return result;
 }
 
+
+//! Integrand for complex formfactor.
+/*complex_t FormFactorTetrahedron::Integrand(double Z, void* params) const
+{
+    (void)params;  // to avoid unused-variable warning
+    double Rz = m_half_side -Z*m_root3/std::tan(m_alpha);
+    complex_t r3qyR = m_root3*m_q.y()*Rz;
+    complex_t qxR = m_q.x()*Rz;
+
+    return (std::exp(complex_t(0.0, 1.0)*r3qyR) -
+            std::cos(qxR)-complex_t(0.0, 1.0)*r3qyR*
+            MathFunctions::Sinc(qxR))
+            *std::exp(complex_t(0.0, 1.0)*(m_q.z()*Z-m_q.y()*Rz/m_root3));
+
+}*/
+
+//! Complex formfactor.
+
+/*complex_t FormFactorTetrahedron::evaluate_for_q(const cvector_t& q) const
+{   m_q = q;
+    double H = m_height;
+    double R = m_half_side;
+    double tga = std::tan(m_alpha);
+
+  if ( std::abs(m_q.mag()) < Numeric::double_epsilon) {
+      double sqrt3HdivRtga = m_root3*H/R/tga;
+       return tga/3.*R*R*R*(1. -
+          (1.-sqrt3HdivRtga)*(1.-sqrt3HdivRtga)*(1.-sqrt3HdivRtga));
+    }
+    else {
+    complex_t integral = m_integrator->integrate(0., H);
+    return    2.0*m_root3/(q.x()*q.x()-3.0*q.y()*q.y())*integral;
+    }
+}*/
+
+
 complex_t FormFactorTetrahedron::evaluate_for_q(const cvector_t& q) const
 {
     double H = m_height;
     double R = m_half_side;
     double tga = std::tan(m_alpha);
+    double L = 2.*tga*R/m_root3-H;
 
     complex_t qx = q.x();
     complex_t qy = q.y();
     complex_t qz = q.z();
 
+    complex_t q1, q2, q3;
+    q1=(1./2.)*((m_root3*qx - qy)/tga - qz);
+    q2=(1./2.)*((m_root3*qx + qy)/tga + qz);
+    q3 = (qy/tga - qz/2.);
+
     complex_t F;
     const complex_t im(0,1);
 
-    if (std::abs(qx)==0.0 && std::abs(qy)==0.0) {
-        complex_t qzH_half = qz*H/2.0;
-        //WRONG
-        F = m_root3*R*R*H*std::exp(im*qzH_half)*MathFunctions::Sinc(qzH_half);
+    if (std::abs(qx) <= Numeric::double_epsilon) {
+
+        if (std::abs(qy) <= Numeric::double_epsilon) {
+
+            if (std::abs(qz) <= Numeric::double_epsilon) {
+                // qx=qy=qz=0
+                double sqrt3HdivRtga = m_root3*H/R/tga;
+                F = tga/3.*R*R*R*(1. -
+                   (1.-sqrt3HdivRtga)*(1.-sqrt3HdivRtga)*(1.-sqrt3HdivRtga));
+            }
+            else {
+                //qx=qy=0 qz!=0
+                complex_t qzH_half = qz*H/2.0;
+                F = m_root3*H*std::exp(im*qzH_half)*(
+                            MathFunctions::Sinc(qzH_half)*
+                            (R*R-im*2.*m_root3*R/(qz*tga)-6./(qz*qz*tga*tga))
+                            + m_root3*std::exp(im*qzH_half)/(qz*tga)*(
+                            2.*im*R - im*m_root3*H/tga + 2.*m_root3/(qz*tga)));
+            }
+        }
+        else {
+            // qx=0 qy!=0
+            F = 2.*H/(m_root3*qy*qy)*
+                    std::exp(im*R*qz*tga/m_root3 + im*q3*L)*(
+                    std::exp(-im*q2*L)*MathFunctions::Sinc(q2*H)
+                  - std::exp(im*q3*L)*MathFunctions::Sinc(q3*H)) ;
+        }
     }
     else {
-        if (std::abs(qx*qx-3.0*qy*qy)==0.0) {
-            complex_t qa = 2.*qy/tga + qz/2.;
-            complex_t qb = - qy/tga + qz/2.;
-            F = H/2.*m_root3*std::exp(im*2.*qy*R/m_root3)*(
-                        - std::exp(im*qa*H-im*2.*m_root3*qy*R)*MathFunctions::Sinc(qa*H)
-                        + std::exp(im*qb*H)*MathFunctions::Sinc(qb*H)*
-                        ( 1.- 3.*qy/(tga*qb) - im*2.*m_root3*qy*R )
-                        + 3.*qy/(qb*tga)*std::exp(im*2.*qb*H)
-                        )/( qx*qx ) ;
-        } else {
-
-            complex_t q1, q2, q3;
-            double L;
-            L = 2.*tga*R/m_root3-H;
-            q3 = (qy/tga - qz/2.);
-
-            if (std::abs(qx)==0.0) {
-
-               F = - 2.*H*MathFunctions::Sinc(q3*H)*
-                       std::exp(im*(q3*L+qz*R*tga/m_root3))/((m_root3*qy*qy));
-
-            } else {
-
-            q1=(1./2.)*((m_root3*qx-qy)/tga - qz);
-            q2=(1./2.)*((m_root3*qx+qy)/tga + qz);
-
-            F = -(1. + m_root3*qy/qx)*MathFunctions::Sinc(q1*H)*std::exp(im*q1*L)
-                -(1. - m_root3*qy/qx)*MathFunctions::Sinc(q2*H)*std::exp(-im*q2*L)
-                + 2.*MathFunctions::Sinc(q3*H)*std::exp(im*q3*L);
-
-            F = F*H*std::exp(im*qz*R*tga/m_root3)*m_root3/((qx*qx-3.*qy*qy));}
+        // qx!=0
+         if (std::abs(qx*qx-3.0*qy*qy)==0.0) {
+            // qx**2= 3qy**2
+             complex_t qa = 2.0*qy/tga + qz/2.0;
+             F = H*m_root3*std::exp(im*2.0*qy*R/m_root3)*(
+                 MathFunctions::Sinc(q3*H)
+                   *(1.0 +m_root3*qy*(-im*2.0*R + m_root3/(q3*tga)))
+               - 3.0*qy*std::exp(-im*2.0*q3*H)/(q3*tga)
+               - std::exp(im*qa*H-im*2.0*m_root3*qy*R)*MathFunctions::Sinc(qa*H)
+                 )/(2.0*qx*qx);
         }
-    }
-
+        else {
+        //Formula Isgisaxs
+         /*    complex_t qc1      = 2./m_root3*qx;
+             complex_t qc2      = qx/m_root3 + qy;
+
+             complex_t qq1  = 2.*qc1 -  qc2 - tga*qz;
+             complex_t qq2  = qc1 +  qc2 + tga*qz;
+             complex_t qq3  =-qc1 +2.*qc2 - tga*qz;
+             complex_t Rt  =  R/m_root3;
+             complex_t Ht  =  H/(2.*tga);
+
+             F = -qc2*MathFunctions::Sinc(qq1*Ht)*std::exp(im*(Rt-Ht)*qq1) +
+        (qc2-qc1)*MathFunctions::Sinc(qq2*Ht)*std::exp(-im*(Rt-Ht)*qq2) +
+                qc1*MathFunctions::Sinc(qq3*Ht)*std::exp(im*(Rt-Ht)*qq3);
+             F = F*2.*H/m_root3/qc1/qc2/(qc1-qc2)*std::exp(im*Rt*tga*qz);*/
+
+             F =-(1.+m_root3*qy/qx)*MathFunctions::Sinc(q1*H)*std::exp(im*q1*L)
+                -(1.-m_root3*qy/qx)*MathFunctions::Sinc(q2*H)*std::exp(-im*q2*L)
+                +2.*MathFunctions::Sinc(q3*H)*std::exp(im*q3*L);
+
+             F = H*m_root3*std::exp(im*qz*R*tga/m_root3)/(qx*qx-3.*qy*qy)*F;
+}
+}
     return F;
 }
 
-- 
GitLab