Esempio n. 1
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. 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 track(cl, xp, eikonal, vg, vol_dict):
    '''Propagate unidirectional fully dispersive waves using eikonal data as a boundary condition.
	The volume must be oriented so the polarization axis is x (linear polarization only).

	:param numpy.array xp: ray phase space with shape (bundles,rays,8)
	:param numpy.array eikonal: ray eikonal data with shape (bundles,4)
	:param numpy.array vg: ray group velocity with shape (bundles,rays,4)
	:param dictionary vol_dict: input file dictionary for the volume'''
    band = vol_dict['frequency band']
    size = (band[1] - band[0], ) + vol_dict['size']
    N = vol_dict['wave grid']
    # N[3] is the number of diagnostic planes, including the initial plane
    diagnostic_steps = N[3] - 1
    subcycles = vol_dict['subcycles']
    steps = diagnostic_steps * subcycles
    field_planes = steps + 1

    powersof2 = [2**i for i in range(32)]
    if N[0] - 1 not in powersof2:
        raise ValueError('UPPE propagator requires 2**n+1 w-nodes')
    if N[1] not in powersof2:
        raise ValueError('UPPE propagator requires 2**n x-nodes')
    if N[2] not in powersof2:
        raise ValueError('UPPE propagator requires 2**n y-nodes')
    try:
        window_speed = vol_dict['window speed']
    except:
        window_speed = 1.0
    try:
        chi3 = vol_dict['chi3']
    except:
        chi3 = 0.0

    # Capture the rays
    if vol_dict['wave coordinates'] == 'cartesian':
        field_tool = caustic_tools.FourierTool(N, band, (0, 0, 0), size[1:],
                                               cl)
    else:
        field_tool = caustic_tools.BesselBeamTool(N, band, (0, 0, 0), size[1:],
                                                  cl)

    w_nodes, x1_nodes, x2_nodes, plot_ext = field_tool.GetGridInfo()
    A = np.zeros(N).astype(np.complex)
    J = np.zeros(N).astype(np.complex)
    ne = np.zeros(N).astype(np.complex)
    A0, dom3d = field_tool.GetBoundaryFields(xp[:, 0, :], eikonal, 1)

    # Setup the wave propagation domain
    chi = vol_dict['dispersion inside'].chi(w_nodes)
    try:
        ionizer = vol_dict['ionizer']
    except KeyError:
        ionizer = ionization.Ionization(1.0, 1.0, 1.0, 1.0)
    dens_nodes = grid_tools.cell_centers(-size[3] / 2, size[3] / 2, steps)
    field_walls = grid_tools.cell_walls(dens_nodes[0], dens_nodes[-1], steps)
    diagnostic_walls = np.linspace(-size[3] / 2, size[3] / 2, N[3])
    dz = field_walls[1] - field_walls[0]
    Dz = diagnostic_walls[1] - diagnostic_walls[0]
    dom4d = np.concatenate((dom3d, [field_walls[0], field_walls[-1]]))

    # Step through the domain
    # Strategy to get density plane is to re-use ray gather system
    # This works as long as the shape of xp is (*,*,8)
    xp_eff = np.zeros((N[1], N[2], 8))
    if vol_dict['wave coordinates'] == 'cartesian':
        xp_eff[..., 1] = np.outer(x1_nodes, np.ones(N[2]))
        xp_eff[..., 2] = np.outer(np.ones(N[1]), x2_nodes)
    else:
        xp_eff[..., 1] = np.outer(x1_nodes, np.cos(x2_nodes))
        xp_eff[..., 2] = np.outer(x1_nodes, np.sin(x2_nodes))
    A[..., 0] = A0
    J[..., 0] = 0.0
    ne[..., 0] = 0.0
    for k in range(diagnostic_steps):
        print('Advancing to diagnostic plane', k + 1)
        rhs_evals = 0
        for s in range(subcycles):
            if subcycles > 1:
                if s == 0:
                    print('  subcycling .', end='', flush=True)
                else:
                    print('.', end='', flush=True)
            xp_eff[..., 3] = dens_nodes[k * subcycles + s]
            dens = vol_dict['object'].GetDensity(xp_eff)
            A0, J0, ne0, evals = propagator(cl, field_tool, window_speed, A0,
                                            chi, chi3, dens, ionizer, dz)
            A0[:4, ...] = 0.0
            rhs_evals += evals
        print('', rhs_evals, 'evaluations of j(w,kx,ky)')
        A[..., k + 1] = A0
        J[..., k + 1] = J0
        ne[..., k + 1] = ne0

    # Finish by relaunching rays and returning UPPE data
    field_tool.RelaunchRays(xp, eikonal, vg, A[..., -1], size[3])
    return A, J, ne, dom4d
Esempio n. 4
0
def track(xp, eikonal, vg, vol_dict):
    '''Propagate unidirectional fully dispersive waves using eikonal data as a boundary condition.
	The volume must be oriented so the polarization axis is x (linear polarization only).

	:param numpy.array xp: ray phase space with shape (bundles,rays,8)
	:param numpy.array eikonal: ray eikonal data with shape (bundles,4)
	:param numpy.array vg: ray group velocity with shape (bundles,rays,4)
	:param dictionary vol_dict: input file dictionary for the volume'''
    band = vol_dict['frequency band']
    size = (band[1] - band[0], ) + vol_dict['size']
    N = vol_dict['wave grid']
    # N[3] is the number of diagnostic planes, including the initial plane
    diagnostic_steps = N[3] - 1
    subcycles = vol_dict['subcycles']
    steps = diagnostic_steps * subcycles
    field_planes = steps + 1
    Vol = vol_dict['object']

    try:
        window_speed = vol_dict['window speed']
    except:
        window_speed = 1.0
    try:
        chi3 = vol_dict['chi3']
    except:
        chi3 = 0.0

    # Capture the rays
    if vol_dict['wave coordinates'] == 'cartesian':
        field_tool = caustic_tools.FourierTool(N, band, (0, 0, 0), size[1:],
                                               Vol.queue, Vol.transform_k)
    else:
        field_tool = caustic_tools.BesselBeamTool(N, band, (0, 0, 0), size[1:],
                                                  Vol.queue, Vol.transform_k)

    w_nodes, x1_nodes, x2_nodes, plot_ext = field_tool.GetGridInfo()
    A = np.zeros(N).astype(np.complex)
    J = np.zeros(N).astype(np.complex)
    ne = np.zeros(N).astype(np.complex)
    A0, dom3d = field_tool.GetBoundaryFields(xp[:, 0, :], eikonal, 1)

    # Setup the wave propagation domain
    chi = vol_dict['dispersion inside'].chi(w_nodes)
    try:
        ionizer = vol_dict['ionizer']
    except KeyError:
        ionizer = ionization.Ionization(1.0, 1.0, 1.0, 1.0)
    dens_nodes = grid_tools.cell_centers(-size[3] / 2, size[3] / 2, steps)
    field_walls = grid_tools.cell_walls(dens_nodes[0], dens_nodes[-1], steps)
    diagnostic_walls = np.linspace(-size[3] / 2, size[3] / 2, N[3])
    dz = field_walls[1] - field_walls[0]
    Dz = diagnostic_walls[1] - diagnostic_walls[0]
    dom4d = np.concatenate((dom3d, [field_walls[0], field_walls[-1]]))

    # Step through the domain
    # Strategy to get density plane is to re-use ray gather system
    # This works as long as the shape of xp is (*,*,8)
    xp_eff = np.zeros((N[1], N[2], 8))
    if vol_dict['wave coordinates'] == 'cartesian':
        xp_eff[..., 1] = np.outer(x1_nodes, np.ones(N[2]))
        xp_eff[..., 2] = np.outer(np.ones(N[1]), x2_nodes)
    else:
        xp_eff[..., 1] = np.outer(x1_nodes, np.cos(x2_nodes))
        xp_eff[..., 2] = np.outer(x1_nodes, np.sin(x2_nodes))
    A[..., 0] = A0
    J[..., 0] = 0.0
    ne[..., 0] = 0.0
    for k in range(diagnostic_steps):
        print('Advancing to diagnostic plane', k + 1)
        for s in range(subcycles):
            xp_eff[..., 3] = dens_nodes[k * subcycles + s]
            dens = vol_dict['object'].GetDensity(xp_eff)
            A0, J0, ne0 = propagator(field_tool, window_speed, A0, chi, chi3,
                                     dens, ionizer, dz)
            try:
                A0 *= vol_dict['damping filter'](w_nodes)[:, np.newaxis,
                                                          np.newaxis]
            except KeyError:
                A0 = A0
        A[..., k + 1] = A0
        J[..., k + 1] = J0
        ne[..., k + 1] = ne0

    # Return the wave amplitude
    # Rays are re-launched externally
    return A, J, ne, dom4d
Esempio n. 5
0
def track(cl, xp, eikonal, vg, vol_dict):
    '''Propagate unidirectional fully dispersive waves using eikonal data as a boundary condition.
	The volume must be oriented so the polarization axis is x (linear polarization only).

	:param numpy.array xp: ray phase space with shape (bundles,rays,8)
	:param numpy.array eikonal: ray eikonal data with shape (bundles,4)
	:param numpy.array vg: ray group velocity with shape (bundles,rays,4)
	:param dictionary vol_dict: input file dictionary for the volume'''
    band = vol_dict['frequency band']
    NL_band = vol_dict['nonlinear band']
    size = (band[1] - band[0], ) + vol_dict['size']
    N = vol_dict['wave grid']
    # N[3] is the number of diagnostic planes, including the initial plane
    diagnostic_steps = N[3] - 1
    subcycles = vol_dict['subcycles']
    steps = diagnostic_steps * subcycles
    field_planes = steps + 1

    powersof2 = [2**i for i in range(32)]
    if N[0] - 1 not in powersof2:
        raise ValueError('UPPE propagator requires 2**n+1 w-nodes')
    if N[1] not in powersof2:
        raise ValueError('UPPE propagator requires 2**n x-nodes')
    if N[2] not in powersof2:
        raise ValueError('UPPE propagator requires 2**n y-nodes')
    try:
        window_speed = vol_dict['window speed']
    except KeyError:
        window_speed = 1.0
    try:
        chi3 = vol_dict['chi3']
    except KeyError:
        chi3 = 0.0
    try:
        full_relaunch = vol_dict['full relaunch']
    except KeyError:
        full_relaunch = False

    # Capture the rays
    if vol_dict['wave coordinates'] == 'cartesian':
        field_tool = caustic_tools.FourierTool(N, band, (0, 0, 0), size[1:],
                                               cl)
    else:
        field_tool = caustic_tools.BesselBeamTool(N, band, (0, 0, 0), size[1:],
                                                  cl, vol_dict['radial modes'])

    warnings.warn(
        'Polarization information is lost upon entering paraxial region.')
    w_nodes, x1_nodes, x2_nodes, plot_ext = field_tool.GetGridInfo()
    A = np.zeros(N).astype(np.complex)
    J = np.zeros(N).astype(np.complex)
    ne = np.zeros(N).astype(np.complex)
    A[..., 0], dom3d = field_tool.GetBoundaryFields(xp[:, 0, :], eikonal, 1)

    # Setup the wave propagation medium
    chi = vol_dict['dispersion inside'].chi(w_nodes).astype(np.complex)
    try:
        ionizer = ionization.Ionizer(vol_dict['ionizer'])
    except KeyError:
        ionizer = None
    mat = Material(cl.q, field_tool, N, vol_dict['wave coordinates'],
                   vol_dict['object'], chi, chi3,
                   vol_dict['density reference'], window_speed)

    # Setup the wave propagation domain
    dens_nodes = grid_tools.cell_centers(-size[3] / 2, size[3] / 2, steps)
    field_walls = grid_tools.cell_walls(dens_nodes[0], dens_nodes[-1], steps)
    diagnostic_walls = np.linspace(-size[3] / 2, size[3] / 2, N[3])
    dzmin = vol_dict['minimum step']
    Dz = diagnostic_walls[1] - diagnostic_walls[0]
    dom4d = np.concatenate((dom3d, [field_walls[0], field_walls[-1]]))

    # Step through the domain
    A0 = np.copy(A[..., 0])
    for k in range(diagnostic_steps):
        zi = diagnostic_walls[k]
        zf = diagnostic_walls[k + 1]
        print('Advancing to diagnostic plane', k + 1)
        A0, J0, ne0, evals = propagator(cl, field_tool, window_speed, A0, mat,
                                        ionizer, NL_band, subcycles, zi, zf,
                                        dzmin)
        print('', evals, 'evaluations of j(w,kx,ky)')
        A[..., k + 1] = A0
        J[..., k + 1] = J0
        ne[..., k + 1] = ne0

    # Finish by relaunching rays and returning UPPE data
    if full_relaunch:
        field_tool.RelaunchRays1(xp, eikonal, vg, A[..., -1], size[3],
                                 vol_dict['dispersion inside'])
    else:
        field_tool.RelaunchRays(xp, eikonal, vg, A[..., -1], size[3],
                                vol_dict['dispersion inside'])
    return A, J, ne, dom4d
Esempio n. 6
0
 def test_normal(self):
     nodes = grid_tools.cell_centers(0.0, 5.0, 5)
     assert np.allclose(nodes, [0.5, 1.5, 2.5, 3.5, 4.5])
     walls = grid_tools.cell_walls(0.5, 4.5, 5)
     assert np.allclose(walls, [0.0, 1.0, 2.0, 3.0, 4.0, 5.0])
Esempio n. 7
0
def track(cl, xp, eikonal, vg, vol_dict):
    '''Propagate paraxial waves using eikonal data as a boundary condition.
	The volume must be oriented so the polarization axis is x (linear polarization only).

	:param numpy.array xp: ray phase space with shape (bundles,rays,8)
	:param numpy.array eikonal: ray eikonal data with shape (bundles,4)
	:param numpy.array vg: ray group velocity with shape (bundles,rays,4)
	:param dictionary vol_dict: input file dictionary for the volume'''
    band = vol_dict['frequency band']
    size = (band[1] - band[0], ) + vol_dict['size']
    N = vol_dict['wave grid']
    # N[3] is the number of diagnostic planes, including the initial plane
    diagnostic_steps = N[3] - 1
    subcycles = vol_dict['subcycles']
    steps = diagnostic_steps * subcycles
    field_planes = steps + 1
    Vol = vol_dict['object']

    powersof2 = [2**i for i in range(32)]
    if N[0] not in powersof2:
        raise ValueError('Paraxial propagator requires 2**n w-nodes')
    if N[1] not in powersof2:
        raise ValueError('Paraxial propagator requires 2**n x-nodes')
    if N[2] not in powersof2:
        raise ValueError('Paraxial propagator requires 2**n y-nodes')
    try:
        window_speed = vol_dict['window speed']
    except:
        window_speed = 1.0
    try:
        chi3 = vol_dict['chi3']
    except:
        chi3 = 0.0

    # Capture the rays
    if vol_dict['wave coordinates'] == 'cartesian':
        field_tool = caustic_tools.FourierTool(N, band, (0, 0, 0), size[1:],
                                               cl)
    else:
        field_tool = caustic_tools.BesselBeamTool(N, band, (0, 0, 0), size[1:],
                                                  cl)

    w_nodes, x1_nodes, x2_nodes, plot_ext = field_tool.GetGridInfo()
    A = np.zeros(N).astype(np.complex)
    A0, dom3d = field_tool.GetBoundaryFields(xp[:, 0, :], eikonal, 1)
    n0 = np.mean(
        np.sqrt(np.einsum('...i,...i', xp[:, 0, 5:8], xp[:, 0, 5:8])) /
        xp[:, 0, 4])
    ng = 1.0 / np.mean(
        np.sqrt(np.einsum('...i,...i', vg[:, 0, 1:4], vg[:, 0, 1:4])))

    # Setup the wave propagation domain
    chi = vol_dict['dispersion inside'].chi(w_nodes)
    dens_nodes = grid_tools.cell_centers(-size[3] / 2, size[3] / 2, steps)
    field_walls = grid_tools.cell_walls(dens_nodes[0], dens_nodes[-1], steps)
    diagnostic_walls = np.linspace(-size[3] / 2, size[3] / 2, N[3])
    dz = field_walls[1] - field_walls[0]
    Dz = diagnostic_walls[1] - diagnostic_walls[0]
    dom4d = np.concatenate((dom3d, [field_walls[0], field_walls[-1]]))

    # Step through the domain
    # Strategy to get density plane is to re-use ray gather system
    # This works as long as the shape of xp is (*,*,8)
    xp_eff = np.zeros((N[1], N[2], 8))
    if vol_dict['wave coordinates'] == 'cartesian':
        xp_eff[..., 1] = np.outer(x1_nodes, np.ones(N[2]))
        xp_eff[..., 2] = np.outer(np.ones(N[1]), x2_nodes)
    else:
        xp_eff[..., 1] = np.outer(x1_nodes, np.cos(x2_nodes))
        xp_eff[..., 2] = np.outer(x1_nodes, np.sin(x2_nodes))
    A[..., 0] = A0
    for k in range(diagnostic_steps):
        print('Advancing to diagnostic plane', k + 1)
        for s in range(subcycles):
            xp_eff[..., 3] = dens_nodes[k * subcycles + s]
            dens = vol_dict['object'].GetDensity(xp_eff)
            A0 = propagator(field_tool, A0, chi, dens, n0, ng, dz, True)
            try:
                A0 *= vol_dict['damping filter'](w_nodes)[:, np.newaxis,
                                                          np.newaxis]
            except KeyError:
                A0 = A0
        A[..., k + 1] = A0

    # Finish by relaunching rays and returning wave data
    field_tool.RelaunchRays(xp, eikonal, vg, A[..., -1], size[3])
    return A, dom4d