uvswf evaluation with complex kr; ss field ewald done, untested
Former-commit-id: 63048ddf2a9260742510a4fa246a59b8360381ce
This commit is contained in:
parent
a3f5f98736
commit
37b864effc
|
@ -66,7 +66,7 @@ qpms_dbgmsg_flags qpms_dbgmsg_enable(qpms_dbgmsg_flags types);
|
||||||
|
|
||||||
#define QPMS_ENSURE(x, msg, ...) {if(!(x)) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,msg, ##__VA_ARGS__); }
|
#define QPMS_ENSURE(x, msg, ...) {if(!(x)) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,msg, ##__VA_ARGS__); }
|
||||||
|
|
||||||
#define QPMS_ASSERT(x) {if(!(x)) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__, "Unexpected error. This is most certainly a bug.")
|
#define QPMS_ASSERT(x) {if(!(x)) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__, "Unexpected error. This is most certainly a bug.");}
|
||||||
|
|
||||||
#define QPMS_NOT_IMPLEMENTED(msg, ...) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__, \
|
#define QPMS_NOT_IMPLEMENTED(msg, ...) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__, \
|
||||||
"Not implemented:" msg, ##__VA_ARGS__)
|
"Not implemented:" msg, ##__VA_ARGS__)
|
||||||
|
|
|
@ -1461,7 +1461,6 @@ complex double *qpms_scatsys_build_modeproblem_matrix_irrep_packed_parallelR(
|
||||||
return target_packed;
|
return target_packed;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 // must allow for complex kr in qpms_eval_uvswf
|
|
||||||
ccart3_t qpms_scatsys_eval_E(const qpms_scatsys_t *ss,
|
ccart3_t qpms_scatsys_eval_E(const qpms_scatsys_t *ss,
|
||||||
const complex double *cvf, const cart3_t where,
|
const complex double *cvf, const cart3_t where,
|
||||||
const complex double k) {
|
const complex double k) {
|
||||||
|
@ -1485,7 +1484,6 @@ ccart3_t qpms_scatsys_eval_E(const qpms_scatsys_t *ss,
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
ccart3_t qpms_scatsys_eval_E_irrep(const qpms_scatsys_t *ss,
|
ccart3_t qpms_scatsys_eval_E_irrep(const qpms_scatsys_t *ss,
|
||||||
|
|
46
qpms/vswf.c
46
qpms/vswf.c
|
@ -7,6 +7,7 @@
|
||||||
#include "qpms_specfunc.h"
|
#include "qpms_specfunc.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "qpms_error.h"
|
||||||
|
|
||||||
|
|
||||||
qpms_vswf_set_spec_t *qpms_vswf_set_spec_init() {
|
qpms_vswf_set_spec_t *qpms_vswf_set_spec_init() {
|
||||||
|
@ -150,18 +151,19 @@ void qpms_vswfset_sph_pfree(qpms_vswfset_sph_t *w) {
|
||||||
free(w);
|
free(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
csphvec_t qpms_vswf_L00(sph_t kdrj, qpms_bessel_t btyp,
|
csphvec_t qpms_vswf_L00(csph_t kr, qpms_bessel_t btyp,
|
||||||
qpms_normalisation_t norm) {
|
qpms_normalisation_t norm) {
|
||||||
QPMS_UNTESTED;
|
QPMS_UNTESTED;
|
||||||
// CHECKME Is it OK to ignore norm?? (Is L_0^0 the same for all conventions?)
|
// CHECKME Is it OK to ignore norm?? (Is L_0^0 the same for all conventions?)
|
||||||
complex double bessel0;
|
complex double bessel0;
|
||||||
QPMS_ENSURE_SUCCESS(qpms_sph_bessel_fill(btyp, 0, kr.r, &bessel0));
|
QPMS_ENSURE_SUCCESS(qpms_sph_bessel_fill(btyp, 0, kr.r, &bessel0));
|
||||||
return {0.25 * M_2_SQRTPI * bessel0, 0, 0};
|
csphvec_t result = {0.25 * M_2_SQRTPI * bessel0, 0, 0};
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
qpms_errno_t qpms_vswf_fill(csphvec_t *const longtarget,
|
qpms_errno_t qpms_vswf_fill_csph(csphvec_t *const longtarget,
|
||||||
csphvec_t * const mgtarget, csphvec_t * const eltarget, qpms_l_t lMax,
|
csphvec_t * const mgtarget, csphvec_t * const eltarget, qpms_l_t lMax,
|
||||||
sph_t kr, qpms_bessel_t btyp, qpms_normalisation_t norm) {
|
csph_t kr, qpms_bessel_t btyp, qpms_normalisation_t norm) {
|
||||||
assert(lMax >= 1);
|
assert(lMax >= 1);
|
||||||
complex double *bessel = malloc((lMax+1)*sizeof(complex double));
|
complex double *bessel = malloc((lMax+1)*sizeof(complex double));
|
||||||
if(qpms_sph_bessel_fill(btyp, lMax, kr.r, bessel)) abort();
|
if(qpms_sph_bessel_fill(btyp, lMax, kr.r, bessel)) abort();
|
||||||
|
@ -214,6 +216,14 @@ qpms_errno_t qpms_vswf_fill(csphvec_t *const longtarget,
|
||||||
return QPMS_SUCCESS;
|
return QPMS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qpms_errno_t qpms_vswf_fill(csphvec_t *const longtarget,
|
||||||
|
csphvec_t * const mgtarget, csphvec_t * const eltarget, qpms_l_t lMax,
|
||||||
|
sph_t kr, qpms_bessel_t btyp, qpms_normalisation_t norm) {
|
||||||
|
csph_t krc = {kr.r, kr.theta, kr.phi};
|
||||||
|
return qpms_vswf_fill_csph(longtarget, mgtarget, eltarget, lMax,
|
||||||
|
krc, btyp, norm);
|
||||||
|
}
|
||||||
|
|
||||||
// consistency check: this should give the same results as the above function (up to rounding errors)
|
// consistency check: this should give the same results as the above function (up to rounding errors)
|
||||||
qpms_errno_t qpms_vswf_fill_alternative(csphvec_t *const longtarget, csphvec_t * const mgtarget, csphvec_t * const eltarget,
|
qpms_errno_t qpms_vswf_fill_alternative(csphvec_t *const longtarget, csphvec_t * const mgtarget, csphvec_t * const eltarget,
|
||||||
qpms_l_t lMax, sph_t kr,
|
qpms_l_t lMax, sph_t kr,
|
||||||
|
@ -385,7 +395,7 @@ qpms_errno_t qpms_planewave2vswf_fill_cart(cart3_t wavedir_cart /*allow complex
|
||||||
longcoeff, mgcoeff, elcoeff, lMax, norm);
|
longcoeff, mgcoeff, elcoeff, lMax, norm);
|
||||||
}
|
}
|
||||||
|
|
||||||
csphvec_t qpms_eval_vswf(sph_t kr,
|
csphvec_t qpms_eval_vswf_csph(csph_t kr,
|
||||||
complex double * const lc, complex double *const mc, complex double *const ec,
|
complex double * const lc, complex double *const mc, complex double *const ec,
|
||||||
qpms_l_t lMax, qpms_bessel_t btyp, qpms_normalisation_t norm)
|
qpms_l_t lMax, qpms_bessel_t btyp, qpms_normalisation_t norm)
|
||||||
{
|
{
|
||||||
|
@ -398,7 +408,7 @@ csphvec_t qpms_eval_vswf(sph_t kr,
|
||||||
if(lc) lset = malloc(nelem * sizeof(csphvec_t));
|
if(lc) lset = malloc(nelem * sizeof(csphvec_t));
|
||||||
if(mc) mset = malloc(nelem * sizeof(csphvec_t));
|
if(mc) mset = malloc(nelem * sizeof(csphvec_t));
|
||||||
if(ec) eset = malloc(nelem * sizeof(csphvec_t));
|
if(ec) eset = malloc(nelem * sizeof(csphvec_t));
|
||||||
qpms_vswf_fill(lset, mset, eset, lMax, kr, btyp, norm);
|
qpms_vswf_fill_csph(lset, mset, eset, lMax, kr, btyp, norm);
|
||||||
if(lc) for(qpms_y_t y = 0; y < nelem; ++y)
|
if(lc) for(qpms_y_t y = 0; y < nelem; ++y)
|
||||||
csphvec_kahanadd(&lsum, &lcomp, csphvec_scale(lc[y], lset[y]));
|
csphvec_kahanadd(&lsum, &lcomp, csphvec_scale(lc[y], lset[y]));
|
||||||
if(mc) for(qpms_y_t y = 0; y < nelem; ++y)
|
if(mc) for(qpms_y_t y = 0; y < nelem; ++y)
|
||||||
|
@ -414,18 +424,24 @@ csphvec_t qpms_eval_vswf(sph_t kr,
|
||||||
return esum;
|
return esum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
csphvec_t qpms_eval_vswf(sph_t kr,
|
||||||
|
complex double * const lc, complex double *const mc, complex double *const ec,
|
||||||
|
qpms_l_t lMax, qpms_bessel_t btyp, qpms_normalisation_t norm) {
|
||||||
|
csph_t krc = {kr.r, kr.theta, kr.phi};
|
||||||
|
return qpms_eval_vswf_csph(krc, lc, mc, ec, lMax, btyp, norm);
|
||||||
|
}
|
||||||
|
|
||||||
csphvec_t qpms_eval_uvswf(const qpms_vswf_set_spec_t *setspec,
|
csphvec_t qpms_eval_uvswf(const qpms_vswf_set_spec_t *bspec,
|
||||||
const complex double *coeffs, const sph_t kr,
|
const complex double *coeffs, const csph_t kr,
|
||||||
const qpms_bessel_t btyp) {
|
const qpms_bessel_t btyp) {
|
||||||
QPMS_UNTESTED;
|
QPMS_UNTESTED;
|
||||||
const qpms_l_t lMax = b->lMax;
|
const qpms_l_t lMax = bspec->lMax;
|
||||||
complex double *cM = NULL, *cN = NULL, *cL = NULL, cL00 = 0;
|
complex double *cM = NULL, *cN = NULL, *cL = NULL, cL00 = 0;
|
||||||
if (b->lMax_L > 0)
|
if (bspec->lMax_L > 0)
|
||||||
QPMS_CRASHING_CALLOC(cL, lMax, sizeof(complex double));
|
QPMS_CRASHING_CALLOC(cL, lMax, sizeof(complex double));
|
||||||
if (b->lMax_M > 0)
|
if (bspec->lMax_M > 0)
|
||||||
QPMS_CRASHING_CALLOC(cM, lMax, sizeof(complex double));
|
QPMS_CRASHING_CALLOC(cM, lMax, sizeof(complex double));
|
||||||
if (b->lMax_N > 0)
|
if (bspec->lMax_N > 0)
|
||||||
QPMS_CRASHING_CALLOC(cN, lMax, sizeof(complex double));
|
QPMS_CRASHING_CALLOC(cN, lMax, sizeof(complex double));
|
||||||
for (size_t i = 0; i < bspec->n; ++i) {
|
for (size_t i = 0; i < bspec->n; ++i) {
|
||||||
if (bspec->ilist[i] == 0) // L00, needs special care
|
if (bspec->ilist[i] == 0) // L00, needs special care
|
||||||
|
@ -452,10 +468,10 @@ csphvec_t qpms_eval_uvswf(const qpms_vswf_set_spec_t *setspec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
csphvec_t result = qpms_eval_vswf(kr, cL, cM, cN, lMax, btyp, norm);
|
csphvec_t result = qpms_eval_vswf_csph(kr, cL, cM, cN, lMax, btyp, bspec->norm);
|
||||||
|
free(cM); free(cN); free(cL);
|
||||||
if(cL00)
|
if(cL00)
|
||||||
result = csphvec_add(result,
|
result = csphvec_add(result,
|
||||||
scphvec_scale(cL00, qpms_vswf_L00(kr, btyp, norm)));
|
csphvec_scale(cL00, qpms_vswf_L00(kr, btyp, bspec->norm)));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
33
qpms/vswf.h
33
qpms/vswf.h
|
@ -42,20 +42,22 @@ static inline ssize_t qpms_vswf_set_spec_find_uvswfi(const qpms_vswf_set_spec_t
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NOT IMPLEMENTED Evaluates a set of VSWF basis functions at a given point.
|
/// Evaluates a set of VSWF basis functions at a given point.
|
||||||
/** The list of basis wave indices is specified in \a setspec;
|
/** The list of basis wave indices is specified in \a setspec;
|
||||||
* \a setspec->norm must be set as well.
|
* \a setspec->norm must be set as well.
|
||||||
*/
|
*/
|
||||||
qpms_errno_t qpms_uvswf_fill(
|
qpms_errno_t qpms_uvswf_fill(
|
||||||
csphvec_t *const target,
|
csphvec_t *const target, ///< Target array of size at least setspec->n.
|
||||||
const qpms_vswf_set_spec_t *setspec,
|
const qpms_vswf_set_spec_t *setspec,
|
||||||
sph_t evaluation_point, qpms_bessel_t btyp);
|
csph_t kr, ///< Evaluation point.
|
||||||
|
qpms_bessel_t btyp);
|
||||||
|
|
||||||
/// Evaluates field specified by SVWF coefficients at a given point.
|
/// Evaluates field specified by SVWF coefficients at a given point.
|
||||||
/** SVWF coefficients in \a coeffs must be ordered according to \a setspec->ilist.
|
/** SVWF coefficients in \a coeffs must be ordered according to \a setspec->ilist.
|
||||||
*/
|
*/
|
||||||
csphvec_t qpms_eval_uvswf(const qpms_vswf_set_spec_t *setspec,
|
csphvec_t qpms_eval_uvswf(const qpms_vswf_set_spec_t *setspec,
|
||||||
const complex double *coeffs, sph_t evaluation_point,
|
const complex double *coeffs, ///< SVWF coefficient vector of size setspec->n.
|
||||||
|
csph_t kr, ///< Evaluation point.
|
||||||
qpms_bessel_t btyp);
|
qpms_bessel_t btyp);
|
||||||
|
|
||||||
/// Electric wave N.
|
/// Electric wave N.
|
||||||
|
@ -86,7 +88,7 @@ qpms_errno_t qpms_legendre_deriv_y_fill(double *where, double *where_deriv, doub
|
||||||
|
|
||||||
/// Evaluate the zeroth-degree longitudinal VSWF \f$ \mathbf{L}_0^0 \f$.
|
/// Evaluate the zeroth-degree longitudinal VSWF \f$ \mathbf{L}_0^0 \f$.
|
||||||
csphvec_t qpms_vswf_L00(
|
csphvec_t qpms_vswf_L00(
|
||||||
sph_t kdrj, //< VSWF evaluation point.
|
csph_t kdrj, //< VSWF evaluation point.
|
||||||
qpms_bessel_t btyp,
|
qpms_bessel_t btyp,
|
||||||
qpms_normalisation_t norm);
|
qpms_normalisation_t norm);
|
||||||
|
|
||||||
|
@ -106,10 +108,28 @@ qpms_errno_t qpms_vswf_fill(
|
||||||
qpms_l_t lMax, //< Maximum multipole degree to be calculated.
|
qpms_l_t lMax, //< Maximum multipole degree to be calculated.
|
||||||
sph_t kdrj, //< VSWF evaluation point.
|
sph_t kdrj, //< VSWF evaluation point.
|
||||||
qpms_bessel_t btyp, qpms_normalisation_t norm);
|
qpms_bessel_t btyp, qpms_normalisation_t norm);
|
||||||
|
|
||||||
// Should give the same results: for consistency checks
|
// Should give the same results: for consistency checks
|
||||||
qpms_errno_t qpms_vswf_fill_alternative(csphvec_t *resultL, csphvec_t *resultM, csphvec_t *resultN, qpms_l_t lMax, sph_t kdrj,
|
qpms_errno_t qpms_vswf_fill_alternative(csphvec_t *resultL, csphvec_t *resultM, csphvec_t *resultN, qpms_l_t lMax, sph_t kdrj,
|
||||||
qpms_bessel_t btyp, qpms_normalisation_t norm);
|
qpms_bessel_t btyp, qpms_normalisation_t norm);
|
||||||
|
|
||||||
|
/// Evaluate VSWFs at a given point from \a l = 1 up to a given degree \a lMax (complex \a kr version).
|
||||||
|
/**
|
||||||
|
* The target arrays \a resultL, \a resultM, \a resultN have to be large enough to contain
|
||||||
|
* \a lMax * (\a lMax + 2) elements. If NULL is passed instead, the corresponding SVWF type
|
||||||
|
* is not evaluated.
|
||||||
|
*
|
||||||
|
* Does not evaluate the zeroth-order wave \f$ \mathbf{L}_0^0 \f$.
|
||||||
|
* If you need that, use qpms_vswf_L00().
|
||||||
|
*/
|
||||||
|
qpms_errno_t qpms_vswf_fill_csph(
|
||||||
|
csphvec_t *resultL, //< Target array for longitudinal VSWFs.
|
||||||
|
csphvec_t *resultM, //< Target array for magnetic VSWFs.
|
||||||
|
csphvec_t *resultN, //< Target array for electric VSWFs.
|
||||||
|
qpms_l_t lMax, //< Maximum multipole degree to be calculated.
|
||||||
|
csph_t kdrj, //< VSWF evaluation point.
|
||||||
|
qpms_bessel_t btyp, qpms_normalisation_t norm);
|
||||||
|
|
||||||
qpms_errno_t qpms_vecspharm_fill(csphvec_t *const a1target, csphvec_t *const a2target, csphvec_t *const a3target,
|
qpms_errno_t qpms_vecspharm_fill(csphvec_t *const a1target, csphvec_t *const a2target, csphvec_t *const a3target,
|
||||||
qpms_l_t lMax, sph_t dir, qpms_normalisation_t norm);
|
qpms_l_t lMax, sph_t dir, qpms_normalisation_t norm);
|
||||||
qpms_errno_t qpms_vecspharm_dual_fill(csphvec_t *const a1target, csphvec_t *const a2target, csphvec_t *const a3target,
|
qpms_errno_t qpms_vecspharm_dual_fill(csphvec_t *const a1target, csphvec_t *const a2target, csphvec_t *const a3target,
|
||||||
|
@ -127,6 +147,9 @@ csphvec_t qpms_eval_vswf(sph_t where,
|
||||||
complex double *longcoeffs, complex double *mgcoeffs, complex double *elcoeffs,
|
complex double *longcoeffs, complex double *mgcoeffs, complex double *elcoeffs,
|
||||||
qpms_l_t lMax, qpms_bessel_t btyp, qpms_normalisation_t norm);
|
qpms_l_t lMax, qpms_bessel_t btyp, qpms_normalisation_t norm);
|
||||||
|
|
||||||
|
csphvec_t qpms_eval_vswf_csph(csph_t where,
|
||||||
|
complex double *longcoeffs, complex double *mgcoeffs, complex double *elcoeffs,
|
||||||
|
qpms_l_t lMax, qpms_bessel_t btyp, qpms_normalisation_t norm);
|
||||||
|
|
||||||
qpms_vswfset_sph_t *qpms_vswfset_make(qpms_l_t lMax, sph_t kdlj,
|
qpms_vswfset_sph_t *qpms_vswfset_make(qpms_l_t lMax, sph_t kdlj,
|
||||||
qpms_bessel_t btyp, qpms_normalisation_t norm);//NI
|
qpms_bessel_t btyp, qpms_normalisation_t norm);//NI
|
||||||
|
|
Loading…
Reference in New Issue