2 * \brief T-matrices for scattering systems.
6 // #include "qpms_types.h" // included via materials.h
7 // #include <gsl/gsl_spline.h> // included via materials.h
13 struct qpms_finite_group_t
;
14 typedef struct qpms_finite_group_t qpms_finite_group_t
;
16 /// Returns a pointer to the beginning of the T-matrix row \a rowno.
17 static inline complex double *qpms_tmatrix_row(qpms_tmatrix_t
*t
, size_t rowno
){
18 return t
->m
+ (t
->spec
->n
* rowno
);
21 /// Initialises a zero T-matrix.
22 qpms_tmatrix_t
*qpms_tmatrix_init(const qpms_vswf_set_spec_t
*bspec
);
24 /// Copies a T-matrix, allocating new array for the T-matrix data.
25 qpms_tmatrix_t
*qpms_tmatrix_copy(const qpms_tmatrix_t
*T
);
27 /// Destroys a T-matrix.
28 void qpms_tmatrix_free(qpms_tmatrix_t
*t
);
30 /// Check T-matrix equality/similarity.
32 * This function actually checks for identical vswf specs.
33 * TODO define constants with "default" atol, rtol for this function.
35 bool qpms_tmatrix_isclose(const qpms_tmatrix_t
*T1
, const qpms_tmatrix_t
*T2
,
36 const double rtol
, const double atol
);
38 /// Creates a T-matrix from another matrix and a symmetry operation.
39 /** The symmetry operation is expected to be a unitary (square)
40 * matrix \a M with the same
41 * VSWF basis spec as the T-matrix (i.e. \a t->spec). The new T-matrix will then
42 * correspond to CHECKME \f[ T' = MTM^\dagger \f]
44 qpms_tmatrix_t
*qpms_tmatrix_apply_symop(
45 const qpms_tmatrix_t
*T
, ///< the original T-matrix
46 const complex double *M
///< the symmetry op matrix in row-major format
49 /// Applies a symmetry operation onto a T-matrix, rewriting the original T-matrix data.
50 /** The symmetry operation is expected to be a unitary (square)
51 * matrix \a M with the same
52 * VSWF basis spec as the T-matrix (i.e. \a t->spec). The new T-matrix will then
53 * correspond to CHECKME \f[ T' = MTM^\dagger \f]
55 qpms_tmatrix_t
*qpms_tmatrix_apply_symop_inplace(
56 qpms_tmatrix_t
*T
, ///< the original T-matrix
57 const complex double *M
///< the symmetry op matrix in row-major format
60 /// Symmetrizes a T-matrix with an involution symmetry operation.
61 /** The symmetry operation is expected to be a unitary (square)
62 * matrix \a M with the same
63 * VSWF basis spec as the T-matrix (i.e. \a t->spec). The new T-matrix will then
64 * correspond to CHECKME \f[ T' = \frac{T + MTM^\dagger}{2} \f]
66 qpms_tmatrix_t
*qpms_tmatrix_symmetrise_involution(
67 const qpms_tmatrix_t
*T
, ///< the original T-matrix
68 const complex double *M
///< the symmetry op matrix in row-major format
71 /// Creates a \f$ C_\infty \f$ -symmetrized version of a T-matrix.
73 * \f[ {T'}_{tlm}^{\tau\lambda\mu} = T_{tlm}^{\tau\lambda\mu} \delta_{m\mu} \f]
75 qpms_tmatrix_t
*qpms_tmatrix_symmetrise_C_inf(
76 const qpms_tmatrix_t
*T
///< the original T-matrix
78 /// Creates a \f$ C_N \f$ -symmetrized version of a T-matrix.
80 * \f[ {T'}_{tlm}^{\tau\lambda\mu} = \begin{cases}
81 * T{}_{lm}^{\lambda\mu} & (m-\mu)\mod N=0\\
82 * 0 & (m-\mu)\mod N\ne0
85 qpms_tmatrix_t
*qpms_tmatrix_symmetrise_C_N(
86 const qpms_tmatrix_t
*T
, ///< the original T-matrix
87 int N
///< number of z-axis rotations in the group
90 /// Symmetrizes a T-matrix with an involution symmetry operation, rewriting the original one.
91 /** The symmetry operation is expected to be a unitary (square)
92 * matrix \a M with the same
93 * VSWF basis spec as the T-matrix (i.e. \a t->spec). The new T-matrix will then
94 * correspond to CHECKME \f[ T' = \frac{T + MTM^\dagger}{2} \f]
96 qpms_tmatrix_t
*qpms_tmatrix_symmetrise_involution_inplace(
97 qpms_tmatrix_t
*T
, ///< the original T-matrix
98 const complex double *M
///< the symmetry op matrix in row-major format
101 /// Creates a \f$ C_\infty \f$ -symmetrized version of a T-matrix, rewriting the original one.
103 * \f[ {T'}_{tlm}^{\tau\lambda\mu} = T_{tlm}^{\tau\lambda\mu} \delta_{m\mu} \f]
105 qpms_tmatrix_t
*qpms_tmatrix_symmetrise_C_inf_inplace(
106 qpms_tmatrix_t
*T
///< the original T-matrix
108 /// Creates a \f$ C_N \f$ -symmetrized version of a T-matrix, rewriting the original one.
110 * \f[ {T'}_{tlm}^{\tau\lambda\mu} = \begin{cases}
111 * T{}_{lm}^{\lambda\mu} & (m-\mu)\mod N=0\\
112 * 0 & (m-\mu)\mod N\ne0
115 qpms_tmatrix_t
*qpms_tmatrix_symmetrise_C_N_inplace(
116 qpms_tmatrix_t
*T
, ///< the original T-matrix
117 int N
///< number of z-axis rotations in the group
120 /// Reads an open scuff-tmatrix generated file.
122 * \a *freqs, \a *freqs_su, \a *tmatrices_array and \a *tmdata
123 * arrays are allocated by this function
124 * and have to be freed by the caller after use.
125 * \a freqs_su and \a tmatrices_array can be NULL, in that case
126 * the respective arrays are not filled nor allocated.
128 * The contents of tmatrices_array is NOT
129 * supposed to be freed element per element.
131 * TODO more checks and options regarding NANs etc.
134 qpms_errno_t
qpms_load_scuff_tmatrix(
135 const char *path
, ///< Path to the TMatrix file
136 const qpms_vswf_set_spec_t
*bspec
, ///< VSWF set spec
137 size_t *n
, ///< Number of successfully loaded t-matrices
138 double **freqs
, ///< Frequencies in SI units..
139 double **freqs_su
, ///< Frequencies in SCUFF units (optional).
140 /// The resulting T-matrices (optional).
141 qpms_tmatrix_t
**tmatrices_array
,
142 complex double **tmdata
///< The T-matrices raw contents
145 /// Tells whether qpms_load_scuff_tmatrix should crash if fopen() fails.
146 /** If true (default), the function causes the program
147 * die e.g. when the tmatrix file
150 * If false, it does nothing and returns an appropriate error value instead.
151 * This is desirable e.g. when used in Python (so that proper exception can
154 extern bool qpms_load_scuff_tmatrix_crash_on_failure
;
156 /// Loads a scuff-tmatrix generated file.
157 /** A simple wrapper over qpms_read_scuff_tmatrix() that needs a
158 * path instead of open FILE.
160 * The T-matrix is transformed from the VSWF basis defined by
161 * QPMS_NORMALISATION_CONVENTION_SCUFF into the basis defined
162 * by convention bspec->norm.
164 * Right now, bspec->norm with real or "reversed complex" spherical
165 * harmonics are not supported.
167 qpms_errno_t
qpms_read_scuff_tmatrix(
168 FILE *f
, ///< An open stream with the T-matrix data.
169 const qpms_vswf_set_spec_t
*bspec
, ///< VSWF set spec
170 size_t *n
, ///< Number of successfully loaded t-matrices
171 double **freqs
, ///< Frequencies in SI units.
172 double **freqs_su
, ///< Frequencies in SCUFF units (optional).
173 /// The resulting T-matrices (optional).
174 qpms_tmatrix_t
**tmatrices_array
,
175 /// The T-matrices raw contents.
176 /** The coefficient of outgoing wave defined by
177 * \a bspec->ilist[desti] as a result of incoming wave
178 * \a bspec->ilist[srci] at frequency \a (*freqs)[fi]
180 * (*tmdata)[bspec->n*bspec->n*fi + desti*bspec->n + srci].
182 complex double ** tmdata
185 /// In-place application of point group elements on raw T-matrix data.
186 /** \a tmdata can be e.g. obtained by qpms_load_scuff_tmatrix().
187 * The \a symops array should always contain all elements of a finite
188 * point (sub)group, including the identity operation.
192 qpms_errno_t
qpms_symmetrise_tmdata_irot3arr(
193 complex double *tmdata
, const size_t tmcount
,
194 const qpms_vswf_set_spec_t
*bspec
,
196 const qpms_irot3_t
*symops
199 /// In-place application of a point group on raw T-matrix data.
200 /** This does the same as qpms_symmetrise_tmdata_irot3arr(),
201 * but takes a valid finite point group as an argument.
205 qpms_errno_t
qpms_symmetrise_tmdata_finite_group(
206 complex double *tmdata
, const size_t tmcount
,
207 const qpms_vswf_set_spec_t
*bspec
,
208 const qpms_finite_group_t
*pointgroup
211 /// In-place application of point group elements on a T-matrix.
212 /** The \a symops array should always contain all elements of a finite
213 * point (sub)group, including the identity operation.
217 qpms_tmatrix_t
*qpms_tmatrix_symmetrise_irot3arr_inplace(
220 const qpms_irot3_t
*symops
223 /// In-place application of point group elements on a T-matrix.
224 /** This does the same as qpms_tmatrix_symmetrise_irot3arr(),
225 * but takes a valid finite point group as an argument.
229 qpms_tmatrix_t
*qpms_tmatrix_symmetrise_finite_group_inplace(
231 const qpms_finite_group_t
*pointgroup
234 /// Application of T-matrix on a vector of incident field coefficients, \f$ f = Ta \f$.
235 complex double *qpms_apply_tmatrix(
236 complex double *f_target
, ///< Scattered field coefficient array of size T->spec->n; if NULL, a new one is allocated.
237 const complex double *a
, ///< Incident field coefficient array of size T->spec->n.
238 const qpms_tmatrix_t
*T
241 /// Generic T-matrix generator function that fills a pre-initialised qpms_tmatrix_t given a frequency.
243 * qpms_tmatrix_generator_axialsym()
244 * qpms_tmatrix_generator_interpolator()
245 * qpms_tmatrix_generator_sphere()
246 * qpms_tmatrix_generator_constant()
248 typedef struct qpms_tmatrix_generator_t
{
249 qpms_errno_t (*function
) (qpms_tmatrix_t
*t
, ///< T-matrix to fill.
250 complex double omega
, ///< Angular frequency.
251 const void *params
///< Implementation dependent parameters.
253 const void *params
; ///< Parameter pointer passed to the function.
254 } qpms_tmatrix_generator_t
;
256 /// Implementation of qpms_matrix_generator_t that just copies a constant matrix.
257 /** N.B. this does almost no checks at all, so use it only for t-matrices with
258 * the same base spec.
260 qpms_errno_t
qpms_tmatrix_generator_constant(qpms_tmatrix_t
*t
,
261 complex double omega
,
262 /// Source T-matrix, real type is (const qpms_tmatrix_t*).
263 const void *tmatrix_orig
266 /* Fuck this, include the whole <gsl/gsl_spline.h>
267 typedef struct gsl_spline gsl_spline; // Forward declaration for the interpolator struct
268 typedef struct gsl_interp_type gsl_interp_type;
269 extern const gsl_interp_type * gsl_interp_linear;
270 extern const gsl_interp_type * gsl_interp_polynomial;
271 extern const gsl_interp_type * gsl_interp_cspline;
272 extern const gsl_interp_type * gsl_interp_cspline_periodic;
273 extern const gsl_interp_type * gsl_interp_akima;
274 extern const gsl_interp_type * gsl_interp_akima_periodic;
275 extern const gsl_interp_type * gsl_interp_steffen;
278 // struct gsl_interp_accel; // use if lookup proves to be too slow
279 typedef struct qpms_tmatrix_interpolator_t
{
280 const qpms_vswf_set_spec_t
*bspec
;
282 gsl_spline
**splines_real
; ///< There will be a spline object for each nonzero element
283 gsl_spline
**splines_imag
; ///< There will be a spline object for each nonzero element
284 // gsl_interp_accel **accel_real;
285 // gsl_interp_accel **accel_imag;
286 } qpms_tmatrix_interpolator_t
;
288 /// Free a T-matrix interpolator.
289 void qpms_tmatrix_interpolator_free(qpms_tmatrix_interpolator_t
*interp
);
291 /// Fills an existing T-matrix with new interpolated values.
292 qpms_errno_t
qpms_tmatrix_interpolator_eval_fill(qpms_tmatrix_t
*target
, ///< T-matrix to be updated, not NULL.
293 const qpms_tmatrix_interpolator_t
*interp
, double freq
);
295 /// Evaluate a T-matrix interpolated value.
296 /** The result is to be freed using qpms_tmatrix_free().*/
297 qpms_tmatrix_t
*qpms_tmatrix_interpolator_eval(const qpms_tmatrix_interpolator_t
*interp
, double freq
);
299 /// Create a T-matrix interpolator from frequency and T-matrix arrays.
300 qpms_tmatrix_interpolator_t
*qpms_tmatrix_interpolator_create(size_t n
, ///< Number of freqs and T-matrices provided.
301 const double *freqs
, const qpms_tmatrix_t
*tmatrices_array
, ///< N.B. array of qpms_tmatrix_t, not pointers!
302 const gsl_interp_type
*iptype
303 //, bool copy_bspec ///< if true, copies its own copy of basis spec from the first T-matrix.
307 /// qpms_tmatrix_interpolator for qpms_tmatrix_generator_t.
308 /** As in qpms_tmatrix_interpolator_eval(), the imaginary part of frequency is discarded!
310 qpms_errno_t
qpms_tmatrix_generator_interpolator(qpms_tmatrix_t
*t
, ///< T-matrix to fill.
311 complex double omega
, ///< Angular frequency.
312 const void *interpolator
///< Parameter of type qpms_tmatrix_interpolator_t *.
315 /// Calculates the reflection Mie-Lorentz coefficients for a spherical particle.
317 * This function is based on the previous python implementation mie_coefficients() from qpms_p.py,
318 * so any bugs therein should affect this function as well and perhaps vice versa.
320 * Most importantly, the case of magnetic material, \a mu_i != 0 or \a mu_e != 0 has never been tested
321 * and might give wrong results.
323 * \return Array with the Mie-Lorentz reflection coefficients in the order determined by bspec.
324 * If \a target was not NULL, this is target, otherwise a newly allocated array.
328 complex double *qpms_mie_coefficients_reflection(
329 complex double *target
, ///< Target array of length bspec->n. If NULL, a new one will be allocated.
330 const qpms_vswf_set_spec_t
*bspec
, ///< Defines which of the coefficients are calculated.
331 double a
, ///< Radius of the sphere.
332 complex double k_i
, ///< Wave number of the internal material of the sphere.
333 complex double k_e
, ///< Wave number of the surrounding medium.
334 complex double mu_i
, ///< Relative permeability of the sphere material.
335 complex double mu_e
, ///< Relative permeability of the surrounding medium.
336 qpms_bessel_t J_ext
, ///< Kind of the "incoming" waves. Most likely QPMS_BESSEL_REGULAR.
337 qpms_bessel_t J_scat
///< Kind of the "scattered" waves. Most likely QPMS_HANKEL_PLUS.
340 /// Replaces the contents of an existing T-matrix with that of a spherical nanoparticle calculated using the Lorentz-mie theory.
341 qpms_errno_t
qpms_tmatrix_spherical_fill(qpms_tmatrix_t
*t
, ///< T-matrix whose contents are to be replaced. Not NULL.
342 double a
, ///< Radius of the sphere.
343 complex double k_i
, ///< Wave number of the internal material of the sphere.
344 complex double k_e
, ///< Wave number of the surrounding medium.
345 complex double mu_i
, ///< Relative permeability of the sphere material.
346 complex double mu_e
///< Relative permeability of the surrounding medium.
349 /// Parameter structure for qpms_tmatrix_generator_sphere().
350 typedef struct qpms_tmatrix_generator_sphere_param_t
{
351 qpms_epsmu_generator_t outside
;
352 qpms_epsmu_generator_t inside
;
354 } qpms_tmatrix_generator_sphere_param_t
;
356 /// T-matrix generator for spherical particles using Lorentz-Mie solution.
357 qpms_errno_t
qpms_tmatrix_generator_sphere(qpms_tmatrix_t
*t
,
358 complex double omega
,
359 const void *params
///< Of type qpms_tmatrix_generator_sphere_param_t.
362 /// Creates a new T-matrix of a spherical particle using the Lorentz-Mie theory.
363 static inline qpms_tmatrix_t
*qpms_tmatrix_spherical(
364 const qpms_vswf_set_spec_t
*bspec
,
365 double a
, ///< Radius of the sphere.
366 complex double k_i
, ///< Wave number of the internal material of the sphere.
367 complex double k_e
, ///< Wave number of the surrounding medium.
368 complex double mu_i
, ///< Relative permeability of the sphere material.
369 complex double mu_e
///< Relative permeability of the surrounding medium.
371 qpms_tmatrix_t
*t
= qpms_tmatrix_init(bspec
);
372 qpms_tmatrix_spherical_fill(t
, a
, k_i
, k_e
, mu_i
, mu_e
);
376 /// Convenience function to calculate T-matrix of a non-magnetic spherical particle using the permittivity values, replacing existing T-matrix data.
377 qpms_errno_t
qpms_tmatrix_spherical_mu0_fill(
378 qpms_tmatrix_t
*t
, ///< T-matrix whose contents are to be replaced. Not NULL.
379 double a
, ///< Radius of the sphere.
380 double omega
, ///< Angular frequency.
381 complex double epsilon_fg
, ///< Relative permittivity of the sphere.
382 complex double epsilon_bg
///< Relative permittivity of the background medium.
385 /// Convenience function to calculate T-matrix of a non-magnetic spherical particle using the permittivity values.
386 static inline qpms_tmatrix_t
*qpms_tmatrix_spherical_mu0(
387 const qpms_vswf_set_spec_t
*bspec
,
388 double a
, ///< Radius of the sphere.
389 double omega
, ///< Angular frequency.
390 complex double epsilon_fg
, ///< Relative permittivity of the sphere.
391 complex double epsilon_bg
///< Relative permittivity of the background medium.
393 qpms_tmatrix_t
*t
= qpms_tmatrix_init(bspec
);
394 qpms_tmatrix_spherical_mu0_fill(t
, a
, omega
, epsilon_fg
, epsilon_bg
);
398 /// Return value type for qpms_arc_function_t.
399 typedef struct qpms_arc_function_retval_t
{
400 double r
; ///< Distance from the origin.
401 double beta
; ///< Angle between surface normal and radial direction.
402 } qpms_arc_function_retval_t
;
404 /// Prototype for general parametrisation of \f$ C_\infty \f$-symmetric particle's surface.
405 typedef struct qpms_arc_function_t
{
406 /// Arc parametrisation function.
407 /** TODO link to notes.
410 * qpms_arc_cylinder(),
413 qpms_arc_function_retval_t (*function
) (
414 double theta
, ///< Polar angle from interval \f$ [0, \pi] \f$.
415 const void *params
///< Pointer to implementation specific parameters.
418 } qpms_arc_function_t
;
420 /// Parameter structure for qpms_arc_cylinder().
421 typedef struct qpms_arc_cylinder_params_t
{
422 double R
; ///< Cylinder radius.
423 double h
; ///< Cylinder height.
424 } qpms_arc_cylinder_params_t
;
426 /// Arc parametrisation of cylindrical particle; for qpms_arc_function_t.
427 qpms_arc_function_retval_t
qpms_arc_cylinder(double theta
,
428 const void *params
; ///< Points to qpms_arc_cylinder_params_t
431 /// Arc parametrisation of spherical particle; for qpms_arc_function_t.
432 /** Useful mostly only for benchmarks, as one can use the Mie-Lorentz solution. */
433 qpms_arc_function_retval_t
qpms_arc_sphere(double theta
,
434 const void *R
; ///< Points to double containing particle's radius.
438 /// Replaces T-matrix contents with those of a particle with \f$ C_\infty \f$ symmetry.
440 * N.B. currently, this might crash for higher values of lMax (lMax > 5).
441 * Also, it seems that I am doing something wrong, as the result is accurate for sphere
442 * with lMax = 1 and for higher l the accuracy decreases.
444 qpms_errno_t
qpms_tmatrix_axialsym_fill(
445 qpms_tmatrix_t
*t
, ///< T-matrix whose contents are to be replaced. Not NULL.
446 complex double omega
, ///< Angular frequency.
447 qpms_epsmu_t outside
, ///< Optical properties of the outside medium.
448 qpms_epsmu_t inside
, ///< Optical properties of the particle's material.
449 qpms_arc_function_t shape
, ///< Particle surface parametrisation.
450 /** If `lMax_extend > t->bspec->lMax`, then the internal \a Q, \a R matrices will be
451 * trimmed at this larger lMax; the final T-matrix will then be trimmed
452 * according to bspec.
457 /// Creates a new T-matrix of a particle with \f$ C_\infty \f$ symmetry.
458 static inline qpms_tmatrix_t
*qpms_tmatrix_axialsym(
459 const qpms_vswf_set_spec_t
*bspec
,
460 complex double omega
, ///< Angular frequency.
461 qpms_epsmu_t outside
, ///< Optical properties of the outside medium.
462 qpms_epsmu_t inside
, ///< Optical properties of the particle's material.
463 qpms_arc_function_t shape
, ///< Particle surface parametrisation.
464 /// Internal lMax to improve precision of the result.
465 /** If `lMax_extend > bspec->lMax`, then the internal \a Q, \a R matrices will be
466 * trimmed at this larger lMax; the final T-matrix will then be trimmed
467 * according to bspec.
471 qpms_tmatrix_t
*t
= qpms_tmatrix_init(bspec
);
472 qpms_tmatrix_axialsym_fill(t
, omega
, outside
, inside
, shape
, lMax_extend
);
476 /// Parameter structure for qpms_tmatrix_generator_axialsym.
477 typedef struct qpms_tmatrix_generator_axialsym_param_t
{
478 qpms_epsmu_generator_t outside
;
479 qpms_epsmu_generator_t inside
;
480 qpms_arc_function_t shape
;
481 qpms_l_t lMax_extend
;
482 } qpms_tmatrix_generator_axialsym_param_t
;
485 /// qpms_tmatrix_axialsym for qpms_tmatrix_generator_t
486 qpms_errno_t
qpms_tmatrix_generator_axialsym(qpms_tmatrix_t
*t
, ///< T-matrix to fill.
487 complex double omega
, ///< Angular frequency.
488 const void *params
///< Parameters of type qpms_tmatrix_generator_axialsym_param_t.
492 /// Computes the (reduced) transposed R or Q matrix for axially symmetric particle (useful for debugging).
493 qpms_errno_t
qpms_tmatrix_generator_axialsym_RQ_transposed_fill(complex double *target
,
494 complex double omega
,
495 const qpms_tmatrix_generator_axialsym_param_t
*param
,
496 qpms_normalisation_t norm
,
500 /// Computes the (reduced) transposed R or Q matrix for axially symmetric particle (useful mostly for debugging).
501 qpms_errno_t
qpms_tmatrix_axialsym_RQ_transposed_fill(complex double *target
,
502 complex double omega
, qpms_epsmu_t outside
, qpms_epsmu_t inside
,
503 qpms_arc_function_t shape
, qpms_l_t lMaxQR
, qpms_normalisation_t norm
,
504 qpms_bessel_t J
///< Use QPMS_BESSEL_REGULAR to calculate \f$ R^T\f$ or QPMS_HANKEL_PLUS to calculate \f$ Q^T\f$.
508 /// An "abstract" T-matrix, contains a T-matrix generator instead of actual data.
509 typedef struct qpms_tmatrix_function_t
{
510 /** \brief VSWF basis specification, NOT owned by qpms_tmatrix_t by default.
512 * Usually not checked for meaningfulness by the functions (methods),
513 * so the caller should take care that \a spec->ilist does not
514 * contain any duplicities and that for each wave with order \a m
515 * there is also one with order \a −m.
517 const qpms_vswf_set_spec_t
*spec
;
518 const qpms_tmatrix_generator_t
*gen
; ///< A T-matrix generator function.
519 } qpms_tmatrix_function_t
;
521 /// A recepy to create another T-matrices from qpms_tmatrix_fuction_t by symmetry operations.
522 typedef struct qpms_derived_tmatrix_function_t
{
523 const qpms_tmatrix_function_t
*t
;
528 // Abstract types that describe T-matrix/particle/scatsystem symmetries
529 // To be implemented later. See also the thoughts in the beginning of groups.h.
531 typedef *char qpms_tmatrix_id_t
; ///< Maybe I want some usual integer type instead.
533 ///Abstract T-matrix type draft.
537 typedef struct qpms_abstract_tmatrix_t
{
538 qpms_tmatrix_id_t id
;
539 /// Generators of the discrete point group under which T-matrix is invariant.
540 qpms_irot3_t
*invar_gens
;
541 /// Length of invar_gens.
542 qpms_gmi_t invar_gens_size
;
544 } qpms_abstract_tmatrix_t
;
547 typedef struct qpms_abstract_particle_t
{
548 } qpms_abstract_particle_t
;
550 /// An abstract particle, defined by its position and abstract T-matrix.
551 typedef struct qpms_abstract_particle_t
{
552 cart3_t pos
; ///< Particle position in cartesian coordinates.
553 const qpms_abstract_tmatrix_t
*tmatrix
; ///< T-matrix; not owned by this.
554 } qpms_abstract_particle_t
;
557 /** This is just an alias, as the same index can be used for
558 * abstract T-matrices as well.
560 typedef qpms_particle_tid_t qpms_abstract_particle_tid_t
;