//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Sample/Aggregate/Dilute3D.cpp
//! @brief     Implements class Dilute3D.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2026
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "Sample/Aggregate/Dilute3D.h"
#include "Base/Math/Functions.h"
#include "Base/Vector/WavevectorInfo.h"

Dilute3D::Dilute3D(double volume_density, const IParticle& particle)
    : Disordered3D(volume_density, particle)
{
}

Dilute3D* Dilute3D::clone() const
{
    auto* result = new Dilute3D(volumeNumberDensity(), *particle());
    Struct::instructClone(result);
    return result;
}

complex_t Dilute3D::structureCrossFactor(const WavevectorInfo& q_m, const WavevectorInfo& q_n) const
{
    // Dilute: no pair correlations, cross-factor equals self-position factor
    return selfPositionFactor(q_m, q_n);
}

complex_t Dilute3D::selfPositionFactor(const WavevectorInfo& q_m, const WavevectorInfo& q_n) const
{
    const complex_t delta_qz = q_m.getQ().z() - std::conj(q_n.getQ().z());
    ASSERT(zRangeLow() <= zRangeHigh());
    const double center = 0.5 * (zRangeLow() + zRangeHigh());
    const double half_width = 0.5 * (zRangeHigh() - zRangeLow());
    return std::exp(I * delta_qz * center) * Math::sinc(delta_qz * half_width);
}
