source: sasmodels/coreshellcylcode.py @ 5378e40

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 5378e40 was 5378e40, checked in by Helen Park <HMP1@…>, 10 years ago

Initial commit

  • Property mode set to 100644
File size: 3.7 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import numpy as np
5import math
6import pyopencl as cl
7from weights import GaussianDispersion
8
9class GpuCoreShellCylinder(object):
10    PARS = {'scale':1, 'radius':1, 'thickness':1, 'length':1, 'core_sld':1e-6, 'shell_sld':1e-6, 'solvent_sld':0,
11            'background':0, 'axis_theta':0, 'axis_phi':0}
12    PD_PARS = ['radius', 'length', 'thickness', 'axis_phi', 'axis_theta']
13
14    def __init__(self, qx, qy):
15        self.qx = np.asarray(qx, np.float32)
16        self.qy = np.asarray(qy, np.float32)
17        #create context, queue, and build program
18        self.ctx = cl.create_some_context()
19        self.queue = cl.CommandQueue(self.ctx)
20        self.prg = cl.Program(self.ctx, open('Kernel-CoreShellCylinder.cpp').read()).build()
21
22        #buffers
23        mf = cl.mem_flags
24        self.qx_b = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=self.qx)
25        self.qy_b = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=self.qy)
26        self.res_b = cl.Buffer(self.ctx, mf.WRITE_ONLY, qx.nbytes)
27        self.res = np.empty_like(self.qx)
28
29    def eval(self, pars):
30
31        radius, length, thickness, axis_phi, axis_theta = [GaussianDispersion(int(pars[base+'_pd_n']), pars[base+'_pd'], pars[base+'_pd_nsigma'])
32                                     for base in GpuCoreShellCylinder.PD_PARS]
33
34        radius.value, radius.weight = radius.get_weights(pars['radius'], 0, 1000, True)
35        length.value, length.weight = length.get_weights(pars['length'], 0, 1000, True)
36        thickness.value, thickness.weight = thickness.get_weights(pars['thickness'], 0, 1000, True)
37        axis_phi.value, axis_phi.weight = axis_phi.get_weights(pars['axis_phi'], -90, 180, False)
38        axis_theta.value, axis_theta.weight = axis_theta.get_weights(pars['axis_theta'], -90, 180, False)
39
40        sum, norm, norm_vol, vol = 0.0, 0.0, 0.0, 0.0
41        size = len(axis_theta.weight)
42
43        for i in xrange(len(radius.weight)):
44            for j in xrange(len(length.weight)):
45                for k in xrange(len(axis_theta.weight)):
46                    for l in xrange(len(axis_phi.weight)):
47                        for f in xrange(len(thickness.weight)):
48
49                            self.prg.CoreShellCylinderKernel(self.queue, self.qx.shape, None, self.qx_b, self.qy_b, self.res_b,
50                                    np.float32(axis_theta.value[k]), np.float32(axis_phi.value[l]), np.float32(thickness.value[f]),
51                                    np.float32(length.value[j]), np.float32(radius.value[i]), np.float32(pars['scale']),
52                                    np.float32(radius.weight[i]), np.float32(length.weight[j]), np.float32(thickness.weight[f]),
53                                    np.float32(axis_theta.weight[k]), np.float32(axis_phi.weight[l]), np.float32(pars['core_sld']),
54                                    np.float32(pars['shell_sld']), np.float32(pars['solvent_sld']),np.uint32(size),
55                                    np.uint32(self.qx.size))
56                            cl.enqueue_copy(self.queue, self.res, self.res_b)
57
58                            sum += self.res
59                            vol += radius.weight[i]*length.weight[j]*thickness.weight[f]*pow(radius.value[i]+thickness.value[f],2)\
60                                   *(length.value[j]+2.0*thickness.value[f])
61                            norm_vol += radius.weight[i]*length.weight[j]*thickness.weight[k]
62                            norm += radius.weight[i]*length.weight[j]*thickness.weight[f]*axis_theta.weight[k]\
63                                    *axis_phi.weight[l]
64
65        if size>1:
66            norm /= math.asin(1.0)
67        if vol != 0.0 and norm_vol != 0.0:
68            sum *= norm_vol/vol
69
70        return sum/norm + pars['background']
Note: See TracBrowser for help on using the repository browser.