def Initialize(self, input_dict):
     super().Initialize(input_dict)
     km = 2 * np.pi / input_dict['inner scale']
     k0 = 2 * np.pi / input_dict['outer scale']
     Ns = input_dict['grid']
     ds = (self.Lx / (Ns[0] - 1), self.Ly / (Ns[1] - 1)
           )  # make it so outer nodes lie on boundary
     kc = (np.pi / ds[0], np.pi / ds[1])
     kx = np.fft.ifftshift(grid_tools.cyclic_nodes(-kc[0], kc[0], Ns[0]))
     ky = np.fft.ifftshift(grid_tools.cyclic_nodes(-kc[1], kc[1], Ns[1]))
     k2 = np.outer(kx**2, np.ones(Ns[1])) + np.outer(np.ones(Ns[0]), ky**2)
     screen = np.exp(-k2 / km**2) * (0j + k2 + k0**2)**(-11 / 6)
     pos = lambda i: slice(1, int(Ns[i] / 2))
     neg = lambda i: slice(int(Ns[i] / 2) + 1, Ns[i])
     crit = lambda i: int(Ns[i] / 2)
     screen *= np.random.random(Ns) - 0.5 + 1j * np.random.random(Ns) - 0.5j
     screen[neg(0), neg(1)] = np.conj(screen[pos(0), pos(1)][::-1, ::-1])
     screen[neg(0), pos(1)] = np.conj(screen[pos(0), neg(1)][::-1, ::-1])
     screen[0, :] = 0
     screen[:, 0] = 0
     screen[crit(0), :] = np.real(screen[crit(0), :])
     screen[:, crit(1)] = np.real(screen[:, crit(1)])
     screen = np.real(np.fft.ifft(np.fft.ifft(screen, axis=0), axis=1))
     self.screen = 1 + input_dict['amplitude'] * screen / np.max(
         np.abs(screen))
     self.xn = np.linspace(-self.Lx / 2, self.Lx / 2, Ns[0])
     self.yn = np.linspace(-self.Ly / 2, self.Ly / 2, Ns[1])
Esempio n. 2
0
	def GetGridInfo(self):
		w_nodes = self.center[0] + grid_tools.cyclic_nodes(-self.size[0]/2,self.size[0]/2,self.pts[0])
		rho_nodes = grid_tools.cell_centers(0.0,self.size[1]/2,self.pts[1])
		phi_nodes = grid_tools.cyclic_nodes(-np.pi,np.pi,self.pts[2])
		w_walls = grid_tools.cell_walls(w_nodes[0],w_nodes[-1],self.pts[0],self.default_band)
		rho_walls = grid_tools.cell_walls(rho_nodes[0],rho_nodes[-1],self.pts[1])
		phi_walls = grid_tools.cell_walls(phi_nodes[0],phi_nodes[-1],self.pts[2])
		plot_ext = np.array([w_walls[0],w_walls[-1],rho_walls[0],rho_walls[-1],phi_walls[0],phi_walls[-1]])
		return w_nodes,rho_nodes,phi_nodes,plot_ext
Esempio n. 3
0
def PulseSpectrum(xp, box, N, pulse_length, w0):
    '''Weight the rays based their frequency.  Assume transform limited pulse.
	Spectral amplitude is matched with time domain amplitude by performing a test FFT.
	If the lower frequency bound is zero, real carrier resolved fields are used.

	:param numpy.ndarray xp: Ray phase space, primary ray frequency must be loaded
	:param tuple box: The first two elements are the frequency bounds
	:param tuple N: The first element is the number of frequency nodes
	:param pulse_length: The Gaussian pulse width (1/e amplitude)
	:param w0: The central frequency of the wave

	:returns: weight factors with shape (bundles,)'''
    sigma_w = 2.0 / pulse_length
    freq_range = grid_tools.cyclic_nodes(box[0], box[1], N[0])
    # Create a unit-height Gaussian spectral amplitude
    envelope = np.exp(-(freq_range - w0)**2 / sigma_w**2)
    if box[0] == 0.0:
        # Intepret as real carrier resolved field
        envelope = np.fft.irfft(envelope)
    else:
        # Interpret as spectral envelope putting negative frequencies last
        envelope = np.fft.ifftshift(envelope)
        # Get the corresponding time domain envelope
        envelope = np.fft.ifft(envelope)
    coeff = 1 / np.max(np.abs(envelope))
    return coeff * np.exp(-(xp[:, 0, 4] - w0)**2 / sigma_w**2)
Esempio n. 4
0
	def GetGridInfo(self):
		w_nodes = self.center[0] + grid_tools.cyclic_nodes(-self.size[0]/2,self.size[0]/2,self.pts[0])
		x_nodes = grid_tools.cell_centers(-self.size[1]/2,self.size[1]/2,self.pts[1])
		y_nodes = grid_tools.cell_centers(-self.size[2]/2,self.size[2]/2,self.pts[2])
		w_walls = grid_tools.cell_walls(w_nodes[0],w_nodes[-1],self.pts[0],self.default_band)
		x_walls = grid_tools.cell_walls(x_nodes[0],x_nodes[-1],self.pts[1])
		y_walls = grid_tools.cell_walls(y_nodes[0],y_nodes[-1],self.pts[2])
		plot_ext = np.array([w_walls[0],w_walls[-1],x_walls[0],x_walls[-1],y_walls[0],y_walls[-1]])
		return w_nodes,x_nodes,y_nodes,plot_ext
Esempio n. 5
0
 def test_full_slab_edge(self):
     a = np.ones((4, 4, 4))
     a[2, 2, 3] = 2.0
     wn = grid_tools.cyclic_nodes(0.0, 4.0, 4)
     xn = grid_tools.cell_centers(0.0, 4.0, 4)
     yn = grid_tools.cell_centers(0.0, 4.0, 4)
     w = np.array([2.0, 2.0, 2.0])
     x = np.array([2.5, 2.5, 2.5])
     y = np.array([4.0, 3.5, 3.0])
     data = grid_tools.DataFromGrid(w, x, y, wn, xn, yn, a)
     assert np.allclose(data, [2.5, 2.0, 1.5])
Esempio n. 6
0
def load_rays_xw(xp, bundle_radius, N, box, loading_coordinates):
    '''Load the rays in the z=0 plane in a regular pattern.'''
    num_bundles = N[0] * N[1] * N[2] * N[3]
    o0 = np.ones(N[0])
    o1 = np.ones(N[1])
    o2 = np.ones(N[2])
    o3 = np.ones(N[3])
    # load frequencies to respect FFT conventions
    grid0 = grid_tools.cyclic_nodes(box[0], box[1], N[0])
    grid1 = grid_tools.cell_centers(box[2], box[3], N[1])
    if loading_coordinates == 'cartesian':
        grid2 = grid_tools.cell_centers(box[4], box[5], N[2])
    else:
        grid2 = grid_tools.cyclic_nodes(box[4], box[5], N[2])
    grid3 = grid_tools.cell_centers(box[6], box[7], N[3])

    if box[0] == 0.0:
        grid0 = grid0[1:]
        o0 = o0[1:]
        num_bundles -= N[1] * N[2] * N[3]

    # Load the primary rays in configuration+w space

    if loading_coordinates == 'cartesian':
        xp[:, 0, 0] = 0.0
        xp[:, 0, 1] = np.einsum('i,j,k,l', o0, grid1, o2,
                                o3).reshape(num_bundles)
        xp[:, 0, 2] = np.einsum('i,j,k,l', o0, o1, grid2,
                                o3).reshape(num_bundles)
        xp[:, 0, 3] = np.einsum('i,j,k,l', o0, o1, o2,
                                grid3).reshape(num_bundles)
        xp[:, 0, 4] = np.einsum('i,j,k,l', grid0, o1, o2,
                                o3).reshape(num_bundles)
    else:
        xp[:, 0, 0] = 0.0
        xp[:, 0, 1] = np.einsum('i,j,k,l', o0, grid1, np.cos(grid2),
                                o3).reshape(num_bundles)
        xp[:, 0, 2] = np.einsum('i,j,k,l', o0, grid1, np.sin(grid2),
                                o3).reshape(num_bundles)
        xp[:, 0, 3] = np.einsum('i,j,k,l', o0, o1, o2,
                                grid3).reshape(num_bundles)
        xp[:, 0, 4] = np.einsum('i,j,k,l', grid0, o1, o2,
                                o3).reshape(num_bundles)

    # Load the satellite rays in configuration+w space

    xp[:, 1, :] = xp[:, 0, :]
    xp[:, 2, :] = xp[:, 0, :]
    xp[:, 3, :] = xp[:, 0, :]
    xp[:, 4, :] = xp[:, 0, :]
    xp[:, 5, :] = xp[:, 0, :]
    xp[:, 6, :] = xp[:, 0, :]

    xp[:, 1, 1] += bundle_radius[1]
    xp[:, 2, 1] -= bundle_radius[1]

    xp[:, 3, 2] += bundle_radius[2]
    xp[:, 4, 2] -= bundle_radius[2]

    xp[:, 5, 3] += bundle_radius[3]
    xp[:, 6, 3] -= bundle_radius[3]
Esempio n. 7
0
 def test_cyclic(self):
     nodes = grid_tools.cyclic_nodes(0.0, 5.0, 5)
     assert np.allclose(nodes, [0.0, 1.0, 2.0, 3.0, 4.0])
     center, width = grid_tools.cyclic_center_and_width(0.0, 5.0)
     assert center == pytest.approx(2.5)
     assert width == pytest.approx(5)