diff --git a/qpms/vswf.c b/qpms/vswf.c index e526ce8..2bc6660 100644 --- a/qpms/vswf.c +++ b/qpms/vswf.c @@ -308,7 +308,7 @@ qpms_errno_t qpms_vswf_fill_alternative(csphvec_t *const longtarget, csphvec_t * qpms_y_t nelem = qpms_lMax2nelem(lMax); csphvec_t *a; QPMS_CRASHING_MALLOC(a, 3*nelem*sizeof(csphvec_t)) - csphvec_t * const a1 = a, * const a2 = a1 + nelem, * const a3 = a2 + 2 * nelem; + csphvec_t * const a1 = a, * const a2 = a1 + nelem, * const a3 = a1 + 2 * nelem; QPMS_ENSURE_SUCCESS(qpms_vecspharm_fill(a1, a2, a3, lMax, kr, norm)); const csphvec_t *p1 = a1; const csphvec_t *p2 = a2; diff --git a/tests/catch/CMakeLists.txt b/tests/catch/CMakeLists.txt index 287c600..6a82bca 100644 --- a/tests/catch/CMakeLists.txt +++ b/tests/catch/CMakeLists.txt @@ -1,5 +1,7 @@ find_package(Catch2 REQUIRED) -add_executable(catchtest all_includes.C) -target_link_libraries(catchtest PRIVATE Catch2::Catch2WithMain qpms) +add_executable(catchtest all_includes.C t_vswf.C catch_aux.C) +# TODO ensure that the tests are linked against the "working tree" version of qpms, +# not the installed one +target_link_libraries(catchtest PRIVATE Catch2::Catch2WithMain qpms lapacke) diff --git a/tests/catch/t_vswf.C b/tests/catch/t_vswf.C new file mode 100644 index 0000000..118501e --- /dev/null +++ b/tests/catch/t_vswf.C @@ -0,0 +1,44 @@ +#include +#include +#include +#include "catch_aux.h" +using namespace qpmstest; + +constexpr qpms_l_t lMax = 6; + +static std::vector vswfvals_dvector(double r, double theta, double phi, + qpms_l_t lMax, qpms_bessel_t btyp, qpms_normalisation_t norm) +{ + std::vector vals(2 /*el and mg for now */ * (lMax * (lMax+2)) + * 3 /* 3D vector components */ * 2 /*for real and imag*/); + qpms_vswf_fill( + nullptr, (csphvec_t *) &(vals[0]), (csphvec_t *) &(vals[(lMax*(lMax+2)) * 3 * 2]), + lMax, sph_t{r, theta, phi}, + btyp, norm); + return vals; +} + +static std::vector vswfvals_dvector_alternative(double r, double theta, double phi, + qpms_l_t lMax, qpms_bessel_t btyp, qpms_normalisation_t norm) +{ + std::vector vals(2 /*el and mg for now */ * (lMax * (lMax+2)) + * 3 /* 3D vector components */ * 2 /*for real and imag*/); + qpms_vswf_fill_alternative( + nullptr, (csphvec_t *) &(vals[0]), (csphvec_t *) &(vals[(lMax*(lMax+2)) * 3 * 2]), + lMax, sph_t{r, theta, phi}, + btyp, norm); + return vals; +} + +TEST_CASE("VSWF alternative implementation") { + using Catch::Matchers::Approx; + auto norms = GENERATE(QPMS_NORMALISATION_DEFAULT, QPMS_NORMALISATION_NORM_POWER, + QPMS_NORMALISATION_NORM_SPHARM, QPMS_NORMALISATION_CONVENTION_SCUFF); + auto thetas = GENERATE(0., M_PI_2, M_PI_2/2, M_PI, 3*M_PI_2, 0.1, -0.2, 4., 12.666); + auto phis = GENERATE(0., M_PI_2, M_PI_2/2, M_PI, 3*M_PI_2, 0.1, -0.2, 4., 12.666); + auto rs_positive = GENERATE(0.0001, 0.001, 0.01, 0.1, 1., 10., 100.); + CHECK_THAT( + vswfvals_dvector(rs_positive, thetas, phis, lMax, QPMS_HANKEL_PLUS, norms), + Approx(vswfvals_dvector_alternative(rs_positive, thetas, phis, lMax, QPMS_HANKEL_PLUS, norms)) + ) ; +}