예제 #1
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()
예제 #2
0
def test_case(focus, num_rays=100, h_depth=0.7, side=0.4):
    # Case parameters (to be moved out:
    D = 5.
    
    center = N.c_[[0, 7., 7.]]
    x = -1/(math.sqrt(2))
    direction = N.array([0,x,x])
    radius_sun = 2.5 
    ang_range = 0.005
    
    iterate = 100
    min_energy = 1e-6
    
    # Model:
    assembly = MiniDish(D, focus, 0.9, focus + h_depth, side, h_depth, 0.9)
    assembly.set_transform(rotx(-N.pi/4))
    
    # Rays:
    sun = solar_disk_bundle(num_rays, center, direction, radius_sun, ang_range,
        flux=1000.)
    
    # Do the tracing:
    engine = TracerEngine(assembly)
    engine.ray_tracer(sun, iterate, min_energy)
    
    # Plot, scale in suns:
    f = plot_hits(assembly.histogram_hits()[0]/(side/50)**2/1000., (-side/2., side/2., -side/2., side/2.))
    f.show()
예제 #3
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])
예제 #4
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)))
예제 #5
0
    def test_paraboloid1(self):
        """Tests a paraboloid"""

        self.engine = TracerEngine(self.assembly)
        params = self.engine.ray_tracer(self._bund, 1, .05)[0]
        correct_params = N.c_[[0, 0, 0], [0, 0.618033989, 0.381966011]]
        N.testing.assert_array_almost_equal(params, correct_params)
예제 #6
0
 def test_refraction2(self):
     """Tests the refractive functions after two intersections"""
     self.engine = TracerEngine(self.assembly)
     ans = self.engine.ray_tracer(self._bund, 2, .05)
     params = N.arctan(ans[1][1] / ans[1][2])
     correct_params = N.r_[-0.7853981]
     N.testing.assert_array_almost_equal(params, correct_params)
예제 #7
0
    def test_assembly3(self):
        """Tests the assembly after three iterations"""
        self.engine = TracerEngine(self.assembly)
        params = self.engine.ray_tracer(self._bund, 3, .05)[0]
        correct_params = N.c_[[0, -2.069044, -1], [0, 0, -1]]

        N.testing.assert_array_almost_equal(params, correct_params)
예제 #8
0
 def test_refraction1(self):
     """Tests the refractive functions after a single intersection"""
     self.engine = TracerEngine(self.assembly)
     ans = self.engine.ray_tracer(self._bund, 1, .05)
     params = N.arctan(ans[1][1] / ans[1][2])
     correct_params = N.r_[0.785398163, -.4908826]
     N.testing.assert_array_almost_equal(params, correct_params)
예제 #9
0
    def test_absorbed_to_back(self):
        """Absorbed rays moved to back of recorded bundle"""
        engine = TracerEngine(self.assembly)
        engine.ray_tracer(self.bund, 300, .05)

        parents = engine.tree.ordered_parents()
        N.testing.assert_equal(parents, [N.r_[2, 3, 0, 1]])
예제 #10
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)
예제 #11
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)
예제 #12
0
    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)
예제 #13
0
    def test_assembly1(self):
        """Tests the assembly after one iteration"""
        self.engine = TracerEngine(self.assembly)
        ans = self.engine.ray_tracer(self._bund, 1, .05)
        params = N.arctan(ans[1][1] / ans[1][2])
        correct_params = N.r_[0.7853981, 0]

        N.testing.assert_array_almost_equal(params, correct_params)
예제 #14
0
    def test_cylinder_height(self):
        """The bounding cylinder exists for planoconvex lens"""
        f = self.lens.focal_length()
        rb = RayBundle(N.c_[[0., 0., -0.01]], N.c_[[1., 0., 0.]],
            energy=N.r_[1.], ref_index=N.r_[1.5])

        e = TracerEngine(Assembly([self.lens]))
        verts, dirs = e.ray_tracer(rb, 1, 1e-6)

        N.testing.assert_array_equal(verts, N.array([]).reshape(3,0))
예제 #15
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)
예제 #16
0
    def test_cylinder(self):
        """The bounding cylinder exists for biconcave lens"""
        f = self.lens.focal_length()
        rb = RayBundle(N.c_[[0., 0., 0.08]], N.c_[[1., 0., 0.]],
            energy=N.r_[1.], ref_index=N.r_[1.5])
        
        e = TracerEngine(Assembly([self.lens]))
        verts, dirs = e.ray_tracer(rb, 1, 1e-6)

        N.testing.assert_array_equal(verts, N.tile(N.c_[[0.5, 0., 0.08]], (1,2)))
        N.testing.assert_array_equal(dirs, N.c_[[-1., 0., 0.], [1., 0., 0.]])
예제 #17
0
 def test_paraxial_ray(self):
     """A paraxial ray reaches the focus of a planoconvex lens"""
     rb = RayBundle(N.c_[[0., 0.001, 1.]], N.c_[[0., 0., -1.]], 
         energy=N.r_[1.], ref_index=N.r_[1.])
     screen = rect_one_sided_mirror(5, 5)
     f = self.lens.focal_length()
     screen.set_transform(translate(0, 0, -f))
     
     e = TracerEngine(Assembly([self.lens, screen]))
     vert, _ = e.ray_tracer(rb, 3, 1e-6)
     
     self.failUnlessAlmostEqual(vert[1,2], 0, 4)
예제 #18
0
    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)
예제 #19
0
    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])
예제 #20
0
    def test_tree1(self):
        """Tests that the tracing tree works, with three rays"""
        x = 1. / (math.sqrt(2))
        dir = N.c_[[0, x, x], [0, -x, x], [0, 0, 1.]]
        position = N.c_[[0, 0, 2.], [0, 0, 2.], [0, 0., 2.]]
        bund = RayBundle(position, dir, energy=N.ones(3))

        self.engine = TracerEngine(self.assembly)

        self.engine.ray_tracer(bund, 3, .05)[0]
        params = self.engine.tree.ordered_parents()
        correct_params = [N.r_[0, 1, 2], N.r_[1, 2], N.r_[0]]
        N.testing.assert_equal(params, correct_params)
예제 #21
0
    def test_aim(self):
        """Aiming heliostats works"""
        elev = N.pi / 4
        az = N.pi / 2
        self.field.aim_to_sun(az, elev)

        e = TracerEngine(self.field)
        v, d = e.ray_tracer(self.rays, 1, 0.05)

        N.testing.assert_array_almost_equal(d[1, :self.pos.shape[0] / 2], 0)
        N.testing.assert_array_almost_equal(d[0, self.pos.shape[0] / 2:], 0)
        N.testing.assert_array_almost_equal(
            abs(d[2] * (v[0] + v[1]) / (d[0] + d[1])), 85.5)
예제 #22
0
    def test_tree2(self):
        """Tests that the tracing tree works, with a new set of rays"""
        x = 1. / (math.sqrt(2))
        position = N.c_[[0, 0., -5.], [0, 0., 2.], [0, 2., -5.], [0, 0., 0],
                        [0, 0, 2.]]
        dir = N.c_[[0, 0, 1.], [0, x, -x], [0, 0, -1.], [0, 0, 1.], [0, -x, x]]
        bund = RayBundle(position, dir, energy=N.ones(5))

        self.engine = TracerEngine(self.assembly)
        self.engine.ray_tracer(bund, 3, .05)[0]

        params = self.engine.tree.ordered_parents()
        correct_params = [N.r_[0, 1, 3, 4], N.r_[2, 3, 1], N.r_[2, 1]]
        N.testing.assert_equal(params, correct_params)
예제 #23
0
    def trace(self):
        # define the tracer engine
        e = TracerEngine(self.system)
        e.minerer=1e-10

        #define the rays
        rays=self.gen_rays()

        # ray-tracing
        e.ray_tracer(rays, reps=100, min_energy=1e-10)

        if self.rendering:
            trace_scene=Renderer(e)
            trace_scene.show_rays(resolution=10)		     
예제 #24
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])
예제 #25
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)
예제 #26
0
    def setUp(self):
        asm = homogenizer.rect_homogenizer(1., 1., 1.2, 1.)

        # 4 rays starting somewhat above (+z) the homogenizer
        pos = N.zeros((3, 4))
        pos[2] = 1.5

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

        self.bund = RayBundle(pos,
                              dir,
                              ref_index=N.ones(4),
                              energy=N.ones(4) * 4.)
        self.engine = TracerEngine(asm)
예제 #27
0
    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)
예제 #28
0
    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))
예제 #29
0
    def test_move_vertices(self):
        """Moving a vertex on a face set replaces the touching surfaces."""
        # Let's create a hexahedron, then move one vertex to make a
        # tetrahedron.

        # Face set:
        verts = np.vstack((np.zeros(3), np.eye(3), np.ones(3)))
        # origin + unit along each axis
        faces = np.array([
            [0, 1, 2],
            [0, 1, 3],
            [0, 2, 3],  # bottom tetrahedron
            [4, 1, 2],
            [4, 1, 3],
            [4, 2, 3]
        ])
        trisurf = TriangulatedSurface(verts, faces, perfect_mirror)
        assembly = Assembly(objects=[trisurf])

        # Transformation:
        trisurf.move_vertices(np.r_[4], np.ones((1, 3)) * np.sqrt(2))

        # 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)))
예제 #30
0
    def setUp(self):

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

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

        self.engine = TracerEngine(assembly)