예제 #1
0
	def traceMP(self, rays_per_run, iters = 10000, minE = 1e-9, render = False,procs = 1):
		"""Commences raytracing using (rph) number of rays per heliostat, for a maximum of 
		   (iters) iterations, discarding rays with energy less than (minE). If render is
		   True, a 3D scene will be displayed which would need to be closed to proceed."""
		# Get the solar vector using azimuth and elevation
		sun_vec = solar_vector(self.sun_az*degree, self.sun_elev*degree)
		rot_sun = rotation_to_z(-sun_vec)
        	# Calculate number of rays used. Rays per heliostat * number of heliostats.
		rppph = int(rays_per_run/(procs*len(self.field.get_heliostats())))
		rpp = rppph*len(self.field.get_heliostats())
		rpr = rpp*procs					#actual rays per run used

		ray_sources = []
		n = 1
		while n <= procs:
			direct = N.dot(rot_sun, pillbox_sunshape_directions(rpp, 0.00465))
			xy = N.random.uniform(low=-0.25, high=0.25, size=(2, rpp))
        		base_pos = N.tile(self.pos, (rppph, 1)).T
        		base_pos += N.dot(rot_sun[:,:2], xy)

        		base_pos -= direct
        		rays = RayBundle(base_pos, direct, energy=N.ones(rpp))
			ray_sources.append(rays)
			n += 1

		e = TracerEngineMP(self.plant)
		e.multi_ray_sim(ray_sources,procs)
		self.plant = e._asm
		self.helio_hits = sum(e.tree._bunds[1].get_energy())
			# Note that you may need some stuff in here
		if render == True:
			trace_scene = Renderer(e)
			trace_scene.show_rays(resolution=10)
			render = False

		return rpr #this is special
예제 #2
0
	def trace(self):
		'''
		Raytrace method.

		Raytraces successive bundles and stores the resultsogf the shading, blicking, incoming radiative power on the heliostats and the fluxmap on the receiver.
		'''
		# Generate a large ray bundle using [a radial stagger much denser
		# than the field] a Buie sunshape with radius equal to the longest
		# dimension of the field.

		#=============
		render = False
		#=============
		
		sun_vec = solar_vector(self.sun_az*degree, self.sun_elev*degree)
		
		# Generate the following number of rays
		num_rays = 500000.
		iters = 40

		# Results bins:
		incoming = N.zeros(len(self.pos))
		prev_incoming = N.zeros(len(self.pos))
		incoming_Q = N.zeros(len(self.pos))
		incoming_stdev = N.zeros(len(self.pos))

		shading = N.ones(len(self.pos))
		prev_shading = N.zeros(len(self.pos))
		shading_Q = N.zeros(len(self.pos))
		shading_stdev = N.zeros(len(self.pos))

		blocking = N.zeros(len(self.pos))
		prev_blocking = N.zeros(len(self.pos))
		blocking_Q= N.zeros(len(self.pos))
		blocking_stdev= N.zeros(len(self.pos))

		timer_mcrt = 0. 
		timer_postprocess = 0.

		# Receiver bins:
		dl=11./50.
		bins = N.arange(-5.5,5.5+dl, dl)
		fluxmap = N.zeros((len(bins)-1,len(bins)-1))

		# Raytrace:
		mcrt = time.clock()
		e = TracerEngineMP(self.plant)
		procs = 8
		e.minener = 1e-10
		timer_mcrt += time.clock()-mcrt
		hits_helios=0
		i=0

		#while hits_helios < 20e6:
		for i in xrange(iters):
			print ' '
			print ' '
			print 'ITERATION ', i+1#, ' of ', iters 
			mcrt = time.clock()
			# Perform the trace:
			sources = []
			self.flux = 1000.
			for s in xrange(procs):
				sources.append(self.gen_rays(num_rays/float(procs), flux=self.flux/float(procs)))
			e.multi_ray_sim(sources, procs)
			self.plant = e._asm
			self.field._heliostats = self.plant._assemblies[0].get_surfaces()
			self.rec = self.plant._objects[0].get_surfaces()[0]

			timer_mcrt += time.clock()-mcrt
			postprocess = time.clock()

			# Render:
			if render:
				trace_scene = Renderer(e)
				trace_scene.show_rays(resolution=10)

			# Get the energy and location of all hits using optics manager
			en, pts = self.rec.get_optics_manager().get_all_hits()
			x, y = self.rec.global_to_local(pts)[:2]

			# FLUX MAP OPERATIONS
			#===========================================================================
			H, xbins, ybins = N.histogram2d(x, y, bins, weights=en)
			extent = [ybins[0], ybins[-1], xbins[-1], xbins[0]]

			fluxmap = (fluxmap*float(i)+H/(1000.*dl**2.))/(i+1.)
			#===========================================================================
		
			# BLOCKAGE and SHADING
			#===========================================================================
			# Detect blockage and look for the parents of the blocked rays. Identify from which heliostats teh oarents come and associate the blockage losses to the heliostats where blockage is suffered.
			
			hz = (e.tree._bunds[1].get_vertices()[2]) < (self.field._th-self.rec_h/2.)
			hits_helios += N.sum(hz)
			print 'Useful rays:', hits_helios
			# Get the 3rd bundle (after 2 hits):
			bund_2 = e.tree._bunds[2].get_vertices()
			bund_2_ener = e.tree._bunds[2].get_energy()

			# Remove receiver hits from the bundle to get only hits on heliostats:
			bund_2_helio_hits = N.ravel(N.nonzero(bund_2[2] < (self.field._th-self.rec_h/2.)))
			bund_2_bloc = bund_2[:, bund_2_helio_hits]

			# Get the bundle emitting the blocked rays and isolate the blocked rays:
			bund_1_helio_blocs = e.tree._bunds[2].get_parents()[bund_2_helio_hits]
			bund_1 = e.tree._bunds[1].get_vertices()
			bund_1_ener = e.tree._bunds[1].get_energy()
			bund_1_bloc = bund_1[:, bund_1_helio_blocs]

			# Screen the field to find where blocked rays originate:
			for h in xrange(len(self.pos)):
				# Get the information from the optics manager of the heliostat:
				abs_hstats, hits_hstats, dirs_hstats = self.field._heliostats[h].get_optics_manager().get_all_hits()

				blocs = []
				hit_0s = []

				# Check if any hits:
				if len(hits_hstats)!=0:
					# Screen through every hit:
					for r in xrange(N.shape(hits_hstats)[1]):
						# Is the hit a ray that will be blocked or a blocked ray?
						bloc = N.nonzero(hits_hstats[0,r] == bund_1_bloc[0])[0]
						# Next "if" is because if there are no valid hits the bloc returns an empty array or to isolate each hit in case of 2 hits matching.
						if len(bloc)>0:
							for b in xrange(len(bloc)):
								# If sthe first coordinate matches, do the rest of them?
								if (hits_hstats[:,r]==N.ravel(bund_1_bloc[:,bloc[b]])).all():
									# If so add the blocked energy to the result bin.
									blocs.append(bund_1_helio_blocs[bloc[b]])

						else:
							hit_0 = N.nonzero(hits_hstats[0,r] == bund_1[0])[0]
							if len(hit_0)>0:
								for s in xrange(len(hit_0)):
									if (hits_hstats[:,r]==N.ravel(bund_1[:,hit_0[s]])).all():			
										hit_0s.append(e.tree._bunds[1].get_parents()[hit_0[s]])
				prev_blocking[h] = blocking[h]

				# Monte-Carlo sampling:
				blocking[h] = (blocking[h]*i+N.sum(bund_1_ener[blocs]))/(i+1.)		

				# Shading is the theoretical energy hitting subtracted by the energy absorbed without the backside blocking.
				prev_incoming[h] = incoming[h]
				# Monte-Carlo sampling:
				incoming[h] = (incoming[h]*i+N.sum(e.tree._bunds[0].get_energy()[hit_0s]))/(i+1.)

				prev_shading[h] = shading[h]
				# Monte-Carlo sampling:
				shading[h] = (shading[h]*i+self.flux*self.hstat_proj_areas[h]-incoming[h])/(i+1.)
				
			# Streamlined stats variable:
			incoming_Q = incoming_Q+i/(i+1.)*(incoming-prev_incoming)**2.
			blocking_Q = blocking_Q+i/(i+1.)*(blocking-prev_blocking)**2.
			shading_Q = shading_Q+i/(i+1.)*(shading-prev_shading)**2.

			# Standard deviatiosn updates:
			if i>0:
				incoming_stdev = N.sqrt(incoming_Q/i)
				blocking_stdev = N.sqrt(blocking_Q/i)
				shading_stdev = N.sqrt(shading_Q/i)

			print 'Shading=', N.sum(shading)
			print 'Blockage=', N.sum(blocking)

			timer_postprocess += time.clock()-postprocess

			print 'timer_mcrt: ', timer_mcrt/60., 'min'
			print 'timer_postprocess: ', timer_postprocess/60., 'min'

			print 'Peak flux (kW/m2):', N.amax(fluxmap)
			print 'AVG flux (kW/m2): ', N.sum(fluxmap)/(N.shape(fluxmap)[0]*N.shape(fluxmap)[1])
			print 'Total radiative power (kW): ', N.sum(fluxmap*(11./50.)**2)

			i+=1
		
			#===========================================================================
			e.tree._bunds = []
			for clear in xrange(len(e._asm.get_surfaces())):
				e._asm.get_surfaces()[clear].get_optics_manager().reset()
			#===========================================================================
		'''
예제 #3
0
    def trace(self, num_rays=1e5, nbins_w=50., nbins_h=50.):
        '''
		Raytrace method.

		Raytraces successive bundles and stores the resultsogf the shading, blicking, incoming radiative power on the heliostats and the fluxmap on the receiver.
		'''
        # Generate a large ray bundle using [a radial stagger much denser
        # than the field] a Buie sunshape with radius equal to the longest
        # dimension of the field.

        #=============
        render = False
        #=============

        sun_vec = solar_vector(self.sun_az * degree, self.sun_zenith * degree)

        bundlesize = 1e4
        iters = int(num_rays / bundlesize)

        # Results bins:
        incoming = N.zeros(len(self.pos))
        prev_incoming = N.zeros(len(self.pos))
        incoming_Q = N.zeros(len(self.pos))
        incoming_stdev = N.zeros(len(self.pos))

        shading = N.ones(len(self.pos))
        prev_shading = N.zeros(len(self.pos))
        shading_Q = N.zeros(len(self.pos))
        shading_stdev = N.zeros(len(self.pos))

        blocking = N.zeros(len(self.pos))
        prev_blocking = N.zeros(len(self.pos))
        blocking_Q = N.zeros(len(self.pos))
        blocking_stdev = N.zeros(len(self.pos))

        timer_mcrt = 0.
        timer_postprocess = 0.

        # Receiver bins:

        dlw = self.rec_w / nbins_w
        dlh = self.rec_h / nbins_h
        bins_w = N.arange(-self.rec_w / 2., self.rec_w / 2. + dlw, dlw)
        bins_h = N.arange(-self.rec_h / 2., self.rec_h / 2. + dlh, dlh)
        bins = [bins_w, bins_h]
        self.bins = bins
        fluxmap = N.zeros((len(bins_w) - 1, len(bins_h) - 1))

        # Raytrace:
        mcrt = time.clock()
        e = TracerEngineMP(self.plant)
        procs = 1
        e.minener = 1e-10
        timer_mcrt += time.clock() - mcrt
        hits_helios = 0
        i = 0

        #while hits_helios < num_rays:
        for i in xrange(iters):
            print ' '
            print ' '
            print 'ITERATION ', i + 1, ' of ', iters
            #print hits_helios, 'hits out of ', num_rays
            mcrt = time.clock()
            # Perform the trace:
            sources = []
            self.flux = 1000.
            for s in xrange(procs):
                sources.append(
                    self.gen_rays(num_rays=bundlesize / float(procs),
                                  flux=self.flux / float(procs)))
            e.multi_ray_sim(sources=sources, procs=procs)
            self.plant = e._asm
            self.field._heliostats = self.plant._assemblies[0].get_surfaces()
            self.rec = self.plant._objects[0].get_surfaces()[0]

            timer_mcrt += time.clock() - mcrt
            postprocess = time.clock()

            # Render:
            if render:
                trace_scene = Renderer(e)
                trace_scene.show_rays(resolution=10)

            # Get the energy and location of all hits using optics manager
            en, pts = self.rec.get_optics_manager().get_all_hits()
            x, y = self.rec.global_to_local(pts)[:2]

            # FLUX MAP OPERATIONS
            #===========================================================================
            H, xbins, ybins = N.histogram2d(x,
                                            y,
                                            bins,
                                            weights=en / (dlw * dlh) * 1e-3)
            extent = [ybins[0], ybins[-1], xbins[-1], xbins[0]]

            fluxmap = (fluxmap * float(i) + H) / (i + 1.)
            #===========================================================================

            # BLOCKAGE and SHADING
            #===========================================================================
            # Detect blockage and look for the parents of the blocked rays. Identify from which heliostats the parents come and associate the blockage losses to the heliostats where blockage is suffered.

            hz = (e.tree._bunds[1].get_vertices()[2]) < (self.field._th -
                                                         self.rec_h / 2.)
            hits_helios += N.sum(hz)
            print 'Useful rays:', hits_helios
            # Get the 3rd bundle (after 2 hits):
            bund_2 = e.tree._bunds[2].get_vertices()
            bund_2_ener = e.tree._bunds[2].get_energy()

            # Remove receiver hits from the bundle to get only hits on heliostats:
            bund_2_helio_hits = N.ravel(
                N.nonzero(bund_2[2] < (self.field._th - self.rec_h / 2.)))
            bund_2_bloc = bund_2[:, bund_2_helio_hits]

            # Get the bundle emitting the blocked rays and isolate the blocked rays:
            bund_1_helio_blocs = e.tree._bunds[2].get_parents(
            )[bund_2_helio_hits]
            bund_1 = e.tree._bunds[1].get_vertices()
            bund_1_ener = e.tree._bunds[1].get_energy()
            bund_1_bloc = bund_1[:, bund_1_helio_blocs]

            # Screen the field to find where blocked rays originate:
            for h in xrange(len(self.pos)):
                # Get the information from the optics manager of the heliostat:
                abs_hstats, hits_hstats, dirs_hstats = self.field._heliostats[
                    h].get_optics_manager().get_all_hits()

                blocs = []
                hit_0s = []

                # Check if any hits:
                if len(hits_hstats) != 0:
                    # Screen through every hit:
                    for r in xrange(N.shape(hits_hstats)[1]):
                        # Is the hit a ray that will be blocked or a blocked ray?
                        bloc = N.nonzero(hits_hstats[0,
                                                     r] == bund_1_bloc[0])[0]
                        # Next "if" is because if there are no valid hits the bloc returns an empty array or to isolate each hit in case of 2 hits matching.
                        if len(bloc) > 0:
                            for b in xrange(len(bloc)):
                                # If sthe first coordinate matches, do the rest of them?
                                if (hits_hstats[:, r] == N.ravel(
                                        bund_1_bloc[:, bloc[b]])).all():
                                    # If so add the blocked energy to the result bin.
                                    blocs.append(bund_1_helio_blocs[bloc[b]])

                        else:
                            hit_0 = N.nonzero(hits_hstats[0,
                                                          r] == bund_1[0])[0]
                            if len(hit_0) > 0:
                                for s in xrange(len(hit_0)):
                                    if (hits_hstats[:, r] == N.ravel(
                                            bund_1[:, hit_0[s]])).all():
                                        hit_0s.append(
                                            e.tree._bunds[1].get_parents()[
                                                hit_0[s]])
                prev_blocking[h] = blocking[h]

                # Monte-Carlo sampling:
                blocking[h] = (blocking[h] * i +
                               N.sum(bund_1_ener[blocs])) / (i + 1.)

                # Shading is the theoretical energy hitting subtracted by the energy absorbed without the backside blocking.
                prev_incoming[h] = incoming[h]
                # Monte-Carlo sampling:
                incoming[h] = (incoming[h] * i + N.sum(
                    e.tree._bunds[0].get_energy()[hit_0s])) / (i + 1.)

                prev_shading[h] = shading[h]
                # Monte-Carlo sampling:
                shading[h] = (shading[h] * i +
                              self.flux * self.hstat_proj_areas[h] -
                              incoming[h]) / (i + 1.)

            # Streamlined stats variable:
            incoming_Q = incoming_Q + i / (i + 1.) * (incoming -
                                                      prev_incoming)**2.
            blocking_Q = blocking_Q + i / (i + 1.) * (blocking -
                                                      prev_blocking)**2.
            shading_Q = shading_Q + i / (i + 1.) * (shading - prev_shading)**2.

            # Standard deviatiosn updates:
            if i > 0:
                incoming_stdev = N.sqrt(incoming_Q / i)
                blocking_stdev = N.sqrt(blocking_Q / i)
                shading_stdev = N.sqrt(shading_Q / i)

            print 'Shading=', N.sum(shading)
            print 'Blockage=', N.sum(blocking)

            timer_postprocess += time.clock() - postprocess

            print 'timer_mcrt: ', timer_mcrt / 60., 'min'
            print 'timer_postprocess: ', timer_postprocess / 60., 'min'

            print 'Peak flux (kW/m2):', N.amax(fluxmap)
            print 'AVG flux (kW/m2): ', N.sum(fluxmap) / (N.shape(fluxmap)[0] *
                                                          N.shape(fluxmap)[1])
            print 'Total radiative power (kW): ', N.sum(fluxmap *
                                                        (11. / 50.)**2)

            i += 1

            #===========================================================================
            e.tree._bunds = []
            for clear in xrange(len(e._asm.get_surfaces())):
                e._asm.get_surfaces()[clear].get_optics_manager().reset()
            #===========================================================================
            del (self.plant)
        results = {
            'positions': self.pos,
            'blocking': blocking,
            'blocking_stdev': blocking_stdev,
            'shading': shading,
            'shading_stdev': shading_stdev,
            'incoming': incoming,
            'incoming_stdev': incoming_stdev,
            'fluxmap': fluxmap,
            'extent': extent,
            'width': self.width,
            'height': self.height,
            'absorptivity': self.absorptivity,
            'rec_width': self.rec_w,
            'rec_height': self.rec_h,
            'rec_bins': self.bins
        }
        filesave = open(
            '/home/charles/Documents/Boulot/These/Heliostat field/Sandia_data',
            'w')
        pickle.dump(results, filesave)
        filesave.close()