def test_case(focus, num_rays=100, h_depth=0.7, side=0.4): # Case parameters: D = 5. center = N.c_[[0, 7., 7.]] x = -1/(math.sqrt(2)) direction = N.array([0,x,x]) radius_sun = 3. 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) resolution = 20 # Render a subset of the total rays: v = R(engine) v.show_rays(max_rays=100, resolution=resolution, fluxmap=True) # Plot, scale in suns: f = plot_hits(assembly.histogram_hits(bins=resolution)[0]/(side/resolution)**2/1000., (-side/2., side/2., -side/2., side/2.)) f.show()
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_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()
def test_transformed(self): """A transformed triangle excludes rays correctly""" frame = np.dot(translate(0, -1, 0.5), rotx(np.pi/4.)) prm = self.tri.find_intersections(frame, self.bund) np.testing.assert_array_equal(np.isfinite(prm), np.r_[False, False, True, False, False, True])
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 test_rotated(self): """Rotate cylinder by 30 degrees""" frame = rotx(N.pi / 6) ydist = 0.5 / N.cos(N.pi / 6) # Ray parameter of slanted rays using sine law: p1 = N.sin(2 * N.pi / 3) * (1 - ydist) / N.sin(N.pi / 12) p2 = N.sin(N.pi / 3) * ydist / N.sin(5 * N.pi / 12) correct_prm = N.r_[ydist, p2, 1 - ydist, p1] prm = self.gm.find_intersections(frame, self.bund) N.testing.assert_array_almost_equal(prm, correct_prm) self.gm.select_rays(N.arange(4)) outwrd = N.r_[0., N.cos(N.pi / 6), 0.5] correct_norm = N.c_[-outwrd, -outwrd, outwrd, outwrd] norm = self.gm.get_normals() N.testing.assert_array_almost_equal(norm, correct_norm) correct_pts = N.c_[[0., ydist, 0.], [0., p2 * N.sqrt(0.5), p2 * N.sqrt(0.5)], [0., ydist, 0.], [0., 1 - p1 * N.sqrt(0.5), p1 * N.sqrt(0.5)]] pts = self.gm.get_intersection_points_global() N.testing.assert_array_almost_equal(pts, correct_pts)
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(FlatGeometryManager(), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., -0.01]) front_surf = Surface(FlatGeometryManager(), 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 gen_plant(self): """Generates the entire plant""" # set heliostat field characteristics: 0.52m*0.52m, abs = 0, aim_h =61 self.field = HeliostatField(self.pos, 6.09e-1, 6.09e-1, 0, 6.1, 1e-3) # generates a transformation matrix of the receiver rec_trans for rotations rx_M = N.matrix(rotx(self.rx)) ry_M = N.matrix(rotx(self.ry)) rz_M = N.matrix(rotx(self.rz)) rec_trans = N.array((rx_M)*(ry_M)*(rz_M)) # applies translations to the rotation matrix to get the final transformation rec_trans[0,3] = self.dx rec_trans[1,3] = self.dy rec_trans[2,3] = self.dz # applies the transformation to the receiver object self.rec_obj.set_transform(rec_trans) # combines all objects into a single plant self.plant = Assembly(objects = [self.rec_obj], subassemblies=[self.field])
def test_rotated(self): """Rotate finite cylinder by 30 degrees""" frame = rotx(N.pi/6) correct_prm = N.empty(8) correct_prm.fill(N.inf) prm = self.gm.find_intersections(frame, self.bund) N.testing.assert_array_equal(prm, correct_prm)
def test_rotated(self): """Rotate finite cylinder by 30 degrees""" frame = rotx(N.pi / 6) correct_prm = N.empty(8) correct_prm.fill(N.inf) prm = self.gm.find_intersections(frame, self.bund) N.testing.assert_array_equal(prm, correct_prm)
def gen_plant(self): # import custom coordinate file self.pos = N.loadtxt("sandia_hstat_coordinates.csv", delimiter=',') self.pos *= 0.1 # set heliostat field characteristics: 0.52m*0.52m, abs = 0, aim_h = 61 self.field = HeliostatField(self.pos, 6.09e-1, 6.09e-1, 0, 6.1,1e-3) self.reclist, recobj = one_sided_receiver(1.0, 1.0, 0.8) rec_trans = rotx(N.pi/-2) # originally N.pi/2, changed to minus rotx(N.pi/-2) print(recobj) rec_trans[2,3] = 6.1 # height of the tower original 6.1 recobj.set_transform(rec_trans) self.plant = Assembly(objects=[recobj], subassemblies=[self.field])
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 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 __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 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): """ 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 test_rotated(self): """Rotate cylinder by 30 degrees""" frame = rotx(N.pi/6) ydist = 0.5/N.cos(N.pi/6) # Ray parameter of slanted rays using sine law: p1 = N.sin(2*N.pi/3) * (1 - ydist) / N.sin(N.pi/12) p2 = N.sin(N.pi/3) * ydist / N.sin(5*N.pi/12) correct_prm = N.r_[ydist, p2 , 1 - ydist, p1] prm = self.gm.find_intersections(frame, self.bund) N.testing.assert_array_almost_equal(prm, correct_prm) self.gm.select_rays(N.arange(4)) outwrd = N.r_[0., N.cos(N.pi/6), 0.5] correct_norm = N.c_[-outwrd, -outwrd, outwrd, outwrd] norm = self.gm.get_normals() N.testing.assert_array_almost_equal(norm, correct_norm) correct_pts = N.c_[ [0., ydist, 0.], [0., p2*N.sqrt(0.5), p2*N.sqrt(0.5)], [0., ydist, 0.], [0., 1 - p1*N.sqrt(0.5), p1*N.sqrt(0.5)]] pts = self.gm.get_intersection_points_global() N.testing.assert_array_almost_equal(pts, correct_pts)
def test_plane(self): """Translated plane section of a volume""" plane = BoundaryPlane(rotation=rotx(-N.pi/6)[:3,:3], location=N.r_[0., 1., 0.]) N.testing.assert_array_equal(plane.in_bounds(self.points), [False, True, True])
def test_plane(self): """Translated plane section of a volume""" plane = BoundaryPlane(rotation=rotx(-N.pi / 6)[:3, :3], location=N.r_[0., 1., 0.]) N.testing.assert_array_equal(plane.in_bounds(self.points), [False, True, True])