Пример #1
0
class ExampleScene(TracerScene):
    source_y = t_api.Range(0., 5., 2.)
    source_z = t_api.Range(0., 5., 1.)

    def __init__(self):
        # The energy bundle we'll use for now:
        nrm = 1/(N.sqrt(2))
        direct = N.c_[[0,-nrm, nrm],[0,0,-1]]
        position = N.tile(N.c_[[0, self.source_y, self.source_z]], (1, 2))
        self.bund = RayBundle(vertices=position, directions=direct, energy=N.r_[1, 1])

        # The assembly for ray tracing:
        rot1 = N.dot(G.rotx(N.pi/4)[:3,:3], G.roty(N.pi)[:3,:3])
        surf1 = rect_one_sided_mirror(width=10, height=10)
        surf1.set_rotation(rot1)
        surf2 = rect_one_sided_mirror(width=10, height=10)
        self.assembly = Assembly(objects=[surf1, surf2])

        TracerScene.__init__(self, self.assembly, self.bund)

    @t_api.on_trait_change('_scene.activated')
    def initialize_camere(self):
        self._scene.mlab.view(0, -90)
        self._scene.mlab.roll(0)

    @t_api.on_trait_change('source_y, source_z')
    def bundle_move(self):
        position = N.tile(N.c_[[0, self.source_y, self.source_z]], (1, 2))
        self.bund.set_vertices(position)
        self.plot_ray_trace()

    view = tui.View(
        tui.Item('_scene', editor=SceneEditor(scene_class=MayaviScene),
            height=400, width=300, show_label=False),
        tui.HGroup('-', 'source_y', 'source_z'))
Пример #2
0
class TestTraceProtocol1(unittest.TestCase):
    """ 
    Tests intersect_ray and the bundle driver with a single flat surface, not rotated, with 
    a single interation 
    """
    def setUp(self):
        dir = N.array([[1,1,-1],[-1,1,-1],[-1,-1,-1],[1,-1,-1]]).T/math.sqrt(3)
        position = N.c_[[0,0,1],[1,-1,1],[1,1,1],[-1,1,1]]
        self._bund = RayBundle(position, dir, energy=N.ones(4))
        
        self.assembly = Assembly()
        object = AssembledObject()
        object.add_surface(Surface(FlatGeometryManager(), opt.perfect_mirror))
        self.assembly.add_object(object)
        self.engine = TracerEngine(self.assembly)
        
    def test_intersect_ray1(self):
        surfaces = self.assembly.get_surfaces()
        objects = self.assembly.get_objects()
        surfs_per_obj = [len(obj.get_surfaces()) for obj in objects]
        surf_ownership = N.repeat(N.arange(len(objects)), surfs_per_obj)
        ray_ownership = -1*N.ones(self._bund.get_num_rays())
        surfs_relevancy = N.ones((len(surfaces), self._bund.get_num_rays()), dtype=N.bool)
        
        params = self.engine.intersect_ray(self._bund, surfaces, objects, \
            surf_ownership, ray_ownership, surfs_relevancy)[0]
        self.failUnless(params.all())

    def test_ray_tracer(self):
        """Ray tracer after one iteration returns what the surface would have"""
        params = self.engine.ray_tracer(self._bund,1,.05)[0]
        correct_pts = N.zeros((3,4))
        correct_pts[:2,0] = 1
        
        N.testing.assert_array_almost_equal(params, correct_pts)
Пример #3
0
class TestTraceProtocol2(unittest.TestCase):
    """
    Tests intersect_ray with a flat surface rotated around the x axis 45 degrees
    """
    def setUp(self):
        ns = -1 / N.sqrt(2)
        dir = N.c_[[0, 0, 1], [0, 0, -1], [0, ns, ns]]
        position = N.c_[[0, 0, 1], [0, 1, 2], [0, 0, 1]]
        self._bund = RayBundle(position, dir, energy=N.ones(3))

    def test_intersect_ray2(self):
        rot = general_axis_rotation([1, 0, 0], N.pi / 4)
        surface = Surface(FlatGeometryManager(),
                          opt.perfect_mirror,
                          rotation=rot)
        assembly = Assembly()
        object = AssembledObject()
        object.add_surface(surface)
        assembly.add_object(object)

        engine = TracerEngine(assembly)
        surfaces = assembly.get_surfaces()
        objects = assembly.get_objects()
        surfs_per_obj = [len(obj.get_surfaces()) for obj in objects]
        surf_ownership = N.repeat(N.arange(len(objects)), surfs_per_obj)
        ray_ownership = -1 * N.ones(self._bund.get_num_rays())
        surfs_relevancy = N.ones((len(surfaces), self._bund.get_num_rays()),
                                 dtype=N.bool)

        params = engine.intersect_ray(self._bund, surfaces, objects, \
            surf_ownership, ray_ownership, surfs_relevancy)[0]
        correct_params = N.array([[False, True, False]])

        N.testing.assert_array_almost_equal(params, correct_params)
Пример #4
0
    def setUp(self):
        surface1 = Surface(HemisphereGM(2.),
                           opt.perfect_mirror,
                           rotation=general_axis_rotation(
                               N.r_[1, 0, 0], N.pi / 2.))
        surface2 = Surface(HemisphereGM(2.),
                           opt.perfect_mirror,
                           location=N.array([0, -2, 0]),
                           rotation=general_axis_rotation(
                               N.r_[1, 0, 0], -N.pi / 2.))

        self._bund = RayBundle()
        self._bund.set_directions(N.c_[[0, 1, 0]])
        self._bund.set_vertices(N.c_[[0, -1, 0]])
        self._bund.set_energy(N.r_[[1]])
        self._bund.set_ref_index(N.r_[[1]])

        assembly = Assembly()
        object1 = AssembledObject()
        object2 = AssembledObject()
        object1.add_surface(surface1)
        object2.add_surface(surface2)
        assembly.add_object(object1)
        assembly.add_object(object2)

        self.engine = TracerEngine(assembly)
Пример #5
0
    def test_up_down(self):
        """Rays coming from below are absorbed, from above reflected"""
        going_down = N.c_[[1, 1, -1], [-1, 1, -1], [-1, -1, -1], [1, -1, -1]] / N.sqrt(3)
        going_up = going_down.copy()
        going_up[2] = 1 / N.sqrt(3)
        
        pos_up = N.c_[[0,0,1], [1,-1,1], [1,1,1], [-1,1,1]]
        pos_down = pos_up.copy()
        pos_down[2] = -1

        bund = RayBundle()
        bund.set_directions(N.hstack((going_down, going_up)))
        bund.set_vertices(N.hstack((pos_up, pos_down)))
        bund.set_energy(N.tile(100, 8))
        bund.set_ref_index(N.tile(1, 8))
        
        gm = FlatGeometryManager()
        prm = gm.find_intersections(N.eye(4), bund)
        absref = optics_callables.AbsorberReflector(0.)
        selector = N.arange(8)
        gm.select_rays(selector)
        outg = absref(gm, bund, selector)
        
        e = outg.get_energy()
        N.testing.assert_array_equal(e[:4], 100)
        N.testing.assert_array_equal(e[4:], 0)
Пример #6
0
class TestTraceProtocol5(unittest.TestCase):
    """
    Tests a spherical surface
    """
    def setUp(self):
        surface = Surface(HemisphereGM(1.),
                          opt.perfect_mirror,
                          rotation=general_axis_rotation(N.r_[1, 0, 0], N.pi))
        self._bund = RayBundle(energy=N.ones(3))
        self._bund.set_directions(N.c_[[0, 1, 0], [0, 1, 0], [0, -1, 0]])
        self._bund.set_vertices(N.c_[[0, -2., 0.001], [0, 0, 0.001],
                                     [0, 2, 0.001]])

        assembly = Assembly()
        object = AssembledObject()
        object.add_surface(surface)
        assembly.add_object(object)

        self.engine = TracerEngine(assembly)

    def test_ray_tracer1(self):
        params = self.engine.ray_tracer(self._bund, 1, .05)[0]
        correct_params = N.c_[[0, -1, 0], [0, 1, 0], [0, 1, 0]]

        N.testing.assert_array_almost_equal(params, correct_params, decimal=3)
Пример #7
0
def regular_square_bundle(num_rays, center, direction, width):
	"""
	Generate a ray bundles whose rays are equally spaced along a square grid,
	and all pointing in the same direction.
	
	Arguments:
	num_rays - number of rays to generate.
	center - a column 3-array with the 3D coordinate of the disk's center
	direction - a 1D 3-array with the unit direction vector for the bundle.
	width - of the square of starting points.
	
	Returns: 
	A RayBundle object with the above charachteristics set.
	"""
	rot = rotation_to_z(direction)
	directions = N.tile(direction[:,None], (1, num_rays))
	range = N.s_[-width:width:float(2*width)/N.sqrt(num_rays)]
	xs, ys = N.mgrid[range, range]
	vertices_local = N.array([xs.flatten(),  ys.flatten(),  N.zeros(len(xs.flatten()))])
	vertices_global = N.dot(rot,  vertices_local)

	rayb = RayBundle()
	rayb.set_vertices(vertices_global + center)
	rayb.set_directions(directions)
	return rayb
Пример #8
0
def edge_rays_bundle(num_rays,
                     center,
                     direction,
                     radius,
                     ang_range,
                     flux=None,
                     radius_in=0.):

    radius = float(radius)
    radius_in = float(radius_in)
    a = edge_rays_directions(num_rays, ang_range)

    # Rotate to a frame in which <direction> is Z:
    perp_rot = rotation_to_z(direction)
    directions = N.sum(perp_rot[..., None] * a[None, ...], axis=1)
    # Locations:
    # See [1]
    xi1 = random.uniform(size=num_rays)
    thetas = random.uniform(high=2. * N.pi, size=num_rays)
    rs = N.sqrt(radius_in**2. + xi1 * (radius**2. - radius_in**2.))
    xs = rs * N.cos(thetas)
    ys = rs * N.sin(thetas)

    # Rotate locations to the plane defined by <direction>:
    vertices_local = N.vstack((xs, ys, N.zeros(num_rays)))
    vertices_global = N.dot(perp_rot, vertices_local)

    rayb = RayBundle(vertices=vertices_global + center, directions=directions)
    if flux != None:
        rayb.set_energy(N.pi * (radius**2. - radius_in**2.) / num_rays * flux *
                        N.ones(num_rays))
    return rayb
Пример #9
0
class TestParabolicDish(unittest.TestCase):
    def setUp(self):
        pos = N.zeros((3,4))
        pos[0] = N.r_[0, 0.5, 2, -2]
        pos[2] = 2.
        dir = N.tile(N.c_[[0,0,-1]], (1,4))

        self.bund = RayBundle()
        self.bund.set_vertices(pos)
        self.bund.set_directions(dir)

        self.surf = Surface(ParabolicDishGM(2., 1.), opt.perfect_mirror)
    
    def test_selection_at_origin(self):
        """Simple dish rejects missing rays"""
        misses = N.isinf(self.surf.register_incoming(self.bund))
        N.testing.assert_array_equal(misses, N.r_[False, False, True, True])
    
    def test_transformed(self):
        """Translated and rotated dish rejects missing rays"""
        trans = generate_transform(N.r_[1., 0., 0.], N.pi/4., N.c_[[0., 0., 1.]])
        
        self.surf.transform_frame(trans)
        misses = N.isinf(self.surf.register_incoming(self.bund))
        N.testing.assert_array_equal(misses, N.r_[False, False, True, True])
    
    def test_mesh(self):
        """Parabolic dish mesh looks OK"""
        p = ParabolicDishGM(5, 3)
        x, y, z = p.mesh(5)
        
        N.testing.assert_array_almost_equal(z, p.a*(x**2 + y**2))
        self.failIf(N.any(x**2 + y**2 > 6.25))
Пример #10
0
class TestTraceProtocol2(unittest.TestCase):
    """
    Tests intersect_ray with a flat surface rotated around the x axis 45 degrees
    """
    def setUp(self):
        ns = -1/N.sqrt(2)
        dir = N.c_[[0,0,1],[0,0,-1],[0,ns,ns]]
        position = N.c_[[0,0,1],[0,1,2],[0,0,1]]
        self._bund = RayBundle(position, dir, energy=N.ones(3))
        
    def test_intersect_ray2(self):
        rot = general_axis_rotation([1,0,0],N.pi/4)
        surface = Surface(FlatGeometryManager(), opt.perfect_mirror, rotation=rot)
        assembly = Assembly()
        object = AssembledObject()
        object.add_surface(surface)
        assembly.add_object(object)
        
        engine = TracerEngine(assembly)
        surfaces = assembly.get_surfaces()
        objects = assembly.get_objects()
        surfs_per_obj = [len(obj.get_surfaces()) for obj in objects]
        surf_ownership = N.repeat(N.arange(len(objects)), surfs_per_obj)
        ray_ownership = -1*N.ones(self._bund.get_num_rays())
        surfs_relevancy = N.ones((len(surfaces), self._bund.get_num_rays()), dtype=N.bool)
        
        params = engine.intersect_ray(self._bund, surfaces, objects, \
            surf_ownership, ray_ownership, surfs_relevancy)[0]
        correct_params = N.array([[False, True, False]])

        N.testing.assert_array_almost_equal(params, correct_params)
Пример #11
0
def edge_rays_bundle(num_rays,  center,  direction,  radius, ang_range, flux=None, radius_in=0.):

	radius = float(radius)
	radius_in = float(radius_in)
	a = edge_rays_directions(num_rays, ang_range)
		
	# Rotate to a frame in which <direction> is Z:
	perp_rot = rotation_to_z(direction)
	directions = N.sum(perp_rot[...,None] * a[None,...], axis=1)
	# Locations:
	# See [1]
	xi1 = random.uniform(size=num_rays)
	thetas = random.uniform(high=2.*N.pi, size=num_rays)
	rs = N.sqrt(radius_in**2.+xi1*(radius**2.-radius_in**2.))
	xs = rs * N.cos(thetas)
	ys = rs * N.sin(thetas)

	# Rotate locations to the plane defined by <direction>:
	vertices_local = N.vstack((xs, ys, N.zeros(num_rays)))
	vertices_global = N.dot(perp_rot, vertices_local)

	rayb = RayBundle(vertices=vertices_global + center, directions=directions)
	if flux != None:
		rayb.set_energy(N.pi*(radius**2.-radius_in**2.)/num_rays*flux*N.ones(num_rays))
	return rayb
Пример #12
0
class TestInterface(unittest.TestCase):
    def setUp(self):
        self.num_rays = 10
        dir = N.tile(N.c_[[0, 0, -1]], (1, self.num_rays))
        theta = N.linspace(0, 2*N.pi, self.num_rays, endpoint=False)
        position = N.vstack((N.cos(theta), N.sin(theta), N.ones(self.num_rays)))
        
        self._bund = RayBundle(position, dir)
        
        # The boundary is positioned to create a bottom hemisphere.
        boundary = BoundarySphere(radius=4., location=N.r_[0., 0., -4*N.sqrt(3)/2.])
        self.gm = CutSphereGM(2., boundary)
        self.prm = self.gm.find_intersections(N.eye(4), self._bund)
    
    def test_find_intersections(self):
        """The correct parametric locations are found for cut sphere geometry"""
        self.failUnlessEqual(self.prm.shape, (self.num_rays,))
        N.testing.assert_array_almost_equal(self.prm, 1 + 2*N.sin(N.pi/3))
    
    def test_get_normals(self):
        """Cut sphere surface returns center-pointing normals"""
        self.gm.select_rays(N.arange(self.num_rays))
        n = self.gm.get_normals()
        N.testing.assert_array_almost_equal(n[-1,0], n[-1,1:])
        N.testing.assert_array_almost_equal(self._bund.get_vertices()[:2],
            -n[:2]/N.sqrt((n[:2]**2).sum(axis=0)))
    
    def test_inters_points_global(self):
        """Cut sphere returns correct intersections"""
        self.gm.select_rays(N.arange(self.num_rays))
        pts = self.gm.get_intersection_points_global()
        N.testing.assert_array_equal(pts[:2], self._bund.get_vertices()[:2])
        N.testing.assert_array_almost_equal(pts[2], -2*N.sin(N.pi/3))
Пример #13
0
class TestParabolicDish(unittest.TestCase):
    def setUp(self):
        pos = N.zeros((3, 4))
        pos[0] = N.r_[0, 0.5, 2, -2]
        pos[2] = 2.
        dir = N.tile(N.c_[[0, 0, -1]], (1, 4))

        self.bund = RayBundle()
        self.bund.set_vertices(pos)
        self.bund.set_directions(dir)

        self.surf = Surface(ParabolicDishGM(2., 1.), opt.perfect_mirror)

    def test_selection_at_origin(self):
        """Simple dish rejects missing rays"""
        misses = N.isinf(self.surf.register_incoming(self.bund))
        N.testing.assert_array_equal(misses, N.r_[False, False, True, True])

    def test_transformed(self):
        """Translated and rotated dish rejects missing rays"""
        trans = generate_transform(N.r_[1., 0., 0.], N.pi / 4.,
                                   N.c_[[0., 0., 1.]])

        self.surf.transform_frame(trans)
        misses = N.isinf(self.surf.register_incoming(self.bund))
        N.testing.assert_array_equal(misses, N.r_[False, False, True, True])

    def test_mesh(self):
        """Parabolic dish mesh looks OK"""
        p = ParabolicDishGM(5, 3)
        x, y, z = p.mesh(5)

        N.testing.assert_array_almost_equal(z, p.a * (x**2 + y**2))
        self.failIf(N.any(x**2 + y**2 > 6.25))
Пример #14
0
def rect_ray_bundle(num_rays,
                    center,
                    direction,
                    x,
                    y,
                    sunshape,
                    ang_rang,
                    flux=None,
                    BUIE=None):
    '''
    generate a rectancular ray bundle for different sunshape options

    Arguments:
    num_rays - number of rays to generate
    center - a column 3-array with the 3D coordinate of the ray bundle's center 
    direction - a 1D 3-array with the unit average direction vector for the bundle.
    x - width of the rectangular ray bundle
    y - height of the rectangular ray bundle
    sunshape - str, 'pillbox', 'Gaussian','Buie' or 'collimated'
    ang_rang - the angular width of the solar disk (pillbox), sigma (gaussian) or CSR (Buie sunshape)
    flux - if not None, the ray bundle's energy is set such that each ray has
        an equal amount of energy, and the total energy is flux*pi*radius**2

    Returns:
    A RayBundle object with the above characteristics set.
    '''
    if sunshape == 'pillbox':
        a = pillbox_sunshape_directions(num_rays, ang_rang)
    elif sunshape == 'gaussian':
        a = gaussian_sunshape_directions(num_rays, ang_rang)
    elif sunshape == 'buie':
        a = buie_sunshape_directions(num_rays, BUIE.sample, BUIE.FI)
    elif sunshape == 'collimated':
        a = collimated_directions(num_rays)

    # making sure the rect bundle can cover the whole region of interest
    x *= 1.2
    y *= 1.2

    # Rotate to a frame in which <direction> is Z:
    perp_rot = rotation_to_z(direction)
    directions = N.sum(perp_rot[..., None] * a[None, ...], axis=1)

    # Locations:
    # See [1]
    xs = N.random.uniform(low=-x / 2., high=x / 2., size=num_rays)
    ys = N.random.uniform(low=-y / 2., high=y / 2., size=num_rays)

    # Rotate locations to the plane defined by <direction>:
    vertices_local = N.vstack((xs, ys, N.zeros(num_rays)))
    vertices_global = N.dot(perp_rot, vertices_local)

    rayb = RayBundle(vertices=vertices_global + center, directions=directions)

    if flux != None:
        rayb.set_energy(x * y / num_rays * flux * N.ones(num_rays))

    return rayb
Пример #15
0
 def runTest(self):
     pos = N.array([[0, 1.5], [0, -1.5], [1, 0], [-1, 0], [0.1, 0.1], [-0.1, 0.6]])
     bund = RayBundle()
     bund.set_vertices(N.vstack((pos.T, N.ones(pos.shape[0]))))
     bund.set_directions(N.tile(N.c_[[0,0,-1]], (1,6)))
     surf = Surface(HexagonalParabolicDishGM(2., 1.), opt.perfect_mirror)
     
     misses = N.isinf(surf.register_incoming(bund))
     N.testing.assert_array_equal(misses, N.r_[True, True, True, True, False, False])
Пример #16
0
def triangular_bundle(num_rays,
                      A,
                      AB,
                      AC,
                      direction,
                      ang_range=N.pi / 2.,
                      flux=None,
                      procs=1):
    """
	Triangular ray-casting surface anchored on the point A.
	Arguments:
	- num_rays: the number of rays 
	- A: The first summit of the triangle and its anchor point.
	- AB and AC the vertices of the sides of the triangle in its plane of reference.
	- direction: The direction at which the source is pointing
	- ang_range: the angular range of the rays emitted by the source

	Returns: 
	- A ray bundle object for tracing
	"""
    # Triangle ray vertices:
    # Declare random numbers:
    r1 = N.vstack(N.random.uniform(size=num_rays))
    r2 = N.vstack(N.random.uniform(size=num_rays))
    # Define points in a local referential where A is at [0,0] on a z=0 plane.
    sqrtr1 = N.sqrt(r1)
    Plocs = sqrtr1 * (1. -
                      r2) * AB + r2 * sqrtr1 * AC  # Triangle point picking

    vertices_local = N.array([Plocs[:, 0], Plocs[:, 1], N.zeros(num_rays)])

    # Bring everything back to the global referential:
    rot = rotation_to_z(direction)
    vertices_global = N.dot(rot, vertices_local) + N.vstack(A)

    # Local referential directions:
    a = pillbox_sunshape_directions(num_rays, ang_range)
    # Rotate to a frame in which <direction> is Z:
    directions = N.sum(rot[..., None] * a[None, ...], axis=1)

    rayb = RayBundle()

    rayb.set_vertices(vertices_global)
    rayb.set_directions(directions)

    l1 = N.sqrt(N.sum(AB**2))
    l2 = N.sqrt(N.sum(AC**2))
    l3 = N.sqrt(N.sum((-AB + AC)**2))
    s = (l1 + l2 + l3) / 2.
    area = N.sqrt(s * (s - l1) * (s - l2) * (s - l3))
    if flux != None:
        rayb.set_energy(N.ones(num_rays) * flux * area / float(num_rays))
    else:
        rayb.set_energy(N.ones(num_rays) / float(num_rays) / procs)

    return rayb
Пример #17
0
    def setUp(self):
        dir = N.c_[[0., 0, -1], [0, 1, -1], [0, 11, -2], [0, 1, 0]]
        dir /= N.sqrt(N.sum(dir**2, axis=0))
        position = N.c_[[0., 0, 1], [0, -1, 1], [0, -11, 2], [0, 1, 1]]

        bund = RayBundle()
        bund.set_vertices(position)
        bund.set_directions(dir)
        self.bund = bund
        self.correct = N.r_[1., N.sqrt(2), N.sqrt(11**2 + 4)]
Пример #18
0
    def setUp(self):
        self.num_rays = 10
        dir = N.tile(N.c_[[0, 0, -1]], (1, self.num_rays))
        theta = N.linspace(0, 2 * N.pi, self.num_rays, endpoint=False)
        position = N.vstack(
            (N.cos(theta), N.sin(theta), N.ones(self.num_rays)))
        self._bund = RayBundle(position, dir)

        self.gm = HemisphereGM(radius=2.)
        self.prm = self.gm.find_intersections(N.eye(4), self._bund)
Пример #19
0
    def test_up_down(self):
        """Rays coming from below are absorbed, from above reflected"""
        going_down = N.c_[[1, 1, -1], [-1, 1, -1], [-1, -1, -1], [1, -1, -1]] / N.sqrt(3)
        going_up = going_down.copy()
        going_up[2] = 1 / N.sqrt(3)
        
        pos_up = N.c_[[0,0,1], [1,-1,1], [1,1,1], [-1,1,1]]
        pos_down = pos_up.copy()
        pos_down[2] = -1

        bund = RayBundle()
        bund.set_directions(N.hstack((going_down, going_up)))
        bund.set_vertices(N.hstack((pos_up, pos_down)))
        bund.set_energy(N.tile(100, 8))
        bund.set_ref_index(N.tile(1, 8))
        
        gm = FlatGeometryManager()
        prm = gm.find_intersections(N.eye(4), bund)
        absref = optics_callables.AbsorberReflector(0.)
        selector = N.arange(8)
        gm.select_rays(selector)
        outg = absref(gm, bund, selector)
        
        e = outg.get_energy()
        N.testing.assert_array_equal(e[:4], 100)
        N.testing.assert_array_equal(e[4:], 0)
Пример #20
0
    def setUp(self):
        pos = N.zeros((3, 4))
        pos[0] = N.r_[0, 0.5, 2, -2]
        pos[2] = 2.
        dir = N.tile(N.c_[[0, 0, -1]], (1, 4))

        self.bund = RayBundle()
        self.bund.set_vertices(pos)
        self.bund.set_directions(dir)

        self.surf = Surface(ParabolicDishGM(2., 1.), opt.perfect_mirror)
Пример #21
0
    def setUp(self):
        dir = N.array([[1, 1, -1], [-1, 1, -1], [-1, -1, -1], [1, -1, -1]
                       ]).T / math.sqrt(3)
        position = N.c_[[0, 0, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1]]
        self._bund = RayBundle(position, dir, energy=N.ones(4))

        self.assembly = Assembly()
        object = AssembledObject()
        object.add_surface(Surface(FlatGeometryManager(), opt.perfect_mirror))
        self.assembly.add_object(object)
        self.engine = TracerEngine(self.assembly)
Пример #22
0
    def setUp(self):
        self.num_rays = 10
        dir = N.tile(N.c_[[0, 0, -1]], (1, self.num_rays))
        theta = N.linspace(0, 2*N.pi, self.num_rays, endpoint=False)
        position = N.vstack((N.cos(theta), N.sin(theta), N.ones(self.num_rays)))
        
        self._bund = RayBundle()
        self._bund.set_vertices(position)
        self._bund.set_directions(dir)

        self.gm = Paraboloid(a=5., b=5.)
        self.prm = self.gm.find_intersections(N.eye(4), self._bund)
Пример #23
0
def pillbox_rect_bundle(num_rays,
                        center,
                        direction,
                        x,
                        y,
                        ang_rang,
                        flux=None):
    '''
    generate a rectancular ray bundle for pillbox sunshape

    Arguments:
    num_rays - number of rays to generate
    center - a column 3-array with the 3D coordinate of the ray bundle's center 
    direction - a 1D 3-array with the unit average direction vector for the bundle.
    x - width of the rectangular ray bundle
    y - height of the rectangular ray bundle
    ang_rang - the angular width of the solar disk
    flux - if not None, the ray bundle's energy is set such that each ray has
        an equal amount of energy, and the total energy is flux*pi*radius**2

    Returns:
    A RayBundle object with the above characteristics set.
    '''

    a = pillbox_sunshape_directions(num_rays, ang_rang)
    x *= 1.2
    y *= 1.2

    # Rotate to a frame in which <direction> is Z:
    perp_rot = rotation_to_z(direction)
    directions = N.sum(perp_rot[..., None] * a[None, ...], axis=1)

    # Locations:
    # See [1]
    xs = N.random.uniform(low=-x / 2., high=x / 2., size=num_rays)
    ys = N.random.uniform(low=-y / 2., high=y / 2., size=num_rays)

    #if (direction == N.array([0,0,-1])).all():
    #    xs, ys = ys, xs

    # Rotate locations to the plane defined by <direction>:
    vertices_local = N.vstack((xs, ys, N.zeros(num_rays)))
    vertices_global = N.dot(perp_rot, vertices_local)

    #dirct=N.vstack((-N.ones(num_rays)*direction[0],-N.ones(num_rays)*direction[1],-N.ones(num_rays)*direction[2]))
    #vertices_global=vertices_local+dirct*100.

    rayb = RayBundle(vertices=vertices_global + center, directions=directions)

    if flux != None:
        rayb.set_energy(x * y / num_rays * flux * N.ones(num_rays))

    return rayb
Пример #24
0
def pillbox_effective_rays(num_rays, X, Y, Z, hits, direction, A_source,
                           ang_rang, DNI):
    '''
    Generate a ray bundle according to Buie et al.: "Sunshape distributions for terrestrial simulations." Solar Energy 74 (2003) 113-122 (DOI: 10.1016/S0038-092X(03)00125-7).

    *the ray source just cover each individule mirror	

    Arguments:
    num_rays - number of rays over one heliostat, therefore total num of rays is num_rays*num_helios
    direction - (1,3)direction of the normal to the source disc.
    vertices - (3,n) array vertices of each ray
    energy - float - energy of each ray , W
    DNI - Direct normal irradiantion W/m2

    Returns:
    A raybundle object with the above characteristics set.
    '''

    total_rays = num_rays * N.sum(hits)

    a = pillbox_sunshape_directions(total_rays, ang_rang)
    # Rotate to a frame in which <direction> is Z:
    perp_rot = rotation_to_z(direction)
    directions = N.sum(perp_rot[..., None] * a[None, ...], axis=1)

    Xs = N.array([])
    Ys = N.array([])
    Zs = N.array([])

    #X,Y=N.meshgrid(X,Y)

    for i in xrange(len(hits)):
        for j in xrange(len(hits[i])):
            if hits[i, j] == 1:
                xs = N.random.uniform(low=X[i], high=X[i + 1], size=num_rays)
                ys = N.random.uniform(low=Y[j], high=Y[j + 1], size=num_rays)
                zs = Z * N.ones(num_rays)
                Xs = N.append(Xs, xs)
                Ys = N.append(Ys, ys)
                Zs = N.append(Zs, zs)

    vertices = N.vstack((Xs, Ys, Zs))

    energy = N.ones(total_rays) * DNI * A_source / float(total_rays)

    rayb = RayBundle(vertices=vertices, directions=directions)
    if DNI != None:
        rayb.set_energy(energy)

    print total_rays

    return rayb
Пример #25
0
    def setUp(self):
        self.mirror = rect_one_sided_mirror(1.5, 1.5, 0.9)

        pos = N.zeros((3, 8))
        pos[0] = N.tile(N.r_[0, 0.5, 2, -2], 2)
        pos[2] = N.repeat(N.r_[1, -1], 4)
        dir = N.zeros((3, 8))
        dir[2] = N.repeat(N.r_[-1, 1], 4)

        self.bund = RayBundle()
        self.bund.set_vertices(pos)
        self.bund.set_directions(dir)
        self.bund.set_energy(N.ones(8) * 1000)
        self.bund.set_ref_index(N.ones(8))
Пример #26
0
class TestHomogenizer(unittest.TestCase):
    def setUp(self):
        """A homogenizer transforms a bundle correctly"""
        hmg = rect_homogenizer(5., 3., 10., 0.9)
        self.engine = TracerEngine(hmg)
        self.bund = RayBundle()

        # 4 rays starting somewhat above (+z) the homogenizer
        pos = N.zeros((3, 4))
        pos[2] = N.r_[11, 11, 11, 11]
        self.bund.set_vertices(pos)

        # One ray going to each wall:
        dir = N.c_[[1, 0, -1], [-1, 0, -1], [0, 1, -1],
                   [0, -1, -1]] / N.sqrt(2)
        self.bund.set_directions(dir)

        # Laborious setup details:
        self.bund.set_energy(N.ones(4) * 4.)
        self.bund.set_ref_index(N.ones(4))

    def test_first_hits(self):
        """Test bundle enters homogenizer correctly"""
        v, d = self.engine.ray_tracer(self.bund, 1, 0.05)

        out_dirs = N.c_[[-1, 0, -1], [1, 0, -1], [0, -1, -1],
                        [0, 1, -1]] / N.sqrt(2)
        N.testing.assert_array_almost_equal(d, out_dirs)

        out_hits = N.c_[[2.5, 0, 8.5], [-2.5, 0, 8.5], [0, 1.5, 9.5],
                        [0, -1.5, 9.5]]
        N.testing.assert_array_almost_equal(v, out_hits)
Пример #27
0
    def setUp(self):
        self.num_rays = 10
        dir = N.tile(N.c_[[0, 0, -1]], (1, self.num_rays))
        theta = N.linspace(0, 2 * N.pi, self.num_rays, endpoint=False)
        position = N.vstack(
            (N.cos(theta), N.sin(theta), N.ones(self.num_rays)))

        self._bund = RayBundle(position, dir)

        # The boundary is positioned to create a bottom hemisphere.
        boundary = BoundarySphere(radius=4.,
                                  location=N.r_[0., 0., -4 * N.sqrt(3) / 2.])
        self.gm = CutSphereGM(2., boundary)
        self.prm = self.gm.find_intersections(N.eye(4), self._bund)
Пример #28
0
def solar_disk_bundle(num_rays,  center,  direction,  radius, ang_range, flux=None, radius_in=0., angular_span=[0.,2.*N.pi], procs=1):
    """
    Generates a ray bundle emanating from a disk, with each surface element of 
    the disk having the same ray density. The rays all point at directions uniformly 
    distributed between a given angle range from a given direction.
    Setting of the bundle's energy is left to the caller.
    
    Arguments:
    num_rays - number of rays to generate.
    center - a column 3-array with the 3D coordinate of the disk's center
    direction - a 1D 3-array with the unit average direction vector for the
        bundle.
    radius - of the disk.
    ang_range - in radians, the maximum deviation from <direction>.
    flux - if not None, the ray bundle's energy is set such that each ray has
        an equal amount of energy, and the total energy is flux*pi*radius**2
    radius_in - Inner radius if the disc is pierced
    angular_span - wedge of the disc to consider
    
    Returns: 
    A RayBundle object with the above characteristics set.
    """

	# FIXME why should 'center' be a column vector... that's just annoying.

    radius = float(radius)
    radius_in = float(radius_in)
    a = pillbox_sunshape_directions(num_rays, ang_range)
        
    # Rotate to a frame in which <direction> is Z:
    perp_rot = rotation_to_z(direction)
    directions = N.sum(perp_rot[...,None] * a[None,...], axis=1)
    # Locations:
    # See [1]
    xi1 = random.uniform(size=num_rays)
    thetas = random.uniform(low=angular_span[0], high=angular_span[1], size=num_rays)
    rs = N.sqrt(radius_in**2.+xi1*(radius**2.-radius_in**2.))
    xs = rs * N.cos(thetas)
    ys = rs * N.sin(thetas)

    # Rotate locations to the plane defined by <direction>:
    vertices_local = N.vstack((xs, ys, N.zeros(num_rays)))
    vertices_global = N.dot(perp_rot, vertices_local)

    rayb = RayBundle(vertices=vertices_global + center, directions=directions)
    if flux != None:
        rayb.set_energy(N.pi*(radius**2.-radius_in**2.)/num_rays*flux*N.ones(num_rays))
    else:
        rayb.set_energy(N.ones(num_rays)/num_rays/procs)
    return rayb
Пример #29
0
class TestHomogenizer(unittest.TestCase):
    def setUp(self):
        """A homogenizer transforms a bundle correctly"""
        hmg = rect_homogenizer(5., 3., 10., 0.9)
        self.engine = TracerEngine(hmg)
        self.bund = RayBundle()
        
        # 4 rays starting somewhat above (+z) the homogenizer
        pos = N.zeros((3,4))
        pos[2] = N.r_[11, 11, 11, 11]
        self.bund.set_vertices(pos)
        
        # One ray going to each wall:
        dir = N.c_[[1, 0, -1], [-1, 0, -1], [0, 1, -1], [0, -1, -1]]/N.sqrt(2)
        self.bund.set_directions(dir)
        
        # Laborious setup details:
        self.bund.set_energy(N.ones(4)*4.)
        self.bund.set_ref_index(N.ones(4))
    
    def test_first_hits(self):
        """Test bundle enters homogenizer correctly"""
        v, d = self.engine.ray_tracer(self.bund, 1, 0.05)
        
        out_dirs = N.c_[[-1, 0, -1], [1, 0, -1], [0, -1, -1], [0, 1, -1]]/N.sqrt(2)
        N.testing.assert_array_almost_equal(d, out_dirs)
        
        out_hits = N.c_[
            [2.5, 0, 8.5], 
            [-2.5, 0, 8.5], 
            [0, 1.5, 9.5], 
            [0, -1.5, 9.5]]
        N.testing.assert_array_almost_equal(v, out_hits)
Пример #30
0
class TestTraceProtocol6(unittest.TestCase):
    """
    Tests a spherical surface
    """
    def setUp(self):
        surface1 = Surface(HemisphereGM(2.), opt.perfect_mirror,
            rotation=general_axis_rotation(N.r_[1,0,0], N.pi/2.))
        surface2 = Surface(HemisphereGM(2.), opt.perfect_mirror, 
            location=N.array([0,-2,0]), 
            rotation=general_axis_rotation(N.r_[1,0,0], -N.pi/2.))
        
        self._bund = RayBundle()
        self._bund.set_directions(N.c_[[0,1,0]])
        self._bund.set_vertices(N.c_[[0,-1,0]])
        self._bund.set_energy(N.r_[[1]]) 
        self._bund.set_ref_index(N.r_[[1]])

        assembly = Assembly()
        object1 = AssembledObject()
        object2 = AssembledObject()
        object1.add_surface(surface1)
        object2.add_surface(surface2)
        assembly.add_object(object1)
        assembly.add_object(object2)

        self.engine = TracerEngine(assembly)
        
    def test_ray_tracers1(self):
        params = self.engine.ray_tracer(self._bund, 1, .05)[0]
        correct_params = N.c_[[0,2,0]]

        N.testing.assert_array_almost_equal(params,correct_params)
Пример #31
0
    def test_paraxial_ray(self):
        """A paraxial ray in reflected correctly"""
        bund = RayBundle()
        bund.set_vertices(N.c_[[0.01, 0., 2.]])
        bund.set_directions(N.c_[[0., 0., -1.]])
        bund.set_energy(N.r_[100.])
        bund.set_ref_index(N.r_[1])

        self.engine.ray_tracer(bund, 15, 10.)
        non_degenerate = self.engine.tree[-1].get_energy() > 10
        v = self.engine.tree[-1].get_vertices()[:, non_degenerate]
        d = self.engine.tree[-1].get_directions()[:, non_degenerate]
        # Not high equality demanded, because of spherical aberration.
        N.testing.assert_array_almost_equal(v, N.c_[[-0.01, 0., 1.5]], 2)
        N.testing.assert_array_almost_equal(d, N.c_[[0., 0., 1.]], 2)
Пример #32
0
    def setUp(self):
        surface = Surface(HemisphereGM(1.),
                          opt.perfect_mirror,
                          rotation=general_axis_rotation(N.r_[1, 0, 0], N.pi))
        self._bund = RayBundle(energy=N.ones(3))
        self._bund.set_directions(N.c_[[0, 1, 0], [0, 1, 0], [0, -1, 0]])
        self._bund.set_vertices(N.c_[[0, -2., 0.001], [0, 0, 0.001],
                                     [0, 2, 0.001]])

        assembly = Assembly()
        object = AssembledObject()
        object.add_surface(surface)
        assembly.add_object(object)

        self.engine = TracerEngine(assembly)
Пример #33
0
class TestObjectBuilding1(unittest.TestCase):
    """Tests an object composed of sphere surfaces"""
    def setUp(self):
        self.assembly = Assembly()
        surface1 = Surface(HemisphereGM(3.), optics_callables.perfect_mirror, 
            location=N.array([0,0,-1.]),
            rotation=general_axis_rotation(N.r_[1,0,0], N.pi))
        surface2 = Surface(HemisphereGM(3.), optics_callables.perfect_mirror, 
            location=N.array([0,0,1.]))
        
        self.object = AssembledObject()
        self.object.add_surface(surface1)
        self.object.add_surface(surface2)
        self.assembly.add_object(self.object)

        dir = N.c_[[0,0,1.],[0,0,1.]]
        position = N.c_[[0,0,-3.],[0,0,-1.]]
    
        self._bund = RayBundle(position, dir, energy=N.ones(2))
    
    def test_object(self):
        """Tests that the assembly heirarchy works at a basic level"""
        self.engine = TracerEngine(self.assembly)

        inters = self.engine.ray_tracer(self._bund,1,.05)[0]
        correct_inters = N.c_[[0,0,2],[0,0,-2]]

        N.testing.assert_array_almost_equal(inters, correct_inters)
    
    def test_translation(self):
        """Tests an assembly that has been translated"""
        trans = N.array([[1,0,0,0],[0,1,0,0],[0,0,1,1],[0,0,0,1]])
        self.assembly.transform_children(trans)

        self.engine = TracerEngine(self.assembly)

        params =  self.engine.ray_tracer(self._bund,1,.05)[0]
        correct_params = N.c_[[0,0,3],[0,0,-1]]

        N.testing.assert_array_almost_equal(params, correct_params)

    def test_rotation_and_translation(self):
        """Tests an assembly that has been translated and rotated"""
        self._bund = RayBundle()
        self._bund.set_vertices(N.c_[[0,-5,1],[0,5,1]])
        self._bund.set_directions(N.c_[[0,1,0],[0,1,0]])
        self._bund.set_energy(N.r_[[1,1]])
        self._bund.set_ref_index(N.r_[[1,1]])

        trans = generate_transform(N.r_[[1,0,0]], N.pi/2, N.c_[[0,0,1]])
        self.assembly.transform_children(trans)

        self.engine = TracerEngine(self.assembly)

        params =  self.engine.ray_tracer(self._bund,1,.05)[0]
        correct_params = N.c_[[0,-2,1]]

        N.testing.assert_array_almost_equal(params, correct_params)
Пример #34
0
 def test_all_refracted(self):
     dir = N.c_[[1, 1, -1], [-1, 1, -1], [-1, -1, -1], [1, -1, -1]] / N.sqrt(3)
     position = N.c_[[0,0,1], [1,-1,1], [1,1,1], [-1,1,1]]
     en = N.r_[100, 200, 300, 400]
     bund = RayBundle(position, dir, energy=en, ref_index=N.ones(4))
     
     gm = FlatGeometryManager()
     prm = gm.find_intersections(N.eye(4), bund)
     refractive = optics_callables.RefractiveHomogenous(1,1.5)
     selector = N.array([0, 1, 3])
     gm.select_rays(selector)
     outg = refractive(gm, bund, selector)
     
     correct_pts = N.zeros((3,4))
     correct_pts[:2,0] = 1
     correct_pts = N.hstack((correct_pts[:,selector], correct_pts[:,selector]))
     N.testing.assert_array_equal(outg.get_vertices(), correct_pts)
     
     norm = N.c_[gm.get_normals()[:,0]]
     correct_refl_cos = -(dir*norm).sum(axis=0)[selector]
     correct_refr_cos = -N.sqrt(1 - (1./1.5)**2*(1 - correct_refl_cos**2))
     outg_cos = (outg.get_directions()*norm).sum(axis=0)
     N.testing.assert_array_equal(outg_cos, N.r_[correct_refl_cos, correct_refr_cos])
     
     N.testing.assert_array_equal(outg.get_energy().reshape(2,-1).sum(axis=0), \
         N.r_[100, 200, 400]) # reflection and refraction sum to 100%
     N.testing.assert_array_equal(outg.get_parents(), N.tile(selector, 2))
Пример #35
0
    def setUp(self):
        self.assembly = Assembly()

        surface1 = Surface(FlatGeometryManager(),
                           opt.RefractiveHomogenous(1., 1.5),
                           location=N.array([0, 0, -1.]))
        surface2 = Surface(FlatGeometryManager(),
                           opt.RefractiveHomogenous(1., 1.5),
                           location=N.array([0, 0, 1.]))
        object1 = AssembledObject(surfs=[surface1, surface2])

        boundary = BoundarySphere(location=N.r_[0, 0., 3], radius=3.)
        surface3 = Surface(CutSphereGM(2., boundary), opt.perfect_mirror)
        object2 = AssembledObject(surfs=[surface3],
                                  transform=translate(0., 0., 2.))

        self.assembly = Assembly(objects=[object1, object2])

        x = 1. / (math.sqrt(2))
        dir = N.c_[[0, 1., 0.], [0, x, x], [0, 0, 1.]]
        position = N.c_[[0, 0, 2.], [0, 0, 2.], [0, 0., 2.]]
        self._bund = RayBundle(position,
                               dir,
                               ref_index=N.ones(3),
                               energy=N.ones(3))

        self.engine = TracerEngine(self.assembly)
Пример #36
0
    def setUp(self):
        self._surf = Surface(FlatGeometryManager(), perfect_mirror)

        dir = N.array([[1, 1, -1], [-1, 1, -1], [-1, -1, -1], [1, -1, -1]
                       ]).T / math.sqrt(3)
        position = c_[[0, 0, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1]]
        self._bund = RayBundle(position, dir, energy=N.ones(4) * 100)
Пример #37
0
    def test_tetrahedron(self):
        """Triangular mesh with oblique triangles"""
        # Face set:
        theta = np.arange(np.pi / 2., np.pi * 2, 2 * np.pi / 3)
        base_verts = np.vstack((np.cos(theta), np.sin(theta), np.ones(3))).T
        verts = np.vstack((np.zeros(3), base_verts))

        faces = np.array([[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]])
        fset = TriangulatedSurface(verts, faces, perfect_mirror)

        # Flat floor:
        floor = rect_one_sided_mirror(5., 5., 1.)
        floor.set_location(np.r_[0., 0., 1.])
        assembly = Assembly(objects=[fset, floor])

        # Ray bundle of 3 rays starting at equal angles around the tetrahedron:
        theta -= np.pi / 3.
        pos = np.vstack((np.cos(theta), np.sin(theta), np.ones(3) * 0.2)) * 0.2
        direct = np.vstack((np.zeros((2, 3)), np.ones(3)))
        rayb = RayBundle(pos, direct, energy=np.ones(6))

        # Check that the points on the floor describe an isosceles.
        engine = TracerEngine(assembly)
        engine.ray_tracer(rayb, 2, .05)[0]
        verts = engine.tree[-1].get_vertices()
        sizes = np.sqrt(np.sum((verts - np.roll(verts, 1, axis=1))**2, axis=0))

        self.assertAlmostEqual(sizes[0], sizes[1])
        self.assertAlmostEqual(sizes[2], sizes[1])
Пример #38
0
    def test_pyramid(self):
        """A simple right-pyramid triangular mesh"""
        # Face set:
        verts = np.vstack(
            (np.zeros(3), np.eye(3)))  # origin + unit along each axis
        faces = np.array([[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]])
        assembly = Assembly(
            objects=[TriangulatedSurface(verts, faces, perfect_mirror)])

        # Ray bundle:
        pos = np.c_[[1.5, 0.5, 0.5], [-0.5, 0.5, 0.5], [0.5, 1.5, 0.5],
                    [0.5, -0.5, 0.5], [0.5, 0.5, -0.5], [0.5, 0.5, 1.5]]
        direct = np.c_[[-1., 0., 0.], [1., 0., 0.], [0., -1., 0.],
                       [0., 1., 0.], [0., 0., 1.], [0., 0., -1.]]
        rayb = RayBundle(pos, direct, energy=np.ones(6))

        engine = TracerEngine(assembly)
        verts = engine.ray_tracer(rayb, 1, .05)[0]

        p = engine.tree[-1].get_parents()
        zrays = (p >= 4)
        np.testing.assert_array_equal(verts[:, zrays],
                                      np.tile(np.c_[[0.5, 0.5, 0.]], (1, 4)))
        yrays = (p == 2) | (p == 3
                            )  # Only 2 rays here. Edge degeneracy? maybe.
        np.testing.assert_array_equal(verts[:, yrays],
                                      np.tile(np.c_[[0.5, 0., 0.5]], (1, 4)))
        xrays = (p < 2)
        np.testing.assert_array_equal(verts[:, xrays],
                                      np.tile(np.c_[[0., 0.5, 0.5]], (1, 4)))
Пример #39
0
    def trace(self):
        """Generate a flux map using much more rays than drawn"""
        # Generate a large ray bundle using a radial stagger much denser
        # than the field.
        sun_vec = solar_vector(self.sun_az * degree, self.sun_elev * degree)

        hstat_rays = 20
        num_rays = hstat_rays * len(self.field.get_heliostats())
        rot_sun = rotation_to_z(-sun_vec)
        direct = N.dot(rot_sun, pillbox_sunshape_directions(num_rays, 0.00465))

        xy = N.random.uniform(low=-0.25, high=0.25, size=(2, num_rays))
        base_pos = N.tile(self.pos, (hstat_rays, 1)).T
        base_pos += N.dot(rot_sun[:, :2], xy)

        base_pos -= direct
        rays = RayBundle(base_pos, direct, energy=N.ones(num_rays))

        # Perform the trace:
        e = TracerEngine(self.plant)
        e.ray_tracer(rays, 100, 0.05, tree=True)
        e.minener = 1e-5

        # Render:
        trace_scene = Renderer(e)
        trace_scene.show_rays()
Пример #40
0
    def setUp(self):
        self.assembly = Assembly()

        surface1 = Surface(flat_surface.FlatGeometryManager(),
                           optics_callables.RefractiveHomogenous(1., 1.5),
                           location=N.array([0, 0, -1.]))
        surface2 = Surface(flat_surface.FlatGeometryManager(),
                           optics_callables.RefractiveHomogenous(1., 1.5),
                           location=N.array([0, 0, 1.]))

        self.object1 = AssembledObject()
        self.object1.add_surface(surface1)
        self.object1.add_surface(surface2)

        boundary = BoundarySphere(location=N.r_[0, 0., 3], radius=3.)
        surface3 = Surface(CutSphereGM(2., boundary),
                           optics_callables.perfect_mirror)
        self.object2 = AssembledObject()
        self.object2.add_surface(surface3)

        self.transform = generate_transform(N.r_[1, 0., 0], 0.,
                                            N.c_[[0., 0, 2]])
        self.assembly.add_object(self.object1)
        self.assembly.add_object(self.object2, self.transform)

        x = 1. / (math.sqrt(2))
        dir = N.c_[[0, 1., 0.], [0, x, x], [0, 0, 1.]]
        position = N.c_[[0, 0, 2.], [0, 0, 2.], [0, 0., 2.]]
        self._bund = RayBundle(position,
                               dir,
                               energy=N.ones(3),
                               ref_index=N.ones(3))
Пример #41
0
 def gen_rays(self):
     sun_vec = solar_vector(self.sun_az*degree, self.sun_elev*degree)
     rpos = (self.pos + sun_vec).T
     direct = N.tile(-sun_vec, (self.pos.shape[0], 1)).T
     rays = RayBundle(rpos, direct, energy=N.ones(self.pos.shape[0]))
     
     return rays
Пример #42
0
def rect_buie_sunshape(num_rays,
                       center,
                       direction,
                       width,
                       height,
                       CSR,
                       flux=None,
                       pre_process_CSR=True,
                       rays_direction=None):
    '''
	Generate a ray bundle according to Buie et al.: "Sunshape distributions for terrestrial simulations." Solar Energy 74 (2003) 113-122 (DOI: 10.1016/S0038-092X(03)00125-7).

	Arguments:
	num_rays - number of rays in the bundle
	center - position of the source center
	direction - direction of the normal to the source disc.
	radius - radius of the source disc
	CSR - Circumsolar ratio, fraction of the incoming solar energy which incident angle is greater than the angle subtended by the solar disc.
	flux - horizontal radiation density in W/m2
	pre_process_CSR=True - Use or not the polynomial pre-processing to get better I/O match using the Buie sunshape
	rays_direction=None - If the general direction of propagation of the source is different from the source normal.

	Returns:
	A raybundle object with the above characteristics set.
	'''

    # Rays vertices (start positions):
    xs = width * (random.uniform(size=num_rays) - 0.5)
    ys = height * (random.uniform(size=num_rays) - 0.5)

    # Source surface area:
    S = width * height

    # Rays escaping direction setup:
    if rays_direction == None:
        rays_direction = direction

    # Uniform ray energy:
    cosangle = 2. * N.sin(N.sqrt(N.sum((rays_direction - direction)**2)) / 2.)
    energy = N.ones(num_rays) * flux * S / num_rays * N.cos(cosangle)

    # Buie sunshape directions:
    a = buie_distribution(num_rays, CSR, pre_process_CSR)

    # Rotate to a frame in which <rays_direction> is Z:
    perp_rot = rotation_to_z(rays_direction)
    directions = N.sum(perp_rot[..., None] * a[None, ...], axis=1)

    # Rotate to a frame in which <direction> is Z:
    perp_rot = rotation_to_z(direction)

    # Rotate locations to the plane defined by <direction>:
    vertices_local = N.vstack((xs, ys, N.zeros(num_rays)))
    vertices_global = N.dot(perp_rot, vertices_local)

    rayb = RayBundle(vertices=vertices_global + center,
                     directions=directions,
                     energy=energy)

    return rayb
Пример #43
0
class TestTraceProtocol3(unittest.TestCase):
    """
    Tests intersect_ray and the bundle driver with two rotated planes, with a single iteration
    """
    def setUp(self):
        self.x = 1 / (math.sqrt(2))
        dir = N.c_[[0, self.x, -self.x], [0, 1, 0]]
        position = N.c_[[0, 0, 1], [0, 0, 1]]
        self._bund = RayBundle(position, dir, energy=N.ones(2))

        rot1 = general_axis_rotation([1, 0, 0], N.pi / 4)
        rot2 = general_axis_rotation([1, 0, 0], N.pi / (-4))
        surf1 = Surface(FlatGeometryManager(),
                        opt.perfect_mirror,
                        rotation=rot1)
        surf2 = Surface(FlatGeometryManager(),
                        opt.perfect_mirror,
                        rotation=rot2)

        self.assembly = Assembly()
        object = AssembledObject()
        object.add_surface(surf1)
        object.add_surface(surf2)
        self.assembly.add_object(object)

        self.engine = TracerEngine(self.assembly)

    def test_intersect_ray(self):
        surfaces = self.assembly.get_surfaces()
        objects = self.assembly.get_objects()
        surfs_per_obj = [len(obj.get_surfaces()) for obj in objects]
        surf_ownership = N.repeat(N.arange(len(objects)), surfs_per_obj)
        ray_ownership = -1 * N.ones(self._bund.get_num_rays())
        surfs_relevancy = N.ones((len(surfaces), self._bund.get_num_rays()),
                                 dtype=N.bool)

        params = self.engine.intersect_ray(self._bund, surfaces, objects, \
            surf_ownership, ray_ownership, surfs_relevancy)[0]
        correct_params = N.array([[True, True], [False, False]])

        N.testing.assert_array_almost_equal(params, correct_params)

    def test_ray_tracer1(self):
        params = self.engine.ray_tracer(self._bund, 1, .05)[0]
        correct_params = N.c_[[0, .5, .5], [0, 1, 1]]

        N.testing.assert_array_almost_equal(params, correct_params)
Пример #44
0
    def setUp(self):
        # Two rays inside, two outside; two horizontal, two slanted.
        pos = N.c_[[0., 0., 0.], [0., 0., 0.], [0., 1., 0.], [0., 1., 0.]]
        dir = N.c_[[0., 1., 0.], [0., 1., 1.], [0., -1., 0.], [0., -1., 1.]]
        dir /= N.sqrt(N.sum(dir**2, axis=0))

        self.bund = RayBundle(pos, dir)
        self.gm = InfiniteCylinder(diameter=1.)
Пример #45
0
 def setUp(self):
     self.num_rays = 10
     dir = N.tile(N.c_[[0, 0, -1]], (1, self.num_rays))
     theta = N.linspace(0, 2*N.pi, self.num_rays, endpoint=False)
     position = N.vstack((N.cos(theta), N.sin(theta), N.ones(self.num_rays)))
     self._bund = RayBundle(position, dir)
     
     self.gm = HemisphereGM(radius=2.)
     self.prm = self.gm.find_intersections(N.eye(4), self._bund)
Пример #46
0
 def test_paraxial_ray(self):
     """A paraxial ray in reflected correctly"""
     bund = RayBundle()
     bund.set_vertices(N.c_[[0.01, 0., 2.]])
     bund.set_directions(N.c_[[0., 0., -1.]])
     bund.set_energy(N.r_[100.])
     bund.set_ref_index(N.r_[1])
     
     self.engine.ray_tracer(bund, 15, 10.)
     non_degenerate = self.engine.tree[-1].get_energy() > 10
     v = self.engine.tree[-1].get_vertices()[:,non_degenerate]
     d = self.engine.tree[-1].get_directions()[:,non_degenerate]
     # Not high equality demanded, because of spherical aberration.
     N.testing.assert_array_almost_equal(v, N.c_[[-0.01, 0., 1.5]], 2)
     N.testing.assert_array_almost_equal(d, N.c_[[0., 0., 1.]], 2)
Пример #47
0
def triangular_bundle(num_rays, A, AB, AC, direction, ang_range=N.pi/2., flux=None, procs=1):
	"""
	Triangular ray-casting surface anchored on the point A.
	Arguments:
	- num_rays: the number of rays 
	- A: The first summit of the triangle and its anchor point.
	- AB and AC the vertices of the sides of the triangle in its plane of reference.
	- direction: The direction at which the source is pointing
	- ang_range: the angular range of the rays emitted by the source

	Returns: 
	- A ray bundle object for tracing
	"""
	# Triangle ray vertices:
	# Declare random numbers:
	r1 = N.vstack(N.random.uniform(size=num_rays))
	r2 = N.vstack(N.random.uniform(size=num_rays))
	# Define points in a local referential where A is at [0,0] on a z=0 plane.
	sqrtr1 = N.sqrt(r1)
	Plocs = sqrtr1*(1.-r2)*AB+r2*sqrtr1*AC # Triangle point picking

	vertices_local = N.array([Plocs[:,0], Plocs[:,1], N.zeros(num_rays)])

	# Bring everything back to the global referential:
	rot = rotation_to_z(direction)
	vertices_global = N.dot(rot, vertices_local)+N.vstack(A)
	
	# Local referential directions:
	a = pillbox_sunshape_directions(num_rays, ang_range)
	# Rotate to a frame in which <direction> is Z:
	directions = N.sum(rot[...,None] * a[None,...], axis=1)

	rayb = RayBundle()

	rayb.set_vertices(vertices_global)
	rayb.set_directions(directions)

	l1 = N.sqrt(N.sum(AB**2))
	l2 = N.sqrt(N.sum(AC**2))
	l3 = N.sqrt(N.sum((-AB+AC)**2))
	s = (l1+l2+l3)/2.
	area = N.sqrt(s*(s-l1)*(s-l2)*(s-l3))
	if flux != None:
		rayb.set_energy(N.ones(num_rays)*flux*area/float(num_rays))
	else:
		rayb.set_energy(N.ones(num_rays)/float(num_rays)/procs)

	return rayb
Пример #48
0
def single_ray_source(position, direction, flux=None):
	'''
	Establishes a single ray source originating from a definned point on a defined exact 
	direction for the purpose of testing single ray behviours.

	Arguments:
	position - column 3-array with the ray's starting position.
	direction - a 1D 3-array with the unit average direction vector for the
				bundle.
	flux - if not None, the energy transported by the ray.

	Returns:
	A Raybundle object with the corresponding characteristics.
	'''
	directions = N.tile(direction[:,None],1)
	directions /= N.sqrt(N.sum(directions**2, axis=0))
	singray = RayBundle(vertices = position, directions = directions)
	singray.set_energy(flux*N.ones(1))
	return singray
Пример #49
0
 def setUp(self):
     dir = N.array([[1,1,-1],[-1,1,-1],[-1,-1,-1],[1,-1,-1]]).T/math.sqrt(3)
     position = N.c_[[0,0,1],[1,-1,1],[1,1,1],[-1,1,1]]
     self._bund = RayBundle(position, dir, energy=N.ones(4))
     
     self.assembly = Assembly()
     object = AssembledObject()
     object.add_surface(Surface(FlatGeometryManager(), opt.perfect_mirror))
     self.assembly.add_object(object)
     self.engine = TracerEngine(self.assembly)
Пример #50
0
class TestTraceProtocol3(unittest.TestCase):
    """
    Tests intersect_ray and the bundle driver with two rotated planes, with a single iteration
    """
    def setUp(self):
        self.x = 1/(math.sqrt(2))
        dir = N.c_[[0,self.x,-self.x],[0,1,0]]
        position = N.c_[[0,0,1],[0,0,1]]
        self._bund = RayBundle(position, dir, energy=N.ones(2))

        rot1 = general_axis_rotation([1,0,0],N.pi/4)
        rot2 = general_axis_rotation([1,0,0],N.pi/(-4))
        surf1 = Surface(FlatGeometryManager(), opt.perfect_mirror, rotation=rot1)
        surf2 = Surface(FlatGeometryManager(), opt.perfect_mirror, rotation=rot2)
        
        self.assembly = Assembly()
        object = AssembledObject()
        object.add_surface(surf1)
        object.add_surface(surf2)
        self.assembly.add_object(object)

        self.engine = TracerEngine(self.assembly)
        
    def test_intersect_ray(self):
        surfaces = self.assembly.get_surfaces()
        objects = self.assembly.get_objects()
        surfs_per_obj = [len(obj.get_surfaces()) for obj in objects]
        surf_ownership = N.repeat(N.arange(len(objects)), surfs_per_obj)
        ray_ownership = -1*N.ones(self._bund.get_num_rays())
        surfs_relevancy = N.ones((len(surfaces), self._bund.get_num_rays()), dtype=N.bool)
        
        params = self.engine.intersect_ray(self._bund, surfaces, objects, \
            surf_ownership, ray_ownership, surfs_relevancy)[0]
        correct_params = N.array([[True, True],[False, False]])

        N.testing.assert_array_almost_equal(params,correct_params)    

    def test_ray_tracer1(self):
        params = self.engine.ray_tracer(self._bund, 1,.05)[0]
        correct_params = N.c_[[0,.5,.5],[0,1,1]]

        N.testing.assert_array_almost_equal(params,correct_params)
Пример #51
0
    def setUp(self):
        pos = N.zeros((3,4))
        pos[0] = N.r_[0, 0.5, 2, -2]
        pos[2] = 2.
        dir = N.tile(N.c_[[0,0,-1]], (1,4))

        self.bund = RayBundle()
        self.bund.set_vertices(pos)
        self.bund.set_directions(dir)

        self.surf = Surface(ParabolicDishGM(2., 1.), opt.perfect_mirror)
Пример #52
0
    def setUp(self):
        self.num_rays = 10
        dir = N.tile(N.c_[[0, 0, -1]], (1, self.num_rays))
        theta = N.linspace(0, 2*N.pi, self.num_rays, endpoint=False)
        position = N.vstack((N.cos(theta), N.sin(theta), N.ones(self.num_rays)))
        
        self._bund = RayBundle()
        self._bund.set_vertices(position)
        self._bund.set_directions(dir)

        self.gm = Paraboloid(a=5., b=5.)
        self.prm = self.gm.find_intersections(N.eye(4), self._bund)
Пример #53
0
 def setUp(self):
     self.num_rays = 10
     dir = N.tile(N.c_[[0, 0, -1]], (1, self.num_rays))
     theta = N.linspace(0, 2*N.pi, self.num_rays, endpoint=False)
     position = N.vstack((N.cos(theta), N.sin(theta), N.ones(self.num_rays)))
     
     self._bund = RayBundle(position, dir)
     
     # The boundary is positioned to create a bottom hemisphere.
     boundary = BoundarySphere(radius=4., location=N.r_[0., 0., -4*N.sqrt(3)/2.])
     self.gm = CutSphereGM(2., boundary)
     self.prm = self.gm.find_intersections(N.eye(4), self._bund)
Пример #54
0
class TestInterface(unittest.TestCase):
    def setUp(self):
        self.num_rays = 10
        dir = N.tile(N.c_[[0, 0, -1]], (1, self.num_rays))
        theta = N.linspace(0, 2*N.pi, self.num_rays, endpoint=False)
        position = N.vstack((N.cos(theta), N.sin(theta), N.ones(self.num_rays)))
        
        self._bund = RayBundle()
        self._bund.set_vertices(position)
        self._bund.set_directions(dir)

        self.gm = Paraboloid(a=5., b=5.)
        self.prm = self.gm.find_intersections(N.eye(4), self._bund)
    
    def test_find_intersections(self):
        """The correct parametric locations are found for paraboloid geometry"""
        self.failUnlessEqual(self.prm.shape, (self.num_rays,))
        N.testing.assert_array_almost_equal(self.prm, 0.96)
    
    def test_get_normals(self):
        """Paraboloid surface returns center-pointing normals"""
        self.gm.select_rays(N.arange(self.num_rays))
        n = self.gm.get_normals() # all rays selected
        N.testing.assert_array_equal(n[-1,0], n[-1,1:])
        N.testing.assert_array_almost_equal(self._bund.get_vertices()[:2],
            -n[:2]/N.sqrt((n[:2]**2).sum(axis=0)))
    
    def test_inters_points_global(self):
        """Paraboloid returns correct intersections"""
        self.gm.select_rays(N.arange(self.num_rays))
        pts = self.gm.get_intersection_points_global()
        N.testing.assert_array_equal(pts[:2], self._bund.get_vertices()[:2])
        N.testing.assert_array_almost_equal(pts[2], 0.04)
Пример #55
0
    def setUp(self):
        surface = Surface(HemisphereGM(1.), opt.perfect_mirror,
            rotation=general_axis_rotation(N.r_[1,0,0], N.pi))
        self._bund = RayBundle(energy=N.ones(3))
        self._bund.set_directions(N.c_[[0,1,0],[0,1,0],[0,-1,0]])
        self._bund.set_vertices(N.c_[[0,-2.,0.001],[0,0,0.001],[0,2,0.001]])

        assembly = Assembly()
        object = AssembledObject()
        object.add_surface(surface)
        assembly.add_object(object)
        
        self.engine = TracerEngine(assembly)
Пример #56
0
def solar_rect_bundle(num_rays, center, direction, x, y, ang_range, flux=None):

    a = pillbox_sunshape_directions(num_rays, ang_range)

    # Rotate to a frame in which <direction> is Z:
    perp_rot = rotation_to_z(direction)
    directions = N.sum(perp_rot[...,None] * a[None,...], axis=1)

    xs = random.uniform(low=-x/2., high=x/2., size=num_rays)
    ys = random.uniform(low=-y/2., high=y/2., size=num_rays)

    if (direction == N.array([0,0,-1])).all():
        xs, ys = ys, xs

    # Rotate locations to the plane defined by <direction>:
    vertices_local = N.vstack((ys, xs, N.zeros(num_rays)))
    vertices_global = N.dot(perp_rot, vertices_local)

    rayb = RayBundle(vertices=vertices_global + center, directions=directions)
    if flux != None:
        rayb.set_energy(x*y/num_rays*flux*N.ones(num_rays))
    return rayb
Пример #57
0
 def setUp(self):
     self.mirror = rect_one_sided_mirror(1.5, 1.5, 0.9)
     
     pos = N.zeros((3,8))
     pos[0] = N.tile(N.r_[0, 0.5, 2, -2], 2)
     pos[2] = N.repeat(N.r_[1, -1], 4)
     dir = N.zeros((3,8))
     dir[2] = N.repeat(N.r_[-1, 1], 4)
     
     self.bund = RayBundle()
     self.bund.set_vertices(pos)
     self.bund.set_directions(dir)
     self.bund.set_energy(N.ones(8)*1000)
     self.bund.set_ref_index(N.ones(8))
Пример #58
0
class TestTraceProtocol5(unittest.TestCase):
    """
    Tests a spherical surface
    """
    def setUp(self):
        surface = Surface(HemisphereGM(1.), opt.perfect_mirror,
            rotation=general_axis_rotation(N.r_[1,0,0], N.pi))
        self._bund = RayBundle(energy=N.ones(3))
        self._bund.set_directions(N.c_[[0,1,0],[0,1,0],[0,-1,0]])
        self._bund.set_vertices(N.c_[[0,-2.,0.001],[0,0,0.001],[0,2,0.001]])

        assembly = Assembly()
        object = AssembledObject()
        object.add_surface(surface)
        assembly.add_object(object)
        
        self.engine = TracerEngine(assembly)

    def test_ray_tracer1(self):
        params = self.engine.ray_tracer(self._bund, 1, .05)[0]
        correct_params = N.c_[[0,-1,0],[0,1,0],[0,1,0]]
         
        N.testing.assert_array_almost_equal(params,correct_params, decimal=3)
Пример #59
0
def oblique_solar_rect_bundle(num_rays, center, source_direction, rays_direction, x, y, ang_range, flux=None, procs=1):
	a = pillbox_sunshape_directions(num_rays, ang_range)
	# Rotate to a frame in which <direction> is Z:
	perp_rot = rotation_to_z(rays_direction)
	directions = N.sum(perp_rot[...,None] * a[None,...], axis=1)

	xs = random.uniform(low=-x/2., high=x/2., size=num_rays)
	ys = random.uniform(low=-y/2., high=y/2., size=num_rays)

	if (source_direction == N.array([0,0,-1])).all():
		xs, ys = ys, xs

	# Rotate locations to the plane defined by <direction>:
	vertices_local = N.vstack((ys, xs, N.zeros(num_rays)))
	perp_rot = rotation_to_z(source_direction)
	vertices_global = N.dot(perp_rot, vertices_local)

	rayb = RayBundle(vertices=vertices_global + center, directions=directions)
	if flux != None:
		cosangle = 2.*N.sin(N.sqrt(N.sum((rays_direction-source_direction)**2))/2.)
		rayb.set_energy(x*y/num_rays*flux*N.ones(num_rays)*N.cos(cosangle))
	else:
		rayb.set_energy(N.ones(num_rays)/float(num_rays)/procs)
	return rayb
Пример #60
0
class TestInterface(unittest.TestCase):
    def setUp(self):
        self.num_rays = 10
        dir = N.tile(N.c_[[0, 0, -1]], (1, self.num_rays))
        theta = N.linspace(0, 2*N.pi, self.num_rays, endpoint=False)
        position = N.vstack((N.cos(theta), N.sin(theta), N.ones(self.num_rays)))
        self._bund = RayBundle(position, dir)
        
        self.gm = HemisphereGM(radius=2.)
        self.prm = self.gm.find_intersections(N.eye(4), self._bund)
    
    def test_find_intersections(self):
        """The correct parametric locations are found for hemisphere geometry"""
        self.failUnlessEqual(self.prm.shape, (self.num_rays,))
        N.testing.assert_array_almost_equal(self.prm, 1 + 2*N.sin(N.pi/3))
    
    def test_get_normals(self):
        """Hemisphere surface returns center-pointing normals"""
        self.gm.select_rays(N.arange(self.num_rays))
        n = self.gm.get_normals()
        N.testing.assert_array_almost_equal(n[-1,0], n[-1,1:])
        N.testing.assert_array_almost_equal(self._bund.get_vertices()[:2],
            -n[:2]/N.sqrt((n[:2]**2).sum(axis=0)))
    
    def test_inters_points_global(self):
        """Hemisphere returns correct intersections"""
        self.gm.select_rays(N.arange(self.num_rays))
        pts = self.gm.get_intersection_points_global()
        N.testing.assert_array_equal(pts[:2], self._bund.get_vertices()[:2])
        N.testing.assert_array_almost_equal(pts[2], -2*N.sin(N.pi/3))
    
    def test_mesh(self):
        """The HemisphereGM mesh represents the lower hemisphere only"""
        x, y, z = self.gm.mesh(10)
        self.failUnless(N.all(z <= 1e-15))
        self.failIf(N.any(x**2 + y**2 > 4.0001))