lattices.py using now the c module
Former-commit-id: 52cecb23a8757726bcac796417ebade8242d687a
This commit is contained in:
parent
796c7d7289
commit
e2a2100b57
|
@ -6,7 +6,7 @@ nx = np.newaxis
|
||||||
import time
|
import time
|
||||||
import scipy
|
import scipy
|
||||||
import sys
|
import sys
|
||||||
from qpms_c import get_mn_y # TODO be explicit about what is imported
|
from qpms_c import get_mn_y, trans_calculator # TODO be explicit about what is imported
|
||||||
from .qpms_p import cart2sph, nelem2lMax, Ã, B̃ # TODO be explicit about what is imported
|
from .qpms_p import cart2sph, nelem2lMax, Ã, B̃ # TODO be explicit about what is imported
|
||||||
|
|
||||||
def _time_b(active = True, name = None, step = None):
|
def _time_b(active = True, name = None, step = None):
|
||||||
|
@ -83,6 +83,7 @@ class Scattering(object):
|
||||||
self.N = positions.shape[0]
|
self.N = positions.shape[0]
|
||||||
self.k_0 = k_0
|
self.k_0 = k_0
|
||||||
self.lMax = lMax if lMax else nelem2lMax(TMatrices.shape[-1])
|
self.lMax = lMax if lMax else nelem2lMax(TMatrices.shape[-1])
|
||||||
|
self.tc = trans_calculator(lMax)
|
||||||
nelem = lMax * (lMax + 2) #!
|
nelem = lMax * (lMax + 2) #!
|
||||||
self.nelem = nelem #!
|
self.nelem = nelem #!
|
||||||
self.prepared = False
|
self.prepared = False
|
||||||
|
@ -91,7 +92,7 @@ class Scattering(object):
|
||||||
def prepare(self, keep_interaction_matrix = False, verbose=False):
|
def prepare(self, keep_interaction_matrix = False, verbose=False):
|
||||||
btime = _time_b(verbose)
|
btime = _time_b(verbose)
|
||||||
if not self.prepared:
|
if not self.prepared:
|
||||||
if not self.interaction_matrix:
|
if self.interaction_matrix is None:
|
||||||
self.build_interaction_matrix(verbose=verbose)
|
self.build_interaction_matrix(verbose=verbose)
|
||||||
self.lupiv = scipy.linalg.lu_factor(self.interaction_matrix,overwrite_a = not keep_interaction_matrix)
|
self.lupiv = scipy.linalg.lu_factor(self.interaction_matrix,overwrite_a = not keep_interaction_matrix)
|
||||||
if not keep_interaction_matrix:
|
if not keep_interaction_matrix:
|
||||||
|
@ -106,6 +107,7 @@ class Scattering(object):
|
||||||
nelem = len(my)
|
nelem = len(my)
|
||||||
leftmatrix = np.zeros((N,2,nelem,N,2,nelem), dtype=complex)
|
leftmatrix = np.zeros((N,2,nelem,N,2,nelem), dtype=complex)
|
||||||
sbtime = _time_b(verbose, step = 'Calculating interparticle translation coefficients')
|
sbtime = _time_b(verbose, step = 'Calculating interparticle translation coefficients')
|
||||||
|
"""
|
||||||
for i in range(N):
|
for i in range(N):
|
||||||
for j in range(N):
|
for j in range(N):
|
||||||
for yi in range(nelem):
|
for yi in range(nelem):
|
||||||
|
@ -118,6 +120,20 @@ class Scattering(object):
|
||||||
leftmatrix[j,1,yj,i,1,yi] = a
|
leftmatrix[j,1,yj,i,1,yi] = a
|
||||||
leftmatrix[j,0,yj,i,1,yi] = b
|
leftmatrix[j,0,yj,i,1,yi] = b
|
||||||
leftmatrix[j,1,yj,i,0,yi] = b
|
leftmatrix[j,1,yj,i,0,yi] = b
|
||||||
|
"""
|
||||||
|
kdji = cart2sph(self.positions[:,nx,:] - self.positions[nx,:,:])
|
||||||
|
kdji[:,:,0] *= self.k_0
|
||||||
|
# get_AB array structure: [j,yj,i,yi]
|
||||||
|
a, b = self.tc.get_AB(my[nx,:,nx,nx],ny[nx,:,nx,nx],my[nx,nx,nx,:],ny[nx,nx,nx,:],
|
||||||
|
(kdji[:,:,0])[:,nx,:,nx], (kdji[:,:,1])[:,nx,:,nx], (kdji[:,:,2])[:,nx,:,nx],
|
||||||
|
False,self.J_scat)
|
||||||
|
mask = np.broadcast_to(np.eye(N,dtype=bool)[:,nx,:,nx],(N,nelem,N,nelem))
|
||||||
|
a[mask] = 0 # no self-translations
|
||||||
|
b[mask] = 0
|
||||||
|
leftmatrix[:,0,:,:,0,:] = a
|
||||||
|
leftmatrix[:,1,:,:,1,:] = a
|
||||||
|
leftmatrix[:,0,:,:,1,:] = b
|
||||||
|
leftmatrix[:,1,:,:,0,:] = b
|
||||||
_time_e(sbtime, verbose, step = 'Calculating interparticle translation coefficients')
|
_time_e(sbtime, verbose, step = 'Calculating interparticle translation coefficients')
|
||||||
# at this point, leftmatrix is the translation matrix
|
# at this point, leftmatrix is the translation matrix
|
||||||
n2id = np.identity(2*nelem)
|
n2id = np.identity(2*nelem)
|
||||||
|
@ -199,6 +215,7 @@ class Scattering_2D_zsym(Scattering):
|
||||||
self.my, self.ny = get_mn_y(self.lMax)
|
self.my, self.ny = get_mn_y(self.lMax)
|
||||||
self.TE_NMz = (self.my + self.ny) % 2
|
self.TE_NMz = (self.my + self.ny) % 2
|
||||||
self.TM_NMz = 1 - self.TE_NMz
|
self.TM_NMz = 1 - self.TE_NMz
|
||||||
|
self.tc = trans_calculator(lMax)
|
||||||
# TODO možnost zadávat T-matice rovnou ve zhuštěné podobě
|
# TODO možnost zadávat T-matice rovnou ve zhuštěné podobě
|
||||||
TMatrices_TE = TMatrices[...,self.TE_NMz[:,nx],self.TE_yz[:,nx],self.TE_NMz[nx,:],self.TE_yz[nx,:]]
|
TMatrices_TE = TMatrices[...,self.TE_NMz[:,nx],self.TE_yz[:,nx],self.TE_NMz[nx,:],self.TE_yz[nx,:]]
|
||||||
TMatrices_TM = TMatrices[...,self.TM_NMz[:,nx],self.TM_yz[:,nx],self.TM_NMz[nx,:],self.TM_yz[nx,:]]
|
TMatrices_TM = TMatrices[...,self.TM_NMz[:,nx],self.TM_yz[:,nx],self.TM_NMz[nx,:],self.TM_yz[nx,:]]
|
||||||
|
@ -216,13 +233,13 @@ class Scattering_2D_zsym(Scattering):
|
||||||
btime = _time_b(verbose)
|
btime = _time_b(verbose)
|
||||||
if (TE_or_TM == 0): #TE
|
if (TE_or_TM == 0): #TE
|
||||||
if not self.prepared_TE:
|
if not self.prepared_TE:
|
||||||
if not self.interaction_matrix_TE:
|
if self.interaction_matrix_TE is None:
|
||||||
self.build_interaction_matrix(0, verbose)
|
self.build_interaction_matrix(0, verbose)
|
||||||
self.lupiv_TE = scipy.linalg.lu_factor(self.interaction_matrix_TE, overwrite_a = not keep_interaction_matrix)
|
self.lupiv_TE = scipy.linalg.lu_factor(self.interaction_matrix_TE, overwrite_a = not keep_interaction_matrix)
|
||||||
self.prepared_TE = True
|
self.prepared_TE = True
|
||||||
if (TE_or_TM == 1): #TM
|
if (TE_or_TM == 1): #TM
|
||||||
if not self.prepared_TM:
|
if not self.prepared_TM:
|
||||||
if not self.interaction_matrix_TM:
|
if self.interaction_matrix_TM is None:
|
||||||
self.build_interaction_matrix(1, verbose)
|
self.build_interaction_matrix(1, verbose)
|
||||||
self.lupiv_TM = scipy.linalg.lu_factor(self.interaction_matrix_TM, overwrite_a = not keep_interaction_matrix)
|
self.lupiv_TM = scipy.linalg.lu_factor(self.interaction_matrix_TM, overwrite_a = not keep_interaction_matrix)
|
||||||
self.prepared_TM = True
|
self.prepared_TM = True
|
||||||
|
@ -249,9 +266,29 @@ class Scattering_2D_zsym(Scattering):
|
||||||
EoMl = (1,)
|
EoMl = (1,)
|
||||||
elif (TE_or_TM is None):
|
elif (TE_or_TM is None):
|
||||||
EoMl = (0,1)
|
EoMl = (0,1)
|
||||||
|
sbtime = _time_b(verbose, step = 'Calculating interparticle translation coefficients')
|
||||||
|
kdji = cart2sph(self.positions[:,nx,:] - self.positions[nx,:,:])
|
||||||
|
kdji[:,:,0] *= self.k_0
|
||||||
|
# get_AB array structure: [j,yj,i,yi]
|
||||||
|
# FIXME I could save some memory by calculating only half of these coefficients
|
||||||
|
a, b = self.tc.get_AB(my[nx,:,nx,nx],ny[nx,:,nx,nx],my[nx,nx,nx,:],ny[nx,nx,nx,:],
|
||||||
|
(kdji[:,:,0])[:,nx,:,nx], (kdji[:,:,1])[:,nx,:,nx], (kdji[:,:,2])[:,nx,:,nx],
|
||||||
|
False,self.J_scat)
|
||||||
|
mask = np.broadcast_to(np.eye(N,dtype=bool)[:,nx,:,nx],(N,nelem,N,nelem))
|
||||||
|
a[mask] = 0 # no self-translations
|
||||||
|
b[mask] = 0
|
||||||
|
print(np.isnan(np.min(a)))
|
||||||
|
_time_e(sbtime, verbose, step = 'Calculating interparticle translation coefficients')
|
||||||
for EoM in EoMl:
|
for EoM in EoMl:
|
||||||
leftmatrix = np.zeros((N,nelem,N,nelem), dtype=complex)
|
leftmatrix = np.zeros((N,nelem,N,nelem), dtype=complex)
|
||||||
sbtime = _time_b(verbose, step = 'Calculating interparticle translation coefficients, T%s part' % ('M' if EoM else 'E'))
|
y = np.arange(nelem)
|
||||||
|
yi = y[nx,nx,nx,:]
|
||||||
|
yj = y[nx,:,nx,nx]
|
||||||
|
mask = np.broadcast_to((((yi - yj) % 2) == 0),(N,nelem,N,nelem))
|
||||||
|
leftmatrix[mask] = a[mask]
|
||||||
|
mask = np.broadcast_to((((yi - yj) % 2) != 0),(N,nelem,N,nelem))
|
||||||
|
leftmatrix[mask] = b[mask]
|
||||||
|
""" # we use to calculate the AB coefficients here
|
||||||
for i in range(N):
|
for i in range(N):
|
||||||
for j in range(i):
|
for j in range(i):
|
||||||
for yi in range(nelem):
|
for yi in range(nelem):
|
||||||
|
@ -264,6 +301,7 @@ class Scattering_2D_zsym(Scattering):
|
||||||
leftmatrix[j,yj,i,yi] = tr
|
leftmatrix[j,yj,i,yi] = tr
|
||||||
leftmatrix[i,yi,j,yj] = tr if (0 == (my[yj]+my[yi]) % 2) else -tr
|
leftmatrix[i,yi,j,yj] = tr if (0 == (my[yj]+my[yi]) % 2) else -tr
|
||||||
_time_e(sbtime, verbose, step = 'Calculating interparticle translation coefficients, T%s part' % ('M' if EoM else 'E'))
|
_time_e(sbtime, verbose, step = 'Calculating interparticle translation coefficients, T%s part' % ('M' if EoM else 'E'))
|
||||||
|
"""
|
||||||
for j in range(N):
|
for j in range(N):
|
||||||
leftmatrix[j] = - np.tensordot(self.TMatrices_TM[j] if EoM else self.TMatrices_TE[j],leftmatrix[j],
|
leftmatrix[j] = - np.tensordot(self.TMatrices_TM[j] if EoM else self.TMatrices_TE[j],leftmatrix[j],
|
||||||
axes = ([-1],[0]))
|
axes = ([-1],[0]))
|
||||||
|
@ -273,6 +311,8 @@ class Scattering_2D_zsym(Scattering):
|
||||||
self.interaction_matrix_TE = leftmatrix
|
self.interaction_matrix_TE = leftmatrix
|
||||||
if EoM == 1:
|
if EoM == 1:
|
||||||
self.interaction_matrix_TM = leftmatrix
|
self.interaction_matrix_TM = leftmatrix
|
||||||
|
a = None
|
||||||
|
b = None
|
||||||
_time_e(btime, verbose)
|
_time_e(btime, verbose)
|
||||||
|
|
||||||
def scatter_partial(self, TE_or_TM, pq_0, verbose = False):
|
def scatter_partial(self, TE_or_TM, pq_0, verbose = False):
|
||||||
|
|
|
@ -5,6 +5,8 @@ import numpy as np
|
||||||
cimport numpy as np
|
cimport numpy as np
|
||||||
cimport cython
|
cimport cython
|
||||||
from cython.parallel cimport parallel, prange
|
from cython.parallel cimport parallel, prange
|
||||||
|
#cimport openmp
|
||||||
|
#openmp.omp_set_dynamic(1)
|
||||||
|
|
||||||
## Auxillary function for retrieving the "meshgrid-like" indices; inc. nmax
|
## Auxillary function for retrieving the "meshgrid-like" indices; inc. nmax
|
||||||
@cython.boundscheck(False)
|
@cython.boundscheck(False)
|
||||||
|
@ -371,10 +373,65 @@ cdef void trans_calculator_loop_E_C_DD_iiiidddii_As_lllldddbl_DD(char **args, np
|
||||||
# FIXME ERROR HANDLING!!! requires correct import and different data passed (see scipy's generated ufuncs)
|
# FIXME ERROR HANDLING!!! requires correct import and different data passed (see scipy's generated ufuncs)
|
||||||
# sf_error.check_fpe(func_name)
|
# sf_error.check_fpe(func_name)
|
||||||
|
|
||||||
|
@cython.boundscheck(False)
|
||||||
|
@cython.wraparound(False)
|
||||||
|
cdef void trans_calculator_parallel_loop_E_C_DD_iiiidddii_As_lllldddbl_DD(char **args, np.npy_intp *dims, np.npy_intp *steps, void *data) nogil:
|
||||||
|
# E stands for error value (int), C for qpms_trans_calculator*
|
||||||
|
cdef np.npy_intp i, n = dims[0]
|
||||||
|
cdef void *func = (<trans_calculator_get_X_data_t*>data)[0].cmethod
|
||||||
|
#cdef complex double (*func)(qpms_trans_calculator*, double complex *, double complex *, int, int, int, int, double, double, double, int, int) nogil = (<trans_calculator_get_X_data_t*>data)[0].cmethod
|
||||||
|
cdef qpms_trans_calculator* c = (<trans_calculator_get_X_data_t*>data)[0].c
|
||||||
|
#cdef char *func_name= <char*>(<void**>data)[1] # i am not using this, nor have I saved func_name to data
|
||||||
|
|
||||||
|
cdef char *ip0
|
||||||
|
cdef char *ip1
|
||||||
|
cdef char *ip2
|
||||||
|
cdef char *ip3
|
||||||
|
cdef char *ip4
|
||||||
|
cdef char *ip5
|
||||||
|
cdef char *ip6
|
||||||
|
cdef char *ip7
|
||||||
|
cdef char *ip8
|
||||||
|
cdef char *op0
|
||||||
|
cdef char *op1
|
||||||
|
cdef int errval
|
||||||
|
for i in prange(n): # iterating over dimensions
|
||||||
|
ip0 = args[0] + i * steps[0]
|
||||||
|
ip1 = args[1] + i * steps[1]
|
||||||
|
ip2 = args[2] + i * steps[2]
|
||||||
|
ip3 = args[3] + i * steps[3]
|
||||||
|
ip4 = args[4] + i * steps[4]
|
||||||
|
ip5 = args[5] + i * steps[5]
|
||||||
|
ip6 = args[6] + i * steps[6]
|
||||||
|
ip7 = args[7] + i * steps[7]
|
||||||
|
ip8 = args[8] + i * steps[8]
|
||||||
|
op0 = args[9] + i * steps[9]
|
||||||
|
op1 = args[10] + i * steps[10]
|
||||||
|
#errval = func(
|
||||||
|
errval = (<int(*)(qpms_trans_calculator*, double complex *, double complex *, int, int, int, int, double, double, double, int, int) nogil>func)(
|
||||||
|
c,
|
||||||
|
<cdouble *> op0,
|
||||||
|
<cdouble *> op1,
|
||||||
|
<int>(<np.npy_long*>ip0)[0],
|
||||||
|
<int>(<np.npy_long*>ip1)[0],
|
||||||
|
<int>(<np.npy_long*>ip2)[0],
|
||||||
|
<int>(<np.npy_long*>ip3)[0],
|
||||||
|
<double>(<np.npy_double*>ip4)[0],
|
||||||
|
<double>(<np.npy_double*>ip5)[0],
|
||||||
|
<double>(<np.npy_double*>ip6)[0],
|
||||||
|
<int>(<np.npy_bool*>ip7)[0],
|
||||||
|
<int>(<np.npy_long*>ip8)[0],
|
||||||
|
)
|
||||||
|
# TODO if (errval != 0): ...
|
||||||
|
# FIXME ERROR HANDLING!!! requires correct import and different data passed (see scipy's generated ufuncs)
|
||||||
|
# sf_error.check_fpe(func_name)
|
||||||
|
|
||||||
|
|
||||||
cdef np.PyUFuncGenericFunction trans_calculator_get_X_loop_funcs[1]
|
cdef np.PyUFuncGenericFunction trans_calculator_get_X_loop_funcs[1]
|
||||||
trans_calculator_get_X_loop_funcs[0] = trans_calculator_loop_D_Ciiiidddii_As_D_lllldddbl
|
trans_calculator_get_X_loop_funcs[0] = trans_calculator_loop_D_Ciiiidddii_As_D_lllldddbl
|
||||||
|
|
||||||
cdef np.PyUFuncGenericFunction trans_calculator_get_AB_loop_funcs[1]
|
cdef np.PyUFuncGenericFunction trans_calculator_get_AB_loop_funcs[1]
|
||||||
|
#trans_calculator_get_AB_loop_funcs[0] = trans_calculator_parallel_loop_E_C_DD_iiiidddii_As_lllldddbl_DD
|
||||||
trans_calculator_get_AB_loop_funcs[0] = trans_calculator_loop_E_C_DD_iiiidddii_As_lllldddbl_DD
|
trans_calculator_get_AB_loop_funcs[0] = trans_calculator_loop_E_C_DD_iiiidddii_As_lllldddbl_DD
|
||||||
cdef void *trans_calculator_get_AB_elementwise_funcs[1]
|
cdef void *trans_calculator_get_AB_elementwise_funcs[1]
|
||||||
trans_calculator_get_AB_elementwise_funcs[0] = <void *>qpms_trans_calculator_get_AB_p_ext
|
trans_calculator_get_AB_elementwise_funcs[0] = <void *>qpms_trans_calculator_get_AB_p_ext
|
||||||
|
|
|
@ -419,6 +419,10 @@ complex double qpms_trans_calculator_get_A_buf(const qpms_trans_calculator *c,
|
||||||
bool r_ge_d, qpms_bessel_t J,
|
bool r_ge_d, qpms_bessel_t J,
|
||||||
complex double *bessel_buf, double *legendre_buf) {
|
complex double *bessel_buf, double *legendre_buf) {
|
||||||
if (r_ge_d) J = QPMS_BESSEL_REGULAR;
|
if (r_ge_d) J = QPMS_BESSEL_REGULAR;
|
||||||
|
if (0 == kdlj.r && J != QPMS_BESSEL_REGULAR)
|
||||||
|
// TODO warn?
|
||||||
|
return NAN+I*NAN;
|
||||||
|
|
||||||
switch(c->normalization) {
|
switch(c->normalization) {
|
||||||
case QPMS_NORMALIZATION_TAYLOR:
|
case QPMS_NORMALIZATION_TAYLOR:
|
||||||
{
|
{
|
||||||
|
@ -451,6 +455,9 @@ complex double qpms_trans_calculator_get_B_buf(const qpms_trans_calculator *c,
|
||||||
bool r_ge_d, qpms_bessel_t J,
|
bool r_ge_d, qpms_bessel_t J,
|
||||||
complex double *bessel_buf, double *legendre_buf) {
|
complex double *bessel_buf, double *legendre_buf) {
|
||||||
if (r_ge_d) J = QPMS_BESSEL_REGULAR;
|
if (r_ge_d) J = QPMS_BESSEL_REGULAR;
|
||||||
|
if (0 == kdlj.r && J != QPMS_BESSEL_REGULAR)
|
||||||
|
// TODO warn?
|
||||||
|
return NAN+I*NAN;
|
||||||
switch(c->normalization) {
|
switch(c->normalization) {
|
||||||
case QPMS_NORMALIZATION_TAYLOR:
|
case QPMS_NORMALIZATION_TAYLOR:
|
||||||
{
|
{
|
||||||
|
@ -486,6 +493,12 @@ int qpms_trans_calculator_get_AB_buf_p(const qpms_trans_calculator *c,
|
||||||
bool r_ge_d, qpms_bessel_t J,
|
bool r_ge_d, qpms_bessel_t J,
|
||||||
complex double *bessel_buf, double *legendre_buf) {
|
complex double *bessel_buf, double *legendre_buf) {
|
||||||
if (r_ge_d) J = QPMS_BESSEL_REGULAR;
|
if (r_ge_d) J = QPMS_BESSEL_REGULAR;
|
||||||
|
if (0 == kdlj.r && J != QPMS_BESSEL_REGULAR) {
|
||||||
|
*Adest = NAN+I*NAN;
|
||||||
|
*Bdest = NAN+I*NAN;
|
||||||
|
// TODO warn? different return value?
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
switch(c->normalization) {
|
switch(c->normalization) {
|
||||||
case QPMS_NORMALIZATION_TAYLOR:
|
case QPMS_NORMALIZATION_TAYLOR:
|
||||||
{
|
{
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -23,7 +23,7 @@ qpms_c = Extension('qpms_c',
|
||||||
extra_compile_args=['-std=c99','-ggdb','-O3',
|
extra_compile_args=['-std=c99','-ggdb','-O3',
|
||||||
'-DDISABLE_NDEBUG', # uncomment to enable assertions in the modules
|
'-DDISABLE_NDEBUG', # uncomment to enable assertions in the modules
|
||||||
],
|
],
|
||||||
libraries=['gsl', 'blas'],
|
libraries=['gsl', 'blas', 'omp'],
|
||||||
runtime_library_dirs=os.environ['LD_LIBRARY_PATH'].split(':')
|
runtime_library_dirs=os.environ['LD_LIBRARY_PATH'].split(':')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue