diff --git a/qpms/qpms_c.pyx b/qpms/qpms_c.pyx index 2d6323a..e0fad03 100644 --- a/qpms/qpms_c.pyx +++ b/qpms/qpms_c.pyx @@ -1582,6 +1582,7 @@ cdef class ScatteringSystem: ar_view[pi] = self.s[0].tm[self.s[0].p[pi].tmatrix_id].spec[0].n return ar + def fullvec_poffsets(self): cdef np.ndarray[intptr_t, ndim=1] ar = np.empty((self.s[0].p_count,), dtype=np.intp) cdef intptr_t[::1] ar_view = ar @@ -1599,6 +1600,25 @@ cdef class ScatteringSystem: ar_view[pi,1] = self.s[0].p[pi].pos.y ar_view[pi,2] = self.s[0].p[pi].pos.z return ar + + def planewave_full(self, k_cart, E_cart): + if k_cart.shape != (3,) or E_cart.shape != (3,): + raise ValueError("k_cart and E_cart must be ndarrays of shape (3,)") + cdef qpms_incfield_planewave_params_t p + p.use_cartesian = 1 + p.k.cart.x = k_cart[0] + p.k.cart.y = k_cart[1] + p.k.cart.z = k_cart[2] + p.E.cart.x = E_cart[0] + p.E.cart.y = E_cart[1] + p.E.cart.z = E_cart[2] + cdef np.ndarray[np.complex_t, ndim=1] target_np = np.empty( + (self.fecv_size,), dtype=complex) + cdef cdouble[::1] target_view = target_np + qpms_scatsys_incident_field_vector_full(&target_view[0], + self.s, qpms_incfield_planewave, &p, 0) + return target_np + def tlm2uvswfi(t, l, m): ''' TODO doc diff --git a/qpms/qpms_cdefs.pxd b/qpms/qpms_cdefs.pxd index 334413f..ddc1d8d 100644 --- a/qpms/qpms_cdefs.pxd +++ b/qpms/qpms_cdefs.pxd @@ -9,6 +9,10 @@ cdef extern from "qpms_types.h": double x double y double z + cdef struct ccart3_t: + cdouble x + cdouble y + cdouble z cdef struct cart2_t: double x double y @@ -100,6 +104,19 @@ cdef extern from "qpms_error.h": qpms_dbgmsg_flags qpms_dbgmsg_enable(qpms_dbgmsg_flags types) qpms_dbgmsg_flags qpms_dbgmsg_disable(qpms_dbgmsg_flags types) +cdef extern from "vswf.h": + ctypedef qpms_errno_t (*qpms_incfield_t)(cdouble target, const qpms_vswf_set_spec_t *bspec, + const cart3_t evalpoint, const void *args, bint add) + ctypedef struct qpms_incfield_planewave_params_t: + bint use_cartesian + union k: + ccart3_t cart + csph_t sph + union E: + ccart3_t cart + csph sph + qpms_errno_t qpms_incfield_planewave(cdouble target, const qpms_vswf_set_spec_t *bspec, + const cart3_t evalpoint, const void *args, bint add) cdef extern from "indexing.h": qpms_uvswfi_t qpms_tmn2uvswfi(qpms_vswf_type_t t, qpms_m_t m, qpms_l_t n) @@ -342,6 +359,9 @@ cdef extern from "scatsystem.h": cdouble *target, const qpms_scatsys_t *ss, qpms_iri_t iri, double k) cdouble *qpms_scatsys_build_modeproblem_matrix_irrep_packed_parallelR( cdouble *target, const qpms_scatsys_t *ss, qpms_iri_t iri, double k) nogil + cdouble *qpms_scatsys_incident_field_vector_full(cdouble *target_full, + const qpms_scatsys_t *ss, qpms_incfield_t field_at_point, + const void *args, bint add) diff --git a/qpms/vswf.h b/qpms/vswf.h index 9d0e8e1..b4a6f21 100644 --- a/qpms/vswf.h +++ b/qpms/vswf.h @@ -77,7 +77,7 @@ csphvec_t qpms_eval_uvswf(const qpms_vswf_set_spec_t *setspec, // --- qpms_incfield_t instances and their arguments /// Parameter structure for qpms_incfield_planewave() -typedef struct qpms_incfield_planewane_params_t { +typedef struct qpms_incfield_planewave_params_t { bool use_cartesian; ///< If true, wave direction k and amplitude E are specified in cartesian coordinates (via k.cart, E.cart). If false, k is specified in spherical coordinates and E are specified in the corresponding geographical coordinates (via k.sph, E.sph). union { ccart3_t cart;