diff --git a/Base/Vector/BasicVector3D.cpp b/Base/Vector/BasicVector3D.cpp deleted file mode 100644 index 28a445bdc27b419299a6893e7c7d16e9e3050957..0000000000000000000000000000000000000000 --- a/Base/Vector/BasicVector3D.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file Base/Vector/BasicVector3D.cpp -//! @brief Implements type-specific functions from template class BasicVector3D. -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "Base/Vector/BasicVector3D.h" -#include <stdexcept> - -using complex_t = std::complex<double>; - -// ----------------------------------------------------------------------------- -// Functions of this (with no further argument) -// ----------------------------------------------------------------------------- - -//! Returns complex conjugate vector -template <> BasicVector3D<double> BasicVector3D<double>::conj() const -{ - return *this; -} - -template <> BasicVector3D<complex_t> BasicVector3D<complex_t>::conj() const -{ - return {std::conj(x()), std::conj(y()), std::conj(z())}; -} - -//! Returns azimuth angle. -template <> double BasicVector3D<double>::phi() const -{ - return x() == 0.0 && y() == 0.0 ? 0.0 : std::atan2(-y(), x()); -} - -//! Returns polar angle. -template <> double BasicVector3D<double>::theta() const -{ - return x() == 0.0 && y() == 0.0 && z() == 0.0 ? 0.0 : std::atan2(magxy(), z()); -} - -//! Returns cosine of polar angle. -template <> double BasicVector3D<double>::cosTheta() const -{ - return mag() == 0 ? 1 : z() / mag(); -} - -//! Returns squared sine of polar angle. -template <> double BasicVector3D<double>::sin2Theta() const -{ - return mag2() == 0 ? 0 : magxy2() / mag2(); -} - -//! Returns this, trivially converted to complex type. -template <> BasicVector3D<complex_t> BasicVector3D<double>::complex() const -{ - return {x(), y(), z()}; -} - -//! Returns real parts. -template <> BasicVector3D<double> BasicVector3D<double>::real() const -{ - return *this; -} - -template <> BasicVector3D<double> BasicVector3D<complex_t>::real() const -{ - return {x().real(), y().real(), z().real()}; -} - -//! Returns unit vector in direction of this. Throws for null vector. -template <> BasicVector3D<double> BasicVector3D<double>::unit() const -{ - double len = mag(); - if (len == 0.0) - throw std::runtime_error("Cannot normalize zero vector"); - return {x() / len, y() / len, z() / len}; -} - -template <> BasicVector3D<complex_t> BasicVector3D<complex_t>::unit() const -{ - double len = mag(); - if (len == 0.0) - throw std::runtime_error("Cannot normalize zero vector"); - return {x() / len, y() / len, z() / len}; -} - -// ----------------------------------------------------------------------------- -// Combine two vectors -// ----------------------------------------------------------------------------- - -//! Returns angle with respect to another vector. -template <> double BasicVector3D<double>::angle(const BasicVector3D<double>& v) const -{ - double cosa = 0; - double ptot = mag() * v.mag(); - if (ptot > 0) { - cosa = dot(v) / ptot; - if (cosa > 1) - cosa = 1; - if (cosa < -1) - cosa = -1; - } - return std::acos(cosa); -} diff --git a/Base/Vector/BasicVector3D.h b/Base/Vector/BasicVector3D.h index e735b0234de42a5186a23a673fcf8a2df34385ec..ed1f738f51aca1baced9a3210694d64dfaedc091 100644 --- a/Base/Vector/BasicVector3D.h +++ b/Base/Vector/BasicVector3D.h @@ -286,4 +286,96 @@ inline auto BasicVector3D<T>::cross(const BasicVector3D<U>& v) const } #endif // USER_API +// ----------------------------------------------------------------------------- +// Functions of this (with no further argument) +// ----------------------------------------------------------------------------- + +//! Returns complex conjugate vector +template <> inline BasicVector3D<double> BasicVector3D<double>::conj() const +{ + return *this; +} + +template <> inline BasicVector3D<complex_t> BasicVector3D<complex_t>::conj() const +{ + return {std::conj(x()), std::conj(y()), std::conj(z())}; +} + +//! Returns azimuth angle. +template <> inline double BasicVector3D<double>::phi() const +{ + return x() == 0.0 && y() == 0.0 ? 0.0 : std::atan2(-y(), x()); +} + +//! Returns polar angle. +template <> inline double BasicVector3D<double>::theta() const +{ + return x() == 0.0 && y() == 0.0 && z() == 0.0 ? 0.0 : std::atan2(magxy(), z()); +} + +//! Returns cosine of polar angle. +template <> inline double BasicVector3D<double>::cosTheta() const +{ + return mag() == 0 ? 1 : z() / mag(); +} + +//! Returns squared sine of polar angle. +template <> inline double BasicVector3D<double>::sin2Theta() const +{ + return mag2() == 0 ? 0 : magxy2() / mag2(); +} + +//! Returns this, trivially converted to complex type. +template <> inline BasicVector3D<complex_t> BasicVector3D<double>::complex() const +{ + return {x(), y(), z()}; +} + +//! Returns real parts. +template <> inline BasicVector3D<double> BasicVector3D<double>::real() const +{ + return *this; +} + +template <> inline BasicVector3D<double> BasicVector3D<complex_t>::real() const +{ + return {x().real(), y().real(), z().real()}; +} + +//! Returns unit vector in direction of this. Throws for null vector. +template <> inline BasicVector3D<double> BasicVector3D<double>::unit() const +{ + double len = mag(); + if (len == 0.0) + throw std::runtime_error("Cannot normalize zero vector"); + return {x() / len, y() / len, z() / len}; +} + +template <> inline BasicVector3D<complex_t> BasicVector3D<complex_t>::unit() const +{ + double len = mag(); + if (len == 0.0) + throw std::runtime_error("Cannot normalize zero vector"); + return {x() / len, y() / len, z() / len}; +} + +// ----------------------------------------------------------------------------- +// Combine two vectors +// ----------------------------------------------------------------------------- + +//! Returns angle with respect to another vector. +template <> inline double BasicVector3D<double>::angle(const BasicVector3D<double>& v) const +{ + double cosa = 0; + double ptot = mag() * v.mag(); + if (ptot > 0) { + cosa = dot(v) / ptot; + if (cosa > 1) + cosa = 1; + if (cosa < -1) + cosa = -1; + } + return std::acos(cosa); +} + #endif // BORNAGAIN_BASE_VECTOR_BASICVECTOR3D_H