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)
def setUp(self): self.eighth_circle_trans = generate_transform(N.r_[1., 0, 0], N.pi / 4, N.c_[[0., 1, 0]]) self.surf = Surface(flat_surface.FlatGeometryManager(), \ optics_callables.perfect_mirror) self.obj = AssembledObject(surfs=[self.surf]) self.sub_assembly = Assembly() self.sub_assembly.add_object(self.obj, self.eighth_circle_trans) self.assembly = Assembly() self.assembly.add_assembly(self.sub_assembly, self.eighth_circle_trans)
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 gen_plant(self, width=6.1, height=6.1, absorptivity=0.04, aim_height=60., sigma_xy=1e-3, rec_w=11., rec_h=11.): self.pos[:, 1] = self.pos[:, 1] - 4. # correction for the true position of the plate on the tower. self.width = width self.height = height self.absorptivity = absorptivity self.field = HeliostatField(self.pos, width, height, absorptivity, aim_height, sigma_xy) self.rec_w = rec_w self.rec_h = rec_h rec, recobj = one_sided_receiver(self.rec_w, self.rec_h) rec_trans = rotx(N.pi / -2) rec_trans[2, 3] = self.field._th # Evaluating just the receiver recobj.set_transform(rec_trans) self.plant = Assembly(objects=[recobj], subassemblies=[self.field])
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)))
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))
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])
def gen_plant(self): """Generates the entire plant""" # set heliostat field characteristics: 6.09m*6.09m, abs = 0.04, aim_location_xyz =60 self.field = HeliostatGenerator(self.helio_w, self.helio_h, self.helio_abs, self.helio_sigmaxy, slope='normal', curved=True, pos=self.pos, foc=self.helio_focal) self.field( KnownField(self.heliostatcsv, self.pos, N.array([self.helio_focal]).T)) #field(layout) heliostats = Assembly(objects=self.field._heliostats) aiming = SinglePointAiming(self.pos, self.recv_centre, False) if self.helio_tracking == 'TiltRoll': tracking = TiltRoll(solar_vector(self.azimuth, self.zenith), False) elif self.helio_tracking == 'AzEl': tracking = AzElTrackings(solar_vector(self.azimuth, self.zenith), False) tracking.aim_to_sun(-self.pos, aiming.aiming_points, False) tracking(self.field) self.plant = Assembly(objects=[self.recv_obj], subassemblies=[heliostats]) ##### Calculate Total Recv area ##### areacount = 0. corners = self.recv_surf.mesh( 0) #corners is an array of all corners of the plate # BLC is bottom left corner "origin" of the histogram plot # BRC is the bottom right corner "x-axis" used for vector u # TLC is the top right corner "y-axis" used for vector v BLC = N.array([corners[0][1][1], corners[1][1][1], corners[2][1][1]]) BRC = N.array([corners[0][0][1], corners[1][0][1], corners[2][0][1]]) TLC = N.array([corners[0][1][0], corners[1][1][0], corners[2][1][0]]) # Get vectors u and v in array form of array([x,y,z]) u = BRC - BLC v = TLC - BLC # Get width(magnitude of u) and height(magnitude of v) in float form w = (sum(u**2))**0.5 h = (sum(v**2))**0.5 areacount += w * h self.recv_area = areacount print("Reciver area", self.recv_area)
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))
def gen_plant(self): # set heliostat field characteristics: 6.09m*6.09m, abs = 0, aim_h = 61 self.pos[:, 1] = self.pos[:, 1] - 4. # correct6ion for the true position of the plate on the tower. self.field = HeliostatField(self.pos, 6.09, 6.09, absorptivity=0.04, aim_height=60, sigma_xy=1e-3, option=None) self.rec_w = 11 self.rec_h = 11 self.rec, recobj = one_sided_receiver(self.rec_w, self.rec_h) rec_trans = rotx(N.pi / -2) rec_trans[2, 3] = self.field._th #================= ground_rec = False #================= if ground_rec: # Evaluating missed rays in the field along with receiver radius = 1.10 * math.sqrt((self.x_dist / 2)**2 + (self.y_dist / 2)**2) self.ground_rec, ground_recobj = one_sided_receiver( 3 * radius, 3 * radius) ground_rec_trans = rotz(0) ground_rec_trans[0, 3] = self.field_centre[0] ground_rec_trans[1, 3] = self.field_centre[1] recobj.set_transform(rec_trans) ground_recobj.set_transform(ground_rec_trans) self.plant = Assembly(objects=[recobj, ground_recobj], subassemblies=[self.field]) else: # Evaluating just the receiver recobj.set_transform(rec_trans) self.plant = Assembly(objects=[recobj], subassemblies=[self.field])
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 gen_plant(self): xy = radial_stagger(-N.pi/4, N.pi/4 + 0.0001, self.ang_res, 5, 20, self.radial_res) self.pos = N.hstack((xy, N.zeros((xy.shape[0], 1)))) self.field = HeliostatField(self.pos, 0.5, 0.5, 0, 10) self.rec, recobj = one_sided_receiver(1., 1.) rec_trans = roty(N.pi/2) rec_trans[2,3] = 10 recobj.set_transform(rec_trans) self.plant = Assembly(objects=[recobj], subassemblies=[self.field])
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.]])
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)
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 setUp(self): """ Prepare an assembly with two subassemblies: one assembly representing a spherical lens behind a flat screen, and one asssembly representing a perfect mirror. The mirror will be placed at the two subassemblies' focus, so a paraxial ray will come back on the other side of the optical axis. Reference: In [1], the lensmaker equation """ # focal length = 1, thickness = 1/6 R = 1. / 6. back_surf = Surface(HemisphereGM(R), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., -R / 2.]) front_surf = Surface(HemisphereGM(R), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., R / 2.], rotation=rotx(N.pi / 2.)[:3, :3]) front_lens = AssembledObject(surfs=[back_surf, front_surf]) back_surf = Surface(RoundPlateGM(R), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., -0.01]) front_surf = Surface(RoundPlateGM(R), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., 0.01]) glass_screen = AssembledObject(surfs=[back_surf, front_surf], transform=translate(0., 0., 0.5)) lens_assembly = Assembly(objects=[glass_screen, front_lens]) lens_assembly.set_transform(translate(0., 0., 1.)) full_assembly = Assembly(objects=[rect_one_sided_mirror(1., 1., 0.)], subassemblies=[lens_assembly]) self.engine = TracerEngine(full_assembly)
def setUp(self): self.assembly = Assembly() surface1 = Surface(Paraboloid(), optics_callables.perfect_mirror) self.object = AssembledObject() self.object.add_surface(surface1) self.assembly.add_object(self.object) x = 1. / (math.sqrt(2)) dir = N.c_[[0, 0, -1.], [0, x, -x]] position = N.c_[[0, 0, 1.], [0, 0, 1.]] self._bund = RayBundle(position, dir, energy=N.ones(2), ref_index=N.ones(2))
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])
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 setUp(self): absorptive = Surface(RectPlateGM(1., 1.), opt.Reflective(1.), location=N.r_[0.5, 0., 1.]) reflective = Surface(RectPlateGM(1., 1.), opt.Reflective(0.), location=N.r_[-0.5, 0., 1.]) self.assembly = Assembly( objects=[AssembledObject(surfs=[absorptive, reflective])]) # 4 rays: two toward absorptive, two toward reflective. pos = N.zeros((3, 4)) pos[0] = N.r_[0.5, 0.25, -0.25, -0.5] direct = N.zeros((3, 4)) direct[2] = 1. self.bund = RayBundle(pos, direct, energy=N.ones(4))
def setUp(self): self.assembly = Assembly() surface1 = Surface(FlatGeometryManager(), opt.perfect_mirror) self.object1 = AssembledObject() self.object1.add_surface(surface1) boundary = BoundarySphere(location=N.r_[0, 0., 3], radius=3.) surface3 = Surface(CutSphereGM(2., boundary), opt.perfect_mirror) self.object2 = AssembledObject() self.object2.add_surface(surface3) self.transform1 = generate_transform(N.r_[1., 0, 0], N.pi / 4, N.c_[[0, 0, -1.]]) self.transform2 = translate(0., 0., 2.) self.assembly.add_object(self.object1, self.transform1) self.assembly.add_object(self.object2, self.transform2)
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)
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)
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)))
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 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.5, 1.), location=N.array([0, 0, 1.])) self.object = AssembledObject(surfs=[surface1, surface2]) self.assembly.add_object(self.object) x = 1 / (math.sqrt(2)) dir = N.c_[[0, -x, x]] position = N.c_[[0, 1, -2.]] self._bund = RayBundle(position, dir, energy=N.r_[1.], ref_index=N.r_[1.])
def test_image_size(self): """Image size of an object imaged by a biconcave lens matches theory""" origin = N.c_[[0., 0.001, 1.]] direct = -origin / N.linalg.norm(origin) rb = RayBundle(origin, direct, energy=N.r_[1.], ref_index=N.r_[1.]) # Magnification, see [1] p. 26. f = self.lens.focal_length() m = f / (origin[2] + f) # Image location, [ibid]: loc = origin[2] * m screen = rect_one_sided_mirror(5, 5) screen.set_transform(translate(0, 0, -loc)) e = TracerEngine(Assembly([self.lens, screen])) vert, _ = e.ray_tracer(rb, 3, 1e-6) self.failUnlessAlmostEqual(vert[1, 2], -m * origin[1], 4)
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)