From 59cf2e0778ae5378786a2662ec688894a5cb0949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ne=C4=8Dada?= Date: Sun, 3 Mar 2019 00:05:24 +0000 Subject: [PATCH] Basic Python wrapper of qpms_scatsystem_t Former-commit-id: e12b21cd5219f7a995c228de8758ef58498ac987 --- qpms/qpms_c.pyx | 47 ++++++++++++++++++++++++++++++++++++++++++++- qpms/qpms_cdefs.pxd | 25 +++++++++++++++++++++--- qpms/scatsystem.h | 5 +++++ 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/qpms/qpms_c.pyx b/qpms/qpms_c.pyx index 26a3540..e64d3d3 100644 --- a/qpms/qpms_c.pyx +++ b/qpms/qpms_c.pyx @@ -8,6 +8,7 @@ cimport cython from cython.parallel cimport parallel, prange import enum + # Here will be enum and dtype definitions; maybe move these to a separate file class VSWFType(enum.IntEnum): ELECTRIC = QPMS_VSWF_ELECTRIC @@ -1223,6 +1224,9 @@ cdef class FinitePointGroup: self.G = 0 self.owns_data = False + cdef qpms_finite_group_t *rawpointer(self): + return self.G + cdef class FinitePointGroupElement: '''TODO''' cdef readonly FinitePointGroup G @@ -1286,7 +1290,48 @@ cdef class ScatteringSystem: ''' Wrapper over the C qpms_scatsys_t structure. ''' - pass + cdef list basespecs # Here we keep the references to occuring basespecs + #cdef list Tmatrices # Here we keep the references to occuring T-matrices + cdef qpms_scatsys_t *s + + def __cinit__(self, particles, FinitePointGroup sym): + '''TODO doc. + Takes the particles (which have to be a sequence of instances of Particle), + fills them together with their t-matrices to the "proto-qpms_scatsys_t" + orig and calls qpms_scatsys_apply_symmetry + (and then cleans orig) + ''' + cdef qpms_scatsys_t orig # This should be automatically init'd to 0 (CHECKME) + cdef qpms_ss_pi_t p_count = len(particles) + cdef qpms_ss_tmi_t tm_count = 0 + tmindices = dict() + tmobjs = list() + for p in particles: # find and enumerate unique t-matrices + if id(p.t) not in tmindices: + tmindices[id(p.t)] = tm_count + tmobjs.append(p.t) + tm_count += 1 + orig.tm_count = tm_count + orig.p_count = p_count + for tm in tmobjs: # create references to BaseSpec objects + self.basespecs.append(tm.spec) + try: + orig.tm = malloc(orig.tm_count * sizeof(orig.tm[0])) + if not orig.tm: raise MemoryError + orig.p = malloc(orig.p_count * sizeof(orig.p[0])) + if not orig.p: raise MemoryError + for tmi in range(tm_count): + orig.tm[tmi] = ((tmobjs[tmi])).rawpointer() + for pi in range(p_count): + orig.p[pi].pos = particles[pi].p.pos + orig.p[pi].tmatrix_id = tmindices[id(particles[pi].t)] + self.s = qpms_scatsys_apply_symmetry(&orig, sym.rawpointer()) + finally: + free(orig.tm) + free(orig.p) + + def __dealloc__(self): + qpms_scatsys_free(self.s) def tlm2uvswfi(t, l, m): ''' TODO doc diff --git a/qpms/qpms_cdefs.pxd b/qpms/qpms_cdefs.pxd index f3c3ca1..7380cb9 100644 --- a/qpms/qpms_cdefs.pxd +++ b/qpms/qpms_cdefs.pxd @@ -2,7 +2,7 @@ cimport numpy as np ctypedef double complex cdouble -from libc.stdint cimport uintptr_t +from libc.stdint cimport * cdef extern from "qpms_types.h": cdef struct cart3_t: @@ -70,6 +70,8 @@ cdef extern from "qpms_types.h": QPMS_VSWF_ELECTRIC QPMS_VSWF_MAGNETIC QPMS_VSWF_LONGITUDINAL + ctypedef int32_t qpms_ss_tmi_t + ctypedef int32_t qpms_ss_pi_t ctypedef int qpms_gmi_t ctypedef int qpms_iri_t ctypedef const char * qpms_permutation_t @@ -152,6 +154,8 @@ cdef extern from "groups.h": qpms_irot3_t *rep3d qpms_iri_t nirreps qpms_finite_group_irrep_t *irreps + qpms_finite_group_t QPMS_FINITE_GROUP_TRIVIAL + qpms_finite_group_t QPMS_FINITE_GROUP_TRIVIAL_G cdef extern from "symmetries.h": cdouble *qpms_zflip_uvswi_dense(cdouble *target, const qpms_vswf_set_spec_t *bspec) @@ -212,14 +216,29 @@ cdef extern from "scatsystem.h": struct qpms_tmatrix_t: qpms_vswf_set_spec_t *spec cdouble *m - int owns_m # FIXME in fact bool + bint owns_m # FIXME in fact bool struct qpms_particle_t: cart3_t pos const qpms_tmatrix_t *tmatrix + struct qpms_particle_tid_t: + cart3_t pos + qpms_ss_tmi_t tmatrix_id struct qpms_tmatrix_interpolator_t: const qpms_vswf_set_spec_t *bspec struct qpms_scatsys_t: - pass # TODO + qpms_tmatrix_t **tm + qpms_ss_tmi_t tm_count + qpms_particle_tid_t *p + qpms_ss_pi_t p_count + # We shouldn't need more to construct a symmetric scatsystem + qpms_scatsys_t *qpms_scatsys_apply_symmetry(const qpms_scatsys_t *orig, const qpms_finite_group_t *sym) + void qpms_scatsys_free(qpms_scatsys_t *s) + qpms_errno_t qpms_scatsys_dump(qpms_scatsys_t *ss, char *path) #NI + qpms_scatsys_t *qpms_scatsys_load(char *path) #NI + qpms_tmatrix_isclose(const qpms_tmatrix_t *A, const qpms_tmatrix_t *B, + const double rtol, const double atol) + + diff --git a/qpms/scatsystem.h b/qpms/scatsystem.h index 491c96f..208113e 100644 --- a/qpms/scatsystem.h +++ b/qpms/scatsystem.h @@ -290,6 +290,11 @@ typedef struct qpms_scatsys_t { /// Creates a new scatsys by applying a symmetry group, copying particles if needed. /** In fact, it copies everything except the vswf set specs, so keep them alive until scatsys is destroyed. + * The following fields must be filled: + * orig->tm + * orig->tm_count + * orig->p + * orig->p_count */ qpms_scatsys_t *qpms_scatsys_apply_symmetry(const qpms_scatsys_t *orig, const struct qpms_finite_group_t *sym); /// Destroys the result of qpms_scatsys_apply_symmetry or qpms_scatsys_load.