예제 #1
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)
예제 #2
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)
예제 #3
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)
예제 #4
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)
예제 #5
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)
예제 #6
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))
예제 #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
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)
예제 #9
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)
예제 #10
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)
예제 #11
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))
예제 #12
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
예제 #13
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)
예제 #14
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])
예제 #15
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
예제 #16
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)]
예제 #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 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])
예제 #19
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)
예제 #20
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)
예제 #21
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
예제 #22
0
class TestRectOneSided(unittest.TestCase):
    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))

    def test_regular(self):
        """One-sided plate without rotation"""
        e = TracerEngine(Assembly(objects=[self.mirror]))
        e.ray_tracer(self.bund, 1, 0.05)
        outg = e.tree[-1]

        correct_verts = N.zeros((3, 2))
        correct_verts[0] = N.r_[0, 0.5]
        N.testing.assert_array_equal(
            outg.get_vertices()[:, outg.get_energy() > 0], correct_verts)
        N.testing.assert_array_almost_equal(outg.get_energy(), N.r_[100., 100.,
                                                                    0, 0])

    def test_rotated(self):
        """One-sided plate with rotation"""
        rot = sp.roty(N.pi / 4.)
        self.mirror.set_transform(rot)

        e = TracerEngine(Assembly(objects=[self.mirror]))
        e.ray_tracer(self.bund, 1, 0.05)
        outg = e.tree[-1]

        correct_verts = N.array([[0., 0.5], [0., 0.], [0., -0.5]])
        N.testing.assert_array_almost_equal(
            outg.get_vertices()[:, outg.get_energy() > 0], correct_verts)
        N.testing.assert_array_almost_equal(outg.get_energy(), N.r_[100., 100.,
                                                                    0, 0])
예제 #23
0
class TestRectOneSided(unittest.TestCase):
    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))
    
    def test_regular(self):
        """One-sided plate without rotation"""
        e = TracerEngine(Assembly(objects=[self.mirror]))
        e.ray_tracer(self.bund, 1, 0.05)
        outg = e.tree[-1]
        
        correct_verts = N.zeros((3,2))
        correct_verts[0] = N.r_[0, 0.5]
        N.testing.assert_array_equal(
            outg.get_vertices()[:,outg.get_energy() > 0], correct_verts)
        N.testing.assert_array_almost_equal(
            outg.get_energy(), N.r_[100., 100., 0, 0])
    
    def test_rotated(self):
        """One-sided plate with rotation"""
        rot = sp.roty(N.pi/4.)
        self.mirror.set_transform(rot)
        
        e = TracerEngine(Assembly(objects=[self.mirror]))
        e.ray_tracer(self.bund, 1, 0.05)
        outg = e.tree[-1]
        
        correct_verts = N.array([[0., 0.5], [0., 0.], [0., -0.5]])
        N.testing.assert_array_almost_equal(
            outg.get_vertices()[:,outg.get_energy() > 0], correct_verts)
        N.testing.assert_array_almost_equal(
            outg.get_energy(), N.r_[100., 100., 0, 0])
예제 #24
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)
예제 #25
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)
예제 #26
0
def triangular_bundle(num_rays,
                      A,
                      B,
                      C,
                      direction=None,
                      ang_range=N.pi / 2.,
                      flux=None,
                      procs=1):
    """
	Triangular ray-casting surface. A, B and C are 3D coordinates of the vertices. Right hand rule determines the normal vector direction.
	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 around which rays are escaping the source. If None, the direction is the normal.
	- 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))

    AB = B - A
    AC = C - A
    sqrtr1 = N.sqrt(r1)
    vertices = (A + sqrtr1 * (1. - r2) * AB +
                r2 * sqrtr1 * AC).T  # Triangle point picking

    # Local referential directions:
    a = pillbox_sunshape_directions(num_rays, ang_range)
    # Normal vector:
    normal = N.cross(AB, AC)
    normal = normal / N.sqrt(N.sum(normal**2))

    if direction is None:
        direction = normal

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

    rayb = RayBundle()

    rayb.set_vertices(vertices)
    rayb.set_directions(directions)

    # Heron's formula for triangle surface area
    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:
        cosangle = 2. * N.arcsin(0.5 * N.sqrt(N.sum((direction - normal)**2)))
        rayb.set_energy(area / num_rays * flux * N.ones(num_rays) *
                        N.cos(cosangle))
    else:
        rayb.set_energy(N.ones(num_rays) / float(num_rays) / procs)

    return rayb
예제 #27
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)