2019-02-19 21:20:30 +02:00
|
|
|
|
/*! \file qpms_types.h
|
|
|
|
|
* \brief Common qpms types.
|
|
|
|
|
*/
|
2017-12-17 17:02:58 +02:00
|
|
|
|
#ifndef QPMS_TYPES_H
|
|
|
|
|
#define QPMS_TYPES_H
|
|
|
|
|
#include <complex.h>
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stddef.h>
|
2019-02-27 11:53:33 +02:00
|
|
|
|
#include <stdint.h>
|
2018-02-01 17:04:51 +02:00
|
|
|
|
|
|
|
|
|
#ifndef M_PI_2
|
2017-12-17 17:02:58 +02:00
|
|
|
|
#define M_PI_2 (1.570796326794896619231321691639751442098584699687552910487)
|
2018-02-01 17:04:51 +02:00
|
|
|
|
#endif
|
2018-02-02 16:23:15 +02:00
|
|
|
|
#ifndef M_PI
|
|
|
|
|
#define M_PI (3.14159265358979323846)
|
|
|
|
|
#endif
|
2017-12-17 17:02:58 +02:00
|
|
|
|
|
|
|
|
|
// integer index types
|
|
|
|
|
typedef int qpms_lm_t;
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// Type for spherical harmonic degree \a l.
|
|
|
|
|
typedef int qpms_l_t; /* can't be unsigned because of the behaviour under the - operator;
|
2019-02-19 23:35:46 +02:00
|
|
|
|
also -1 needed as an invalid value for scalar waves. */
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// Type for spherical harmonic order \a m.
|
2017-12-17 17:42:18 +02:00
|
|
|
|
typedef qpms_lm_t qpms_m_t;
|
2019-02-19 19:48:00 +02:00
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// Type for the (\a l, \a m) multiindex of transversal (\a M or \a N -type) VSWFs.
|
2019-02-19 19:48:00 +02:00
|
|
|
|
/** This corresponds to the typical memory layout for various coefficient etc.
|
2019-02-19 23:35:46 +02:00
|
|
|
|
* Corresponds to the l-primary, m-secondary ordering, i.e.
|
|
|
|
|
* \f[ y = 0: l = 1, m = -1, \f]
|
|
|
|
|
* \f[ y = 1: l = 1, m = 0, \f]
|
|
|
|
|
* \f[ y = 2: l = 1, m = +1, \f]
|
|
|
|
|
* \f[ y = 3: l = 2, m = -2, \f]
|
2019-02-19 19:48:00 +02:00
|
|
|
|
* ...
|
2019-02-27 13:31:20 +02:00
|
|
|
|
*
|
|
|
|
|
* See also indexing.h.
|
2019-02-19 19:48:00 +02:00
|
|
|
|
*/
|
2017-12-17 17:02:58 +02:00
|
|
|
|
typedef size_t qpms_y_t;
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// Type for the (\a l, \a m) multiindex of spherical harmonics, including (0, 0).
|
2019-02-19 21:20:30 +02:00
|
|
|
|
/** This differs from qpms_y_t by being shifted by one and including
|
2019-02-27 13:31:20 +02:00
|
|
|
|
* the \a l = 0 option. Suitable also for scalar and longitudinal waves.
|
|
|
|
|
* Corresponds to the \a l -primary, \a m -secondary ordering, i.e.
|
2019-02-19 23:35:46 +02:00
|
|
|
|
* \f[ y = 0: l = 0, m = 0, \f]
|
|
|
|
|
* \f[ y = 1: l = 1, m = -1, \f]
|
|
|
|
|
* \f[ y = 2: l = 1, m = 0, \f]
|
|
|
|
|
* \f[ y = 3: l = 1, m = +1, \f]
|
|
|
|
|
* \f[ y = 4: l = 2, m = -2, \f]
|
2019-02-19 21:20:30 +02:00
|
|
|
|
* ...
|
2019-02-27 13:31:20 +02:00
|
|
|
|
*
|
|
|
|
|
* See also indexing.h.
|
2019-02-19 21:20:30 +02:00
|
|
|
|
*/
|
|
|
|
|
typedef size_t qpms_y_sc_t;
|
|
|
|
|
|
|
|
|
|
/// Codes of the VSWF types (electric/N, magnetic/M, longitudinal/L).
|
|
|
|
|
typedef enum {
|
2019-02-27 13:31:20 +02:00
|
|
|
|
QPMS_VSWF_ELECTRIC = 2, ///< "Electric" (\a N -type) transversal wave.
|
|
|
|
|
QPMS_VSWF_MAGNETIC = 1, ///< "Magnetic" (\a M -type) transversal wave.
|
|
|
|
|
QPMS_VSWF_LONGITUDINAL = 0 ///< Longitudinal (\a L -type) wave (not relevant for radiation).
|
2019-02-19 21:20:30 +02:00
|
|
|
|
} qpms_vswf_type_t;
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
// FIXME DOC The references to the functions do not work in doxygen:
|
2019-02-19 19:48:00 +02:00
|
|
|
|
/// Exhaustive index type for VSWF basis functions.
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/** Carries information about the wave being of \a M/N/L (magnetic, electric,
|
|
|
|
|
* or longitudinal) type, as well as the wave's degree and order (\a l, \a m).
|
2019-02-19 21:20:30 +02:00
|
|
|
|
*
|
|
|
|
|
* The formula is 4 * (qpms_y_sc_t) y_sc + (qmps_vswf_type_t) type_code,
|
|
|
|
|
* but don't rely on this and use the functions
|
2019-02-27 13:31:20 +02:00
|
|
|
|
* \ref qpms_tmn2uvswfi() and \ref qpms_uvswfi2tmn()
|
2019-02-19 21:20:30 +02:00
|
|
|
|
* from qpms_types.h instead
|
|
|
|
|
* as the formula might change in future versions.
|
2019-02-27 13:31:20 +02:00
|
|
|
|
*
|
|
|
|
|
* See also indexing.h.
|
2019-02-19 19:48:00 +02:00
|
|
|
|
*/
|
2019-02-25 22:25:42 +02:00
|
|
|
|
typedef unsigned long long qpms_uvswfi_t;
|
2019-02-19 19:48:00 +02:00
|
|
|
|
|
|
|
|
|
/// Error codes / return values for certain numerical functions.
|
|
|
|
|
/** These are de facto a subset of the GSL error codes. */
|
2017-12-18 03:04:12 +02:00
|
|
|
|
typedef enum {
|
2019-02-19 21:20:30 +02:00
|
|
|
|
QPMS_SUCCESS = 0, ///< Success.
|
|
|
|
|
QPMS_ERROR = 1, ///< Unspecified error.
|
2019-06-19 12:47:31 +03:00
|
|
|
|
QPMS_ENOMEM = 8, ///< Out of memory.
|
|
|
|
|
QPMS_NAN_ENCOUNTERED = 1024 ///< NaN value encountered in data processing.
|
|
|
|
|
|
2017-12-18 03:04:12 +02:00
|
|
|
|
} qpms_errno_t;
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
|
|
|
|
|
|
2019-02-19 19:48:00 +02:00
|
|
|
|
/// Vector spherical wavefuction normalisation (and sign) convention codes.
|
|
|
|
|
/** Throughout the literature, various conventions for VSWF bases are used.
|
|
|
|
|
* The meaningful ones are the "power" and "spherical harmonic" normalisation
|
2019-02-27 13:31:20 +02:00
|
|
|
|
* conventions, as the (\a l, \a m) and (\a l, \a −m) waves of the same type have the same
|
2019-02-19 19:48:00 +02:00
|
|
|
|
* intensities.
|
|
|
|
|
* One might also encounter a very inconvenient and messy "antinormalisation"
|
|
|
|
|
* used in Xu (TODO reference).
|
|
|
|
|
*
|
|
|
|
|
* Moreover, VSWFs might use various sign convention. Usually they either
|
2019-02-27 13:31:20 +02:00
|
|
|
|
* carry the Condon-Shortley phase \f$ (-1)^m \f$ or not, which is also saved here.
|
2019-02-19 19:48:00 +02:00
|
|
|
|
*
|
|
|
|
|
* TODO references and exact definitions.
|
|
|
|
|
*/
|
2017-12-17 17:02:58 +02:00
|
|
|
|
typedef enum {
|
2019-02-27 13:31:20 +02:00
|
|
|
|
|
|
|
|
|
#define QPMS_NORMALISATION_T_CSBIT 128 ///< A flag used in qpms_normalisation_t indicating the Condon-Shortley phase.
|
|
|
|
|
|
2018-05-09 11:51:41 +03:00
|
|
|
|
#ifdef USE_XU_ANTINORMALISATION
|
2018-01-26 15:07:29 +02:00
|
|
|
|
// As in TODO
|
2019-02-19 23:41:10 +02:00
|
|
|
|
QPMS_NORMALISATION_XU = 4, ///< such that the numerical values in Xu's tables match, not recommended to use otherwise
|
2018-05-09 11:51:41 +03:00
|
|
|
|
QPMS_NORMALISATION_XU_CS = QPMS_NORMALISATION_XU | QPMS_NORMALISATION_T_CSBIT,
|
|
|
|
|
#endif
|
2019-02-19 23:41:10 +02:00
|
|
|
|
QPMS_NORMALISATION_NONE = 3, ///< genuine unnormalised waves (with unnormalised Legendre polynomials)
|
|
|
|
|
QPMS_NORMALISATION_KRISTENSSON = 2, ///< As in http://www.eit.lth.se/fileadmin/eit/courses/eit080f/Literature/book.pdf, power-normalised
|
2018-01-29 17:33:59 +02:00
|
|
|
|
QPMS_NORMALISATION_POWER = QPMS_NORMALISATION_KRISTENSSON,
|
|
|
|
|
// as in TODO
|
2018-01-28 11:18:06 +02:00
|
|
|
|
QPMS_NORMALISATION_TAYLOR = 1,
|
2018-01-29 17:33:59 +02:00
|
|
|
|
QPMS_NORMALISATION_SPHARM = QPMS_NORMALISATION_TAYLOR,
|
|
|
|
|
// Variants with Condon-Shortley phase
|
2018-05-07 06:46:55 +03:00
|
|
|
|
QPMS_NORMALISATION_NONE_CS = QPMS_NORMALISATION_NONE | QPMS_NORMALISATION_T_CSBIT,
|
2018-01-29 17:33:59 +02:00
|
|
|
|
QPMS_NORMALISATION_KRISTENSSON_CS = QPMS_NORMALISATION_KRISTENSSON | QPMS_NORMALISATION_T_CSBIT,
|
|
|
|
|
QPMS_NORMALISATION_POWER_CS = QPMS_NORMALISATION_KRISTENSSON_CS,
|
|
|
|
|
QPMS_NORMALISATION_TAYLOR_CS = QPMS_NORMALISATION_TAYLOR | QPMS_NORMALISATION_T_CSBIT,
|
|
|
|
|
QPMS_NORMALISATION_SPHARM_CS = QPMS_NORMALISATION_TAYLOR_CS,
|
2018-01-28 11:18:06 +02:00
|
|
|
|
QPMS_NORMALISATION_UNDEF = 0
|
|
|
|
|
} qpms_normalisation_t;
|
2017-12-17 17:02:58 +02:00
|
|
|
|
|
2019-02-19 19:48:00 +02:00
|
|
|
|
/// Determine whether the convention includes Condon-Shortley phase (-1) or not (+1).
|
2018-01-29 17:33:59 +02:00
|
|
|
|
static inline int qpms_normalisation_t_csphase(qpms_normalisation_t norm) {
|
|
|
|
|
return (norm & QPMS_NORMALISATION_T_CSBIT)? -1 : 1;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-19 19:48:00 +02:00
|
|
|
|
/// Returns the normalisation convention code without the Condon-Shortley phase.
|
2018-01-29 17:33:59 +02:00
|
|
|
|
static inline int qpms_normalisation_t_normonly(qpms_normalisation_t norm) {
|
|
|
|
|
return norm & (~QPMS_NORMALISATION_T_CSBIT);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-07 15:39:41 +02:00
|
|
|
|
// TODO move the inlines elsewhere
|
2018-05-08 15:39:12 +03:00
|
|
|
|
/* Normalisation of the spherical waves is now scattered in at least three different files:
|
|
|
|
|
* here, we have the norm in terms of radiated power of outgoing wave.
|
|
|
|
|
* In file legendre.c, function qpms_pitau_get determines the norm used in the vswf.c
|
|
|
|
|
* spherical vector wave norms. The "dual" waves in vswf.c use the ..._abssquare function below.
|
|
|
|
|
* In file translations.c, the normalisations are again set by hand using the normfac and lognormfac
|
|
|
|
|
* functions.
|
|
|
|
|
*/
|
2018-02-07 15:39:41 +02:00
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <assert.h>
|
2018-02-01 06:40:45 +02:00
|
|
|
|
// relative to QPMS_NORMALISATION_KRISTENSSON_CS, i.e.
|
|
|
|
|
// P_l^m[normtype] = P_l^m[Kristensson]
|
|
|
|
|
static inline double qpms_normalisation_t_factor(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) {
|
|
|
|
|
int csphase = qpms_normalisation_t_csphase(norm);
|
|
|
|
|
norm = qpms_normalisation_t_normonly(norm);
|
|
|
|
|
double factor;
|
|
|
|
|
switch (norm) {
|
|
|
|
|
case QPMS_NORMALISATION_KRISTENSSON:
|
|
|
|
|
factor = 1.;
|
|
|
|
|
break;
|
|
|
|
|
case QPMS_NORMALISATION_TAYLOR:
|
|
|
|
|
factor = sqrt(l*(l+1));
|
|
|
|
|
break;
|
2018-05-07 06:46:55 +03:00
|
|
|
|
case QPMS_NORMALISATION_NONE:
|
2018-02-01 06:40:45 +02:00
|
|
|
|
factor = sqrt(l*(l+1) * 4 * M_PI / (2*l+1) * exp(lgamma(l+m+1)-lgamma(l-m+1)));
|
|
|
|
|
break;
|
2018-05-09 11:51:41 +03:00
|
|
|
|
#ifdef USE_XU_ANTINORMALISATION // broken probably in legendre.c
|
2018-05-08 15:39:12 +03:00
|
|
|
|
case QPMS_NORMALISATION_XU:
|
|
|
|
|
factor = sqrt(4 * M_PI) / (2*l+1) * exp(lgamma(l+m+1)-lgamma(l-m+1));
|
|
|
|
|
break;
|
2018-05-09 11:51:41 +03:00
|
|
|
|
#endif
|
2018-02-01 06:40:45 +02:00
|
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
factor *= (m%2)?(-csphase):1;
|
|
|
|
|
return factor;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-01 17:04:51 +02:00
|
|
|
|
|
|
|
|
|
// TODO move elsewhere
|
2018-02-01 06:40:45 +02:00
|
|
|
|
static inline double qpms_normalisation_t_factor_abssquare(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) {
|
|
|
|
|
norm = qpms_normalisation_t_normonly(norm);
|
|
|
|
|
switch (norm) {
|
|
|
|
|
case QPMS_NORMALISATION_KRISTENSSON:
|
|
|
|
|
return 1.;
|
|
|
|
|
break;
|
|
|
|
|
case QPMS_NORMALISATION_TAYLOR:
|
|
|
|
|
return l*(l+1);
|
|
|
|
|
break;
|
2018-05-07 06:46:55 +03:00
|
|
|
|
case QPMS_NORMALISATION_NONE:
|
2018-02-01 06:40:45 +02:00
|
|
|
|
return l*(l+1) * 4 * M_PI / (2*l+1) * exp(lgamma(l+m+1)-lgamma(l-m+1));
|
|
|
|
|
break;
|
2018-05-09 11:51:41 +03:00
|
|
|
|
#ifdef USE_XU_ANTINORMALISATION // broken probably in legendre.c
|
2018-05-08 15:39:12 +03:00
|
|
|
|
case QPMS_NORMALISATION_XU:
|
2018-05-09 11:51:41 +03:00
|
|
|
|
{
|
|
|
|
|
double fac = sqrt(4 * M_PI) / (2*l+1) * exp(lgamma(l+m+1)-lgamma(l-m+1));
|
|
|
|
|
return fac * fac;
|
|
|
|
|
}
|
2018-05-08 15:39:12 +03:00
|
|
|
|
break;
|
2018-05-09 11:51:41 +03:00
|
|
|
|
#endif
|
2018-02-01 06:40:45 +02:00
|
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
return NAN;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-29 17:33:59 +02:00
|
|
|
|
|
|
|
|
|
|
2019-02-19 19:48:00 +02:00
|
|
|
|
/// Bessel function kinds.
|
2017-12-17 17:02:58 +02:00
|
|
|
|
typedef enum {
|
2019-02-19 23:35:46 +02:00
|
|
|
|
QPMS_BESSEL_REGULAR = 1, ///< regular (spherical) Bessel function \a j (Bessel function of the first kind)
|
|
|
|
|
QPMS_BESSEL_SINGULAR = 2, ///< singular (spherical) Bessel function \a y (Bessel function of the second kind)
|
|
|
|
|
QPMS_HANKEL_PLUS = 3, ///< (spherical) Hankel function \f$ h_1 = j + iy \f$
|
|
|
|
|
QPMS_HANKEL_MINUS = 4, ///< (spherical) Hankel function \f$ h_2 = j - iy \f$
|
2019-02-19 21:20:30 +02:00
|
|
|
|
QPMS_BESSEL_UNDEF = 0 ///< invalid / unspecified kind
|
2017-12-17 17:02:58 +02:00
|
|
|
|
} qpms_bessel_t;
|
|
|
|
|
|
|
|
|
|
// coordinate system types
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// 3D cartesian coordinates. See also vectors.h.
|
2018-09-19 09:17:04 +03:00
|
|
|
|
typedef struct cart3_t {
|
2017-12-17 17:02:58 +02:00
|
|
|
|
double x, y, z;
|
|
|
|
|
} cart3_t;
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// 3D complex (actually 6D) coordinates. See also vectors.h.
|
2018-09-19 09:17:04 +03:00
|
|
|
|
typedef struct ccart3_t {
|
2018-01-30 01:09:48 +02:00
|
|
|
|
complex double x, y, z;
|
|
|
|
|
} ccart3_t;
|
|
|
|
|
|
2019-06-24 14:57:39 +03:00
|
|
|
|
/// 3D complex vector pair (represents the E, H fields).
|
|
|
|
|
typedef struct ccart3_pair {
|
|
|
|
|
ccart3_t E, H;
|
|
|
|
|
} ccart3_pair;
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// 2D cartesian coordinates. See also vectors.h.
|
|
|
|
|
/** See also vectors.h */
|
2018-09-19 09:17:04 +03:00
|
|
|
|
typedef struct cart2_t {
|
2017-12-17 17:02:58 +02:00
|
|
|
|
double x, y;
|
|
|
|
|
} cart2_t;
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// Spherical coordinates. See also vectors.h.
|
2018-09-19 09:17:04 +03:00
|
|
|
|
typedef struct sph_t {
|
2017-12-17 17:02:58 +02:00
|
|
|
|
double r, theta, phi;
|
|
|
|
|
} sph_t;
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// Spherical coordinates with complex radial component. See also vectors.h.
|
2018-09-19 09:17:04 +03:00
|
|
|
|
typedef struct csph_t { // Do I really need this???
|
2018-02-01 06:40:45 +02:00
|
|
|
|
complex double r;
|
2018-05-06 22:13:10 +03:00
|
|
|
|
double theta, phi;
|
2018-02-01 06:40:45 +02:00
|
|
|
|
} csph_t;
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// 3D complex vector components in local spherical basis. See also vectors.h.
|
2018-09-19 09:17:04 +03:00
|
|
|
|
typedef struct csphvec_t {
|
2017-12-17 19:07:19 +02:00
|
|
|
|
complex double rc, thetac, phic;
|
|
|
|
|
} csphvec_t;
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// 2D polar coordinates. See also vectors.h.
|
2018-09-19 09:17:04 +03:00
|
|
|
|
typedef struct pol_t {
|
2017-12-17 17:02:58 +02:00
|
|
|
|
double r, phi;
|
|
|
|
|
} pol_t;
|
|
|
|
|
|
2019-02-19 19:48:00 +02:00
|
|
|
|
/// Union type capable to contain various 1D, 2D and 3D coordinates.
|
2019-06-27 10:13:39 +03:00
|
|
|
|
/** Usually combined with qpms_coord_system_t. */
|
2018-12-10 17:10:47 +02:00
|
|
|
|
typedef union anycoord_point_t {
|
2019-02-27 13:31:20 +02:00
|
|
|
|
double z; ///< 1D cartesian coordinate.
|
2018-12-10 17:10:47 +02:00
|
|
|
|
cart3_t cart3;
|
|
|
|
|
cart2_t cart2;
|
|
|
|
|
sph_t sph;
|
|
|
|
|
pol_t pol;
|
|
|
|
|
} anycoord_point_t;
|
|
|
|
|
|
2019-02-19 19:48:00 +02:00
|
|
|
|
/// Enum codes for common coordinate systems.
|
2018-12-10 17:10:47 +02:00
|
|
|
|
typedef enum {
|
|
|
|
|
// IF EVER CHANGING THE CONSTANT VALUES HERE,
|
|
|
|
|
// CHECK THAT THEY DO NOT CLASH WITH THOSE IN PGenPointFlags!
|
2019-02-19 21:20:30 +02:00
|
|
|
|
QPMS_COORDS_CART1 = 64, ///< 1D cartesian (= double).
|
|
|
|
|
QPMS_COORDS_POL = 128, ///< 2D polar.
|
|
|
|
|
QPMS_COORDS_SPH = 256, ///< 3D spherical.
|
|
|
|
|
QPMS_COORDS_CART2 = 512, ///< 2D cartesian.
|
|
|
|
|
QPMS_COORDS_CART3 = 1024, ///< 3D cartesian.
|
2019-06-27 10:13:39 +03:00
|
|
|
|
/// Convenience bitmask (not a valid flag!).
|
|
|
|
|
QPMS_COORDS_BITRANGE = QPMS_COORDS_CART1
|
|
|
|
|
| QPMS_COORDS_POL
|
|
|
|
|
| QPMS_COORDS_SPH
|
|
|
|
|
| QPMS_COORDS_CART2
|
|
|
|
|
| QPMS_COORDS_CART3,
|
2018-12-10 17:10:47 +02:00
|
|
|
|
} qpms_coord_system_t;
|
|
|
|
|
|
2019-02-25 18:11:22 +02:00
|
|
|
|
/// Quaternion type.
|
|
|
|
|
/**
|
|
|
|
|
* Internaly represented as a pair of complex numbers,
|
|
|
|
|
* \f$ Q_a = Q_1 + iQ_z, Q_b = Q_y + i Q_x\f$.
|
|
|
|
|
*
|
2019-02-27 13:31:20 +02:00
|
|
|
|
* See wigner.h for "methods".
|
2019-02-25 18:11:22 +02:00
|
|
|
|
*/
|
|
|
|
|
typedef struct qpms_quat_t {
|
|
|
|
|
complex double a, b;
|
|
|
|
|
} qpms_quat_t;
|
|
|
|
|
|
|
|
|
|
/// Quaternion type as four doubles.
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/** See wigner.h for "methods".
|
2019-02-25 18:11:22 +02:00
|
|
|
|
*/
|
|
|
|
|
typedef struct qpms_quat4d_t {
|
|
|
|
|
double c1, ci, cj, ck;
|
|
|
|
|
} qpms_quat4d_t;
|
|
|
|
|
|
|
|
|
|
/// 3D improper rotations represented as a quaternion and a sign of the determinant.
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/** See wigner.h for "methods".
|
2019-02-25 18:11:22 +02:00
|
|
|
|
*/
|
|
|
|
|
typedef struct qpms_irot3_t {
|
|
|
|
|
qpms_quat_t rot; ///< Quaternion representing the rotation part.
|
|
|
|
|
short det; ///< Determinant of the transformation (valid values are 1 (rotation) or -1 (improper rotation)
|
|
|
|
|
} qpms_irot3_t;
|
|
|
|
|
|
2019-02-25 18:54:59 +02:00
|
|
|
|
/// Specifies a finite set of VSWFs.
|
|
|
|
|
/**
|
|
|
|
|
* When for example not all the M and N -type waves up to a degree lMax
|
|
|
|
|
* need to be computed, this will specify the subset.
|
|
|
|
|
*
|
|
|
|
|
* A typical use case would be when only even/odd fields wrt. z-plane
|
|
|
|
|
* mirror symmetry are considered.
|
|
|
|
|
*
|
2019-02-27 13:31:20 +02:00
|
|
|
|
* See vswf.h for "methods".
|
2019-02-25 18:54:59 +02:00
|
|
|
|
*/
|
|
|
|
|
typedef struct qpms_vswf_set_spec_t {
|
|
|
|
|
size_t n; ///< Actual number of VSWF indices included in ilist.
|
|
|
|
|
qpms_uvswfi_t *ilist; ///< List of wave indices.
|
|
|
|
|
qpms_l_t lMax; ///< Maximum degree of the waves specified in ilist.
|
|
|
|
|
qpms_l_t lMax_M, ///< Maximum degree of the magnetic (M-type) waves.
|
|
|
|
|
lMax_N, ///< Maximum degree of the electric (N-type) waves.
|
|
|
|
|
lMax_L; ///< Maximum degree of the longitudinal (L-type) waves.
|
|
|
|
|
size_t capacity; ///< Allocated capacity of ilist.
|
|
|
|
|
qpms_normalisation_t norm; ///< Normalisation convention. To be set manually if needed.
|
|
|
|
|
} qpms_vswf_set_spec_t;
|
2018-01-30 01:09:48 +02:00
|
|
|
|
|
2019-02-27 11:53:33 +02:00
|
|
|
|
/// T-matrix index used in qpms_scatsys_t and related structures.
|
|
|
|
|
typedef int32_t qpms_ss_tmi_t;
|
|
|
|
|
|
|
|
|
|
/// Particle index used in qpms_scatsys_t and related structures.
|
|
|
|
|
typedef int32_t qpms_ss_pi_t;
|
|
|
|
|
|
2019-02-27 12:29:19 +02:00
|
|
|
|
// These types are mainly used in groups.h:
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// Finite group member index. See also groups.h.
|
2019-02-27 12:29:19 +02:00
|
|
|
|
typedef int qpms_gmi_t;
|
|
|
|
|
|
2019-02-27 13:31:20 +02:00
|
|
|
|
/// Irreducible representation index. See also groups.h.
|
2019-02-27 12:29:19 +02:00
|
|
|
|
typedef int qpms_iri_t;
|
|
|
|
|
|
|
|
|
|
/// Permutation representation of a group element.
|
|
|
|
|
/** For now, it's just a string of the form "(0,1)(3,4,5)"
|
|
|
|
|
*/
|
|
|
|
|
typedef const char * qpms_permutation_t;
|
|
|
|
|
|
2019-03-18 15:04:21 +02:00
|
|
|
|
/// A T-matrix.
|
|
|
|
|
/** In the future, I might rather use a more abstract approach in which T-matrix
|
|
|
|
|
* is a mapping (function) of the field expansion coefficients.
|
|
|
|
|
* So the interface might change.
|
|
|
|
|
* For now, let me stick to the square dense matrix representation.
|
|
|
|
|
*/
|
|
|
|
|
typedef struct qpms_tmatrix_t {
|
|
|
|
|
/** \brief VSWF basis specification, NOT owned by qpms_tmatrix_t by default.
|
|
|
|
|
*
|
|
|
|
|
* Usually not checked for meaningfulness by the functions (methods),
|
|
|
|
|
* so the caller should take care that \a spec->ilist does not
|
|
|
|
|
* contain any duplicities and that for each wave with order \a m
|
|
|
|
|
* there is also one with order \a −m.
|
|
|
|
|
*/
|
|
|
|
|
const qpms_vswf_set_spec_t *spec;
|
|
|
|
|
complex double *m; ///< Matrix elements in row-major order.
|
|
|
|
|
bool owns_m; ///< Information wheter m shall be deallocated with qpms_tmatrix_free()
|
|
|
|
|
} qpms_tmatrix_t;
|
2019-02-27 12:29:19 +02:00
|
|
|
|
|
2018-01-30 01:09:48 +02:00
|
|
|
|
#define lmcheck(l,m) assert((l) >= 1 && abs(m) <= (l))
|
2017-12-17 17:02:58 +02:00
|
|
|
|
#endif // QPMS_TYPES
|