WIP cython wrappers for T-matrix generators

Former-commit-id: 8f3cabbc8039e8096d91bc4c21bcb3380638820d
This commit is contained in:
Marek Nečada 2019-08-11 23:37:25 +03:00
parent d00e46b908
commit 5094fc1bc4
4 changed files with 137 additions and 1 deletions

View File

@ -11,6 +11,8 @@ cdef class TMatrixInterpolator:
cdef double *freqs_su cdef double *freqs_su
cdef size_t nfreqs cdef size_t nfreqs
cdef qpms_tmatrix_interpolator_t *interp cdef qpms_tmatrix_interpolator_t *interp
cdef inline qpms_tmatrix_interpolator_t *rawpointer(self):
return self.interp
cdef class CTMatrix: # N.B. there is another type called TMatrix in tmatrices.py! cdef class CTMatrix: # N.B. there is another type called TMatrix in tmatrices.py!
cdef readonly np.ndarray m # Numpy array holding the matrix data cdef readonly np.ndarray m # Numpy array holding the matrix data
@ -23,3 +25,7 @@ cdef class CTMatrix: # N.B. there is another type called TMatrix in tmatrices.py
Don't forget to reference the BaseSpec object itself when storing the pointer anywhere!!! Don't forget to reference the BaseSpec object itself when storing the pointer anywhere!!!
''' '''
return &(self.t) return &(self.t)

View File

@ -3,6 +3,7 @@ from .qpms_cdefs cimport *
from .cybspec cimport BaseSpec from .cybspec cimport BaseSpec
from .cycommon import * from .cycommon import *
from .cycommon cimport make_c_string from .cycommon cimport make_c_string
from .cymaterials cimport EpsMuGenerator
from .qpms_c cimport FinitePointGroup from .qpms_c cimport FinitePointGroup
import warnings import warnings
import os import os
@ -114,3 +115,107 @@ cdef class CTMatrix: # N.B. there is another type called TMatrix in tmatrices.py
tm = CTMatrix(spec, 0) tm = CTMatrix(spec, 0)
tm.spherical_perm_fill(radius, freq, epsilon_int, epsilon_ext) tm.spherical_perm_fill(radius, freq, epsilon_int, epsilon_ext)
return tm return tm
cdef class __MieParams:
# Not directly callable right now, serves just to be used by TMatrixGenerator.
cdef qpms_tmatrix_generator_sphere_param_t cparam
cdef EpsMuGenerator outside
cdef EpsMuGenerator inside
cdef inline void *rawpointer(self):
return <void *>&(self.cparam)
def __init__(self, outside, inside, r):
self.inside = inside
self.outside = outside
self.cparam.inside = self.inside.raw();
self.cparam.outside = self.outside.raw();
self.cparam.radius = r
property r:
def __get__(self):
return self.cparam.radius
def __set__(self, val):
self.cparam.radius = val
cdef class __ArcCylinder:
cdef qpms_arc_cylinder_params_t p
cdef inline void *rawpointer(self):
return <void *> &(self.p)
cdef class __ArcSphere:
cdef double r
cdef inline void *rawpointer(self):
return <void *> &(self.r)
cdef qpms_arc_function_retval_t userarc(double theta, const void *params):
cdef object fun = <object> params
cdef qpms_arc_function_retval_t retval
retval.r, retval.beta = fun(theta)
return retval
cdef class ArcFunction:
cdef qpms_arc_function_t g
cdef object holder
def __init__(self, what):
if isinstance(what, __ArcCylinder):
self.holder = what
self.g.function = qpms_arc_cylinder
self.g.params = (<__ArcCylinder?>self.holder).rawpointer()
elif isinstance(what, __ArcSphere):
self.holder = what
self.g.function = qpms_arc_sphere
self.g.params = (<__ArcSphere?>self.holder).rawpointer()
elif callable(what):
warnings.warn("Custom python (r, beta) arc functions are an experimental feature. Also expect it to be slow.")
self.holder = what
self.g.function = userarc
self.g.params = <const void *> self.holder
elif isinstance(what, ArcFunction): #Copy constructor
self.holder = what.holder
self.g = (<ArcFunction?>what).g
self.holder.rawpointer()
cdef class __AxialSymParams:
cdef qpms_tmatrix_generator_axialsym_param_t p
cdef EpsMuGenerator outside
cdef EpsMuGenerator inside
cdef ArcFunction shape
cdef void * rawpointer(self):
return <void *> &(self.p)
property lMax_extend:
def __get__(self):
return self.p.lMax_extend
def __set__(self, val):
self.p.lMax_extend = val
def __init__(self, outside, inside, shape, *args, **kwargs):
self.outside = outside
self.p.outside = self.outside.g
self.inside = inside
self.p.inside = self.inside.g
self.shape = shape
self.p.shape = self.shape.g
if len(args)>0:
self.lMax_extend = args[0]
if 'lMax_extend' in kwargs.keys():
self.lMax_extend = kwargs['lMax_extend']
cdef class TMatrixGenerator:
cdef qpms_tmatrix_generator_t g
cdef object holder
cdef qpms_tmatrix_generator_t raw(self):
return self.g
def __init__(self, what):
if isinstance(what, __MieParams):
self.holder = what
self.g.function = qpms_tmatrix_generator_sphere
self.g.params = (<__MieParams?>self.holder).rawpointer()
elif isinstance(what,__AxialSymParams):
self.holder = what
self.g.function = qpms_tmatrix_generator_axialsym
self.g.params = (<__AxialSymParams?>self.holder).rawpointer()
else:
raise ValueError("Can't construct TMatrixGenerator from that")

View File

@ -35,6 +35,7 @@
#define SQ(x) ((x)*(x)) #define SQ(x) ((x)*(x))
#define MAX(x,y) ((x) < (y) ? (y) : (x)) #define MAX(x,y) ((x) < (y) ? (y) : (x))
#define MIN(x,y) ((x) > (y) ? (y) : (x))
qpms_tmatrix_t *qpms_tmatrix_init(const qpms_vswf_set_spec_t *bspec) { qpms_tmatrix_t *qpms_tmatrix_init(const qpms_vswf_set_spec_t *bspec) {
qpms_tmatrix_t *t = malloc(sizeof(qpms_tmatrix_t)); qpms_tmatrix_t *t = malloc(sizeof(qpms_tmatrix_t));
@ -692,7 +693,7 @@ qpms_errno_t qpms_tmatrix_axialsym_fill(
qpms_tmatrix_t *t, complex double omega, qpms_epsmu_t outside, qpms_tmatrix_t *t, complex double omega, qpms_epsmu_t outside,
qpms_epsmu_t inside,qpms_arc_function_t shape, qpms_l_t lMaxQR) qpms_epsmu_t inside,qpms_arc_function_t shape, qpms_l_t lMaxQR)
{ {
QPMS_UNTESTED; QPMS_UNTESTED; // TODO also check whether this is valid for all norms.
const qpms_vswf_set_spec_t *bspec = t->spec; const qpms_vswf_set_spec_t *bspec = t->spec;
struct tmatrix_axialsym_integral_param_t p; struct tmatrix_axialsym_integral_param_t p;
p.k = qpms_wavenumber(omega, outside); p.k = qpms_wavenumber(omega, outside);
@ -797,3 +798,16 @@ qpms_errno_t qpms_tmatrix_generator_axialsym(qpms_tmatrix_t *t, complex double o
p->shape, p->shape,
p->lMax_extend); p->lMax_extend);
} }
qpms_errno_t qpms_tmatrix_generator_constant(qpms_tmatrix_t *t,
complex double omega, const void *tmorig) {
QPMS_UNTESTED;
// TODO more thorough check on bspec!
const qpms_tmatrix_t *orig = tmorig;
const size_t tocopy = SQ(MIN(t->spec->n, orig->spec->n));
memcpy(t->m, orig->m, tocopy*sizeof(complex double));
memset(t->m+tocopy, 0, (SQ(t->spec->n)-tocopy)*sizeof(complex double));
return QPMS_SUCCESS;
}

View File

@ -241,6 +241,7 @@ complex double *qpms_apply_tmatrix(
* qpms_tmatrix_generator_axialsym() * qpms_tmatrix_generator_axialsym()
* qpms_tmatrix_generator_interpolator() * qpms_tmatrix_generator_interpolator()
* qpms_tmatrix_generator_sphere() * qpms_tmatrix_generator_sphere()
* qpms_tmatrix_generator_constant()
*/ */
typedef struct qpms_tmatrix_generator_t { typedef struct qpms_tmatrix_generator_t {
qpms_errno_t (*function) (qpms_tmatrix_t *t, ///< T-matrix to fill. qpms_errno_t (*function) (qpms_tmatrix_t *t, ///< T-matrix to fill.
@ -250,6 +251,16 @@ typedef struct qpms_tmatrix_generator_t {
const void *params; ///< Parameter pointer passed to the function. const void *params; ///< Parameter pointer passed to the function.
} qpms_tmatrix_generator_t; } qpms_tmatrix_generator_t;
/// Implementation of qpms_matrix_generator_t that just copies a constant matrix.
/** N.B. this does almost no checks at all, so use it only for t-matrices with
* the same base spec.
*/
qpms_errno_t qpms_tmatrix_generator_constant(qpms_tmatrix_t *t,
complex double omega,
/// Source T-matrix, real type is (const qpms_tmatrix_t*).
const void *tmatrix_orig
);
/* Fuck this, include the whole <gsl/gsl_spline.h> /* Fuck this, include the whole <gsl/gsl_spline.h>
typedef struct gsl_spline gsl_spline; // Forward declaration for the interpolator struct typedef struct gsl_spline gsl_spline; // Forward declaration for the interpolator struct
typedef struct gsl_interp_type gsl_interp_type; typedef struct gsl_interp_type gsl_interp_type;