Esempio n. 1
0
def calculate_p_center(p1_start, p2_start, p3_start,
                       N_p1, N_p2, N_p3,
                       dp1, dp2, dp3, 
                      ):
    """
    Initializes the cannonical variables p1, p2 and p3 using a centered
    formulation.
    """
    p1_center = af.constant(0, N_p1 * N_p2 * N_p3, len(p1_start), dtype = af.Dtype.f64)
    p2_center = af.constant(0, N_p1 * N_p2 * N_p3, len(p2_start), dtype = af.Dtype.f64)
    p3_center = af.constant(0, N_p1 * N_p2 * N_p3, len(p3_start), dtype = af.Dtype.f64)

    # Assigning for each species:
    for i in range(len(p1_start)):

        p1 = p1_start[i] + (0.5 + np.arange(N_p1)) * dp1[i]
        p2 = p2_start[i] + (0.5 + np.arange(N_p2)) * dp2[i]
        p3 = p3_start[i] + (0.5 + np.arange(N_p3)) * dp3[i]
        
        p2_center[:, i] = af.flat(af.to_array(np.meshgrid(p2, p1, p3)[0]))
        p1_center[:, i] = af.flat(af.to_array(np.meshgrid(p2, p1, p3)[1]))
        p3_center[:, i] = af.flat(af.to_array(np.meshgrid(p2, p1, p3)[2]))

    af.eval(p1_center, p2_center, p3_center)
    return (p1_center, p2_center, p3_center)
Esempio n. 2
0
def calculate_q(q1_start, q2_start, N_q1, N_q2, N_g1, N_g2, dq1, dq2):

    i_q1 = np.arange(-N_g1, N_q1 + N_g1)
    i_q2 = np.arange(-N_g2, N_q2 + N_g2)

    q1_left_bot = q1_start + i_q1 * dq1
    q2_left_bot = q2_start + i_q2 * dq2

    q2_left_bot, q1_left_bot = np.meshgrid(q2_left_bot, q1_left_bot)
    q2_left_bot, q1_left_bot = af.to_array(q2_left_bot), af.to_array(
        q1_left_bot)

    # To bring the data structure to the default form:(N_p, N_s, N_q1, N_q2)
    q1_left_bot = af.reorder(q1_left_bot, 3, 2, 0, 1)
    q2_left_bot = af.reorder(q2_left_bot, 3, 2, 0, 1)

    q1_center_bot = q1_left_bot + 0.5 * dq1
    q2_center_bot = q2_left_bot

    q1_left_center = q1_left_bot
    q2_left_center = q2_left_bot + 0.5 * dq2

    q1_center = q1_left_bot + 0.5 * dq1
    q2_center = q2_left_bot + 0.5 * dq2

    ans = [[q1_left_bot, q2_left_bot], [q1_center_bot, q2_center_bot],
           [q1_left_center, q2_center_bot], [q1_center, q2_center]]

    return (ans)
Esempio n. 3
0
def test_dump_moments():
    test_obj = test()
    N_g      = test_obj.N_ghost

    dump_moments(test_obj, 'test_file')

    h5f          = h5py.File('test_file.h5', 'r')
    moments_read = h5f['moments'][:]
    h5f.close()

    moments_read = np.swapaxes(moments_read, 0, 1)

    print(moments_read.shape)
    print(compute_moments_imported(test_obj, 'density').shape)

    assert(af.sum(af.to_array(moments_read[:, :, 0]) - 
                  af.reorder(compute_moments_imported(test_obj, 'density'), 
                             1, 2, 0
                            )[N_g:-N_g, N_g:-N_g]
                 )==0
          )

    assert(af.sum(af.to_array(moments_read[:, :, 1]) - 
                  af.reorder(compute_moments_imported(test_obj, 'energy'),
                             1, 2, 0
                            )[N_g:-N_g, N_g:-N_g] 
                 )==0
          )
Esempio n. 4
0
    def _calculate_p_center(self):
        """
        Initializes the cannonical variables p1, p2 and p3 using a centered
        formulation. The size, and resolution are the same as declared
        under domain of the physical system object.
        """
        p1_center = self.p1_start + (0.5 + np.arange(
            -self.N_ghost_p, self.N_p1 + self.N_ghost_p)) * self.dp1
        p2_center = self.p2_start + (0.5 + np.arange(
            -self.N_ghost_p, self.N_p2 + self.N_ghost_p)) * self.dp2
        p3_center = self.p3_start + (0.5 + np.arange(
            -self.N_ghost_p, self.N_p3 + self.N_ghost_p)) * self.dp3

        p2_center, p1_center, p3_center = np.meshgrid(p2_center, p1_center,
                                                      p3_center)

        # Flattening the arrays:
        p1_center = af.flat(af.to_array(p1_center))
        p2_center = af.flat(af.to_array(p2_center))
        p3_center = af.flat(af.to_array(p3_center))

        if (self.N_species > 1):

            p1_center = af.tile(p1_center, 1, self.N_species)
            p2_center = af.tile(p2_center, 1, self.N_species)
            p3_center = af.tile(p3_center, 1, self.N_species)

        af.eval(p1_center, p2_center, p3_center)
        return (p1_center, p2_center, p3_center)
Esempio n. 5
0
    def _calculate_p_back(self):

        p1_center = self.p1_start + (0.5 + np.arange(
            -self.N_ghost_p, self.N_p1 + self.N_ghost_p)) * self.dp1

        p2_center = self.p2_start + (0.5 + np.arange(
            -self.N_ghost_p, self.N_p2 + self.N_ghost_p)) * self.dp2

        p3_back = self.p3_start + np.arange(
            -self.N_ghost_p, self.N_p3 + self.N_ghost_p) * self.dp3

        p2_back, p1_back, p3_back = np.meshgrid(p2_center, p1_center,
                                                p3_center)

        # Flattening the arrays:
        p1_back = af.flat(af.to_array(p1_back))
        p2_back = af.flat(af.to_array(p2_back))
        p3_back = af.flat(af.to_array(p3_back))

        if (self.N_species > 1):

            p1_back = af.tile(p1_back, 1, self.N_species)
            p2_back = af.tile(p2_back, 1, self.N_species)
            p3_back = af.tile(p3_back, 1, self.N_species)

        af.eval(p1_back, p2_back, p3_back)
        return (p1_back, p2_back, p3_back)
Esempio n. 6
0
    def _calculate_p_center(self):
        """
        Initializes the cannonical variables p1, p2 and p3 using a centered
        formulation. The size, and resolution are the same as declared
        under domain of the physical system object.
        """
        p1_center = \
            self.p1_start + (0.5 + np.arange(0, self.N_p1, 1)) * self.dp1
        
        p2_center = \
            self.p2_start + (0.5 + np.arange(0, self.N_p2, 1)) * self.dp2
        
        p3_center = \
            self.p3_start + (0.5 + np.arange(0, self.N_p3, 1)) * self.dp3

        p2_center, p1_center, p3_center = np.meshgrid(p2_center,
                                                      p1_center,
                                                      p3_center
                                                     )

        # Flattening the obtained arrays:
        p1_center = af.flat(af.to_array(p1_center))
        p2_center = af.flat(af.to_array(p2_center))
        p3_center = af.flat(af.to_array(p3_center))

        # Reordering such that variation in velocity is along axis 2:
        # This is done to be consistent with the positionsExpanded form:
        p1_center = af.reorder(p1_center, 2, 3, 0, 1)
        p2_center = af.reorder(p2_center, 2, 3, 0, 1)
        p3_center = af.reorder(p3_center, 2, 3, 0, 1)

        af.eval(p1_center, p2_center, p3_center)
        return(p1_center, p2_center, p3_center)
Esempio n. 7
0
    def _calculate_q_center(self):
        """
        Initializes the cannonical variables q1, q2 using a centered
        formulation. The size, and resolution are the same as declared
        under domain of the physical system object.

        Returns in q_expanded form.
        """

        # Obtaining start coordinates for the local zone
        # Additionally, we also obtain the size of the local zone
        ((i_q1_start, i_q2_start), (N_q1_local,
                                    N_q2_local)) = self._da_f.getCorners()

        i_q1_center = i_q1_start + 0.5
        i_q2_center = i_q2_start + 0.5

        i_q1 = (i_q1_center +
                np.arange(-self.N_ghost_q, N_q1_local + self.N_ghost_q))

        i_q2 = (i_q2_center +
                np.arange(-self.N_ghost_q, N_q2_local + self.N_ghost_q))

        q1_center = self.q1_start + i_q1 * self.dq1
        q2_center = self.q2_start + i_q2 * self.dq2

        q2_center, q1_center = np.meshgrid(q2_center, q1_center)
        q1_center, q2_center = af.to_array(q1_center), af.to_array(q2_center)

        # To bring the data structure to the default form:(N_p, N_s, N_q1, N_q2)
        q1_center = af.reorder(q1_center, 3, 2, 0, 1)
        q2_center = af.reorder(q2_center, 3, 2, 0, 1)

        af.eval(q1_center, q2_center)
        return (q1_center, q2_center)
Esempio n. 8
0
def initialize_f(q1, q2, p1, p2, p3, params):

    m = params.mass_particle
    k = params.boltzmann_constant

    rho = af.select(af.abs(q2) > 0.25, q1**0, 2)

    # Seeding the instability
    p1_bulk = af.reorder(p1_bulk, 1, 2, 0, 3)
    p1_bulk += af.to_array(
        np.random.rand(1, q1.shape[1], q1.shape[2]) *
        np.random.choice([-1, 1], size=(1, q1.shape[1], q1.shape[2]))) * 0.005

    p2_bulk = af.to_array(
        np.random.rand(1, q1.shape[1], q1.shape[2]) *
        np.random.choice([-1, 1], size=(1, q1.shape[1], q1.shape[2]))) * 0.005

    p1_bulk = af.reorder(p1_bulk, 2, 0, 1, 3)
    p2_bulk = af.reorder(p2_bulk, 2, 0, 1, 3)

    T = (2.5 / rho)

    f = rho * (m / (2 * np.pi * k * T))**(3 / 2) \
            * af.exp(-m * (p1 - p1_bulk)**2 / (2 * k * T)) \
            * af.exp(-m * (p2 - p2_bulk)**2 / (2 * k * T)) \
            * af.exp(-m * (p3)**2 / (2 * k * T))

    af.eval(f)
    return (f)
Esempio n. 9
0
    def __init__(self):
        self.f = af.to_array(np.array([0]))

        self.cell_centered_EM_fields = af.to_array(np.array([0]))
        self.yee_grid_EM_fields = af.to_array(np.array([0]))

        self.performance_test_flag = False
Esempio n. 10
0
    def __init__(self):
        self.physical_system = type('obj', (object, ),
                                    {'params': type('obj', (object, ),
                                        {'charge_electron': -1})
                                     })

        self.N_q1 = 32
        self.N_q2 = 64

        self.single_mode_evolution = False

        self.N_p1 = 2
        self.N_p2 = 3
        self.N_p3 = 4

        self.k_q1 = 2 * np.pi * fftfreq(self.N_q1, 1 / self.N_q1)
        self.k_q2 = 2 * np.pi * fftfreq(self.N_q2, 1 / self.N_q2)

        self.k_q2, self.k_q1 = np.meshgrid(self.k_q2, self.k_q1)
        self.k_q2, self.k_q1 = af.to_array(self.k_q2), af.to_array(self.k_q1)

        self.q1 = af.to_array((0.5 + np.arange(self.N_q1)) * (1 / self.N_q1))
        self.q2 = af.to_array((0.5 + np.arange(self.N_q2)) * (1 / self.N_q2))

        self.q1 = af.tile(self.q1, 1, self.N_q2)
        self.q2 = af.tile(af.reorder(self.q2), self.N_q1, 1)
Esempio n. 11
0
    def __init__(self):
        
        self.q1_start = np.random.randint(0, 5)
        self.q2_start = np.random.randint(0, 5)

        self.q1_end = np.random.randint(5, 10)
        self.q2_end = np.random.randint(5, 10)

        self.N_q1 = np.random.randint(16, 32)
        self.N_q2 = np.random.randint(16, 32)

        self.dq1 = (self.q1_end - self.q1_start) / self.N_q1
        self.dq2 = (self.q2_end - self.q2_start) / self.N_q2

        N_g = self.N_ghost = np.random.randint(1, 5)

        self.q1 = self.q1_start \
                  * (0.5 + np.arange(-self.N_ghost,
                                     self.N_q1 + self.N_ghost
                                    )
                    ) * self.dq1

        self.q2 = self.q2_start \
                  * (0.5 + np.arange(-self.N_ghost,
                                      self.N_q2 + self.N_ghost
                                    )
                    ) * self.dq2

        self.q2, self.q1 = np.meshgrid(self.q2, self.q1)
        self.q1, self.q2 = af.to_array(self.q1), af.to_array(self.q2)

        self.q1 = af.reorder(self.q1, 2, 0, 1)
        self.q2 = af.reorder(self.q2, 2, 0, 1)

        self.q1 = af.tile(self.q1, 6)
        self.q2 = af.tile(self.q2, 6)

        self._da_fields = PETSc.DMDA().create([self.N_q1, self.N_q2],
                                              dof=6,
                                              stencil_width=self.N_ghost,
                                              boundary_type=('periodic',
                                                             'periodic'),
                                              stencil_type=1,
                                             )

        self._glob_fields  = self._da_fields.createGlobalVec()
        self._local_fields = self._da_fields.createLocalVec()

        self._glob_fields_array  = self._glob_fields.getArray()
        self._local_fields_array = self._local_fields.getArray()

        self.cell_centered_EM_fields = af.constant(0, 6, self.q1.shape[1], 
                                                   self.q1.shape[2],
                                                   dtype=af.Dtype.f64
                                                  )

        self.cell_centered_EM_fields[:, N_g:-N_g, N_g:-N_g] = \
            af.sin(2 * np.pi * self.q1 + 4 * np.pi * self.q2)[:, N_g:-N_g,N_g:-N_g]
        
        self.performance_test_flag = False
Esempio n. 12
0
def test_calculate_p():
    obj = test()

    p1, p2, p3 = calculate_p(obj)

    p1_expected = obj.p1_start + (0.5 + np.arange(obj.N_p1)) * obj.dp1
    p2_expected = obj.p2_start + (0.5 + np.arange(obj.N_p2)) * obj.dp2
    p3_expected = obj.p3_start + (0.5 + np.arange(obj.N_p3)) * obj.dp3

    p2_expected, p1_expected, p3_expected = np.meshgrid(p2_expected,
                                                        p1_expected,
                                                        p3_expected
                                                       )
    
    p1_expected = af.reorder(af.flat(af.to_array(p1_expected)),
                             2, 3, 0, 1
                            )
                          
    p2_expected = af.reorder(af.flat(af.to_array(p2_expected)),
                             2, 3, 0, 1
                            )
                         
    p3_expected = af.reorder(af.flat(af.to_array(p3_expected)),
                             2, 3, 0, 1
                            )

    assert(af.sum(af.abs(p1_expected - p1)) == 0)
    assert(af.sum(af.abs(p2_expected - p2)) == 0)
    assert(af.sum(af.abs(p3_expected - p3)) == 0)
Esempio n. 13
0
def test_fft_poisson():
    """
    This function tests that the FFT solver works as intended.
    We take an expression for density for which the fields can
    be calculated analytically, and check that the numerical
    solution as given by the FFT solver and the analytical
    solution correspond well with each other.
    """
    x_start = 0
    y_start = 0
    z_start = 0

    x_end = 1
    y_end = 2
    z_end = 3

    N_x = np.random.randint(16, 32)
    N_y = np.random.randint(16, 32)
    N_z = np.random.randint(16, 32)

    dx = (x_end - x_start) / N_x
    dy = (y_end - y_start) / N_y
    dz = (z_end - z_start) / N_z

    # Using a centered formulation for the grid points of x, y, z:
    x = x_start + (np.arange(N_x) + 0.5) * dx
    y = y_start + (np.arange(N_y) + 0.5) * dy
    z = z_start + (np.arange(N_z) + 0.5) * dz

    y, x, z = np.meshgrid(y, x, z)

    x = af.to_array(x)
    y = af.to_array(y)
    z = af.to_array(z)

    rho = af.sin(2 * np.pi * x + 4 * np.pi * y + 6 * np.pi * z)

    Ex_analytic = -(2 * np.pi) / (56 * np.pi**2) * \
                  af.cos(2 * np.pi * x + 4 * np.pi * y + 6 * np.pi * z)

    Ey_analytic = -(4 * np.pi) / (56 * np.pi**2) * \
                  af.cos(2 * np.pi * x + 4 * np.pi * y + 6 * np.pi * z)

    Ez_analytic = -(6 * np.pi) / (56 * np.pi**2) * \
                  af.cos(2 * np.pi * x + 4 * np.pi * y + 6 * np.pi * z)

    Ex_numerical, Ey_numerical, Ez_numerical = fft_poisson(rho, dx, dy, dz)

    # Checking that the L1 norm of error is at machine precision:
    Ex_err = af.sum(
        af.abs(Ex_numerical - Ex_analytic)) / Ex_analytic.elements()
    Ey_err = af.sum(
        af.abs(Ey_numerical - Ey_analytic)) / Ey_analytic.elements()
    Ez_err = af.sum(
        af.abs(Ez_numerical - Ez_analytic)) / Ez_analytic.elements()

    assert (Ex_err < 1e-14)
    assert (Ey_err < 1e-14)
    assert (Ez_err < 1e-14)
Esempio n. 14
0
def communicate_fields(self, on_fdtd_grid=False):
    """
    Used in communicating the values at the boundary zones for each of
    the local vectors among all procs.This routine is called to take care
    of communication(and periodic B.C's) procedures for the EM field
    arrays. The function is used for communicating the EM field values 
    on the cell centered grid  which is used by default. Additionally,it can
    also be used to communicate the values on the Yee-grid which is used by the FDTD solver.
    """
    if (self.performance_test_flag == True):
        tic = af.time()

    # Obtaining start coordinates for the local zone
    # Additionally, we also obtain the size of the local zone
    ((i_q1_start, i_q2_start), (N_q1_local,
                                N_q2_local)) = self._da_fields.getCorners()

    N_g = self.N_g

    # Assigning the values of the af.Array
    # fields quantities to the PETSc.Vec:

    if (on_fdtd_grid is True):
        flattened_global_EM_fields_array = \
            af.flat(self.yee_grid_EM_fields[:, :, N_g:-N_g, N_g:-N_g])
        flattened_global_EM_fields_array.to_ndarray(self._glob_fields_array)

    else:
        flattened_global_EM_fields_array = \
            af.flat(self.cell_centered_EM_fields[:, :, N_g:-N_g, N_g:-N_g])
        flattened_global_EM_fields_array.to_ndarray(self._glob_fields_array)

    # Takes care of boundary conditions and interzonal communications:
    self._da_fields.globalToLocal(self._glob_fields, self._local_fields)

    # Converting back to af.Array
    if (on_fdtd_grid is True):

        self.yee_grid_EM_fields = af.moddims(
            af.to_array(self._local_fields_array), 6, 1, N_q1_local + 2 * N_g,
            N_q2_local + 2 * N_g)

        af.eval(self.yee_grid_EM_fields)

    else:

        self.cell_centered_EM_fields = af.moddims(
            af.to_array(self._local_fields_array), 6, 1, N_q1_local + 2 * N_g,
            N_q2_local + 2 * N_g)

        af.eval(self.cell_centered_EM_fields)

    if (self.performance_test_flag == True):
        af.sync()
        toc = af.time()
        self.time_communicate_fields += toc - tic

    return
Esempio n. 15
0
def Jx_Esirkepov_2D(   charge_electron,\
                       number_of_electrons,\
                       positions_x ,positions_y,\
                       velocities_x, velocities_y,\
                       x_grid, y_grid,\
                       ghost_cells,\
                       length_domain_x, length_domain_y,\
                       dx, dy,\
                       dt\
                   ):
    

    elements = x_grid.elements() * y_grid.elements()

    Jx_x_indices, Jx_y_indices,\
    Jx_values_at_these_indices,\
    Jy_x_indices, Jy_y_indices,\
    Jy_values_at_these_indices = indices_and_currents_TSC_2D(charge_electron,\
                                                     positions_x, positions_y,\
                                                     velocities_x, velocities_y,\
                                                     x_grid, y_grid,\
                                                     ghost_cells,\
                                                     length_domain_x, length_domain_y,\
                                                     dt\
                                                   )
    
    # Current deposition using numpy's histogram
    input_indices = (Jx_x_indices*(y_grid.elements()) + Jx_y_indices)
    
    # Computing Jx_Yee
    
    Jx_Yee, temp = np.histogram(  input_indices,\
                                  bins=elements,\
                                  range=(0, elements),\
                                  weights=Jx_values_at_these_indices\
                                 )
    
    Jx_Yee = af.data.moddims(af.to_array(Jx_Yee), y_grid.elements(), x_grid.elements())
    
    # Computing Jy_Yee
    
    input_indices = (Jy_x_indices*(y_grid.elements()) + Jy_y_indices)
    
    Jy_Yee, temp = np.histogram(input_indices,\
                                      bins=elements,\
                                      range=(0, elements),\
                                      weights=Jy_values_at_these_indices\
                                     )
    
    Jy_Yee = af.data.moddims(af.to_array(Jy_Yee), y_grid.elements(), x_grid.elements())

    af.eval(Jx_Yee, Jy_Yee)

    return Jx_Yee, Jy_Yee
Esempio n. 16
0
    def __init__(self, N):
        self.q1_start = 0
        self.q2_start = 0

        self.q1_end = 1
        self.q2_end = 1

        self.N_q1 = N
        self.N_q2 = N

        self.dq1 = (self.q1_end - self.q1_start) / self.N_q1
        self.dq2 = (self.q2_end - self.q2_start) / self.N_q2

        self.N_ghost = np.random.randint(3, 5)

        self.q1 = self.q1_start \
            + (0.5 + np.arange(-self.N_ghost,self.N_q1 + self.N_ghost)) * self.dq1

        self.q2 = self.q2_start \
            + (0.5 + np.arange(-self.N_ghost,self.N_q2 + self.N_ghost)) * self.dq2

        self.q2, self.q1 = np.meshgrid(self.q2, self.q1)
        self.q2, self.q1 = af.to_array(self.q2), af.to_array(self.q1)

        self.q1 = af.reorder(self.q1, 2, 0, 1)
        self.q2 = af.reorder(self.q2, 2, 0, 1)

        self.yee_grid_EM_fields = af.constant(0,
                                              6,
                                              self.q1.shape[1],
                                              self.q1.shape[2],
                                              dtype=af.Dtype.f64)

        self._da_fields = PETSc.DMDA().create(
            [self.N_q1, self.N_q2],
            dof=6,
            stencil_width=self.N_ghost,
            boundary_type=('periodic', 'periodic'),
            stencil_type=1,
        )

        self._glob_fields = self._da_fields.createGlobalVec()
        self._local_fields = self._da_fields.createLocalVec()

        self._glob_fields_array = self._glob_fields.getArray()
        self._local_fields_array = self._local_fields.getArray()

        self.boundary_conditions = type('obj', (object, ), {
            'in_q1': 'periodic',
            'in_q2': 'periodic'
        })

        self.performance_test_flag = False
Esempio n. 17
0
def fft_poisson(rho, dx, dy=None):
    """
    FFT solver which returns the value of electric field. This will only work
    when the system being solved for has periodic boundary conditions.

    Parameters:
    -----------
    rho : The 1D/2D density array obtained from calculate_density() is passed to this
          function.

    dx  : Step size in the x-grid

    dy  : Step size in the y-grid.Set to None by default to avoid conflict with the 1D case.

    Output:
    -------
    E_x, E_y : Depending on the dimensionality of the system considered, either both E_x, and
               E_y are returned or E_x is returned.
    """

    k_x = af.to_array(fftfreq(rho.shape[1], dx))
    k_x = af.Array.as_type(k_x, af.Dtype.c64)
    k_y = af.to_array(fftfreq(rho.shape[0], dy))
    k_x = af.tile(af.reorder(k_x), rho.shape[0], 1)
    k_y = af.tile(k_y, 1, rho.shape[1])
    k_y = af.Array.as_type(k_y, af.Dtype.c64)

    rho = np.array(rho)
    rho_hat = fft2(rho)
    rho_hat = af.to_array(rho_hat)
    potential_hat = af.constant(0,
                                rho.shape[0],
                                rho.shape[1],
                                dtype=af.Dtype.c64)

    potential_hat = (1 / (4 * np.pi**2 * (k_x * k_x + k_y * k_y))) * rho_hat

    potential_hat[0, 0] = 0

    potential_hat = np.array(potential_hat)

    E_x_hat = -1j * 2 * np.pi * np.array(k_x) * potential_hat
    E_y_hat = -1j * 2 * np.pi * np.array(k_y) * potential_hat

    E_x = (ifft2(E_x_hat)).real
    E_y = (ifft2(E_y_hat)).real

    E_x = af.to_array(E_x)
    E_y = af.to_array(E_y)

    af.eval(E_x, E_y)

    return (E_x, E_y)
Esempio n. 18
0
    def __init__(self):
        self.physical_system = type('obj', (object, ), {
            'moment_exponents': moment_exponents,
            'moment_coeffs': moment_coeffs
        })
        self.p1_start = -10
        self.p2_start = -10
        self.p3_start = -10

        self.N_p1 = 32
        self.N_p2 = 32
        self.N_p3 = 32

        self.dp1 = (-2 * self.p1_start) / self.N_p1
        self.dp2 = (-2 * self.p2_start) / self.N_p2
        self.dp3 = (-2 * self.p3_start) / self.N_p3

        self.N_q1 = 16
        self.N_q2 = 16

        self.N_ghost = 3

        self.p1 = self.p1_start + (0.5 + np.arange(self.N_p1)) * self.dp1
        self.p2 = self.p2_start + (0.5 + np.arange(self.N_p2)) * self.dp2
        self.p3 = self.p3_start + (0.5 + np.arange(self.N_p3)) * self.dp3

        self.p2, self.p1, self.p3 = np.meshgrid(self.p2, self.p1, self.p3)

        self.p1 = af.flat(af.to_array(self.p1))
        self.p2 = af.flat(af.to_array(self.p2))
        self.p3 = af.flat(af.to_array(self.p3))

        self.q1 = (-self.N_ghost + 0.5 +
                   np.arange(self.N_q1 + 2 * self.N_ghost)) / self.N_q1

        self.q2 = (-self.N_ghost + 0.5 +
                   np.arange(self.N_q2 + 2 * self.N_ghost)) / self.N_q2

        self.q2, self.q1 = np.meshgrid(self.q2, self.q1)

        self.q1 = af.reorder(af.to_array(self.q1), 2, 0, 1)
        self.q2 = af.reorder(af.to_array(self.q2), 2, 0, 1)

        rho = (1 + 0.01 * af.sin(2 * np.pi * self.q1 + 4 * np.pi * self.q2))
        T = (1 + 0.01 * af.cos(2 * np.pi * self.q1 + 4 * np.pi * self.q2))

        p1_b = 0.01 * af.exp(-10 * self.q1**2 - 10 * self.q2**2)
        p2_b = 0.01 * af.exp(-10 * self.q1**2 - 10 * self.q2**2)
        p3_b = 0.01 * af.exp(-10 * self.q1**2 - 10 * self.q2**2)

        self.f = maxwell_boltzmann(rho, T, p1_b, p2_b, p3_b, self.p1, self.p2,
                                   self.p3)
Esempio n. 19
0
def fft_poisson(self, f=None):
    """
    Solves the Poisson Equation using the FFTs:

    Used as a backup solver in case of low resolution runs
    (ie. used on a single node) with periodic boundary
    conditions.
    """
    if (self.performance_test_flag == True):
        tic = af.time()

    if (self._comm.size != 1):
        raise Exception('FFT solver can only be used when run in serial')

    else:
        N_g = self.N_ghost
        rho = af.reorder(  self.physical_system.params.charge_electron \
                         * self.compute_moments('density', f)[:, N_g:-N_g, N_g:-N_g],
                         1, 2, 0
                        )

        k_q1 = fftfreq(rho.shape[0], self.dq1)
        k_q2 = fftfreq(rho.shape[1], self.dq2)

        k_q2, k_q1 = np.meshgrid(k_q2, k_q1)

        k_q1 = af.to_array(k_q1)
        k_q2 = af.to_array(k_q2)

        rho_hat = af.fft2(rho)

        potential_hat = rho_hat / (4 * np.pi**2 * (k_q1**2 + k_q2**2))
        potential_hat[0, 0] = 0

        E1_hat = -1j * 2 * np.pi * k_q1 * potential_hat
        E2_hat = -1j * 2 * np.pi * k_q2 * potential_hat

        # Non-inclusive of ghost-zones:
        E1_physical = af.reorder(af.real(af.ifft2(E1_hat)), 2, 0, 1)
        E2_physical = af.reorder(af.real(af.ifft2(E2_hat)), 2, 0, 1)

        self.cell_centered_EM_fields[0, N_g:-N_g, N_g:-N_g] = E1_physical
        self.cell_centered_EM_fields[1, N_g:-N_g, N_g:-N_g] = E2_physical

        af.eval(self.cell_centered_EM_fields)

    if (self.performance_test_flag == True):
        af.sync()
        toc = af.time()
        self.time_fieldsolver += toc - tic

    return
Esempio n. 20
0
    def _calculate_k(self):
        """
        Initializes the wave numbers k_q1 and k_q2 which will be 
        used when solving in fourier space.
        """
        k_q1 = 2 * np.pi * fftfreq(self.N_q1, self.dq1)
        k_q2 = 2 * np.pi * fftfreq(self.N_q2, self.dq2)

        k_q2, k_q1 = np.meshgrid(k_q2, k_q1)

        k_q2 = af.to_array(k_q2)
        k_q1 = af.to_array(k_q1)

        af.eval(k_q1, k_q2)
        return(k_q1, k_q2)
Esempio n. 21
0
def cloud_charge_deposition(charge, no_of_particles, positions_x, positions_y,
                            x_center_grid, y_center_grid, shape_function,
                            ghost_cells, Lx, Ly, dx, dy):

    elements = x_center_grid.elements() * y_center_grid.elements()

    rho_x_indices, rho_y_indices, rho_values_at_these_indices = shape_function(
        charge, positions_x, positions_y, x_center_grid, y_center_grid,
        ghost_cells, Lx, Ly)

    input_indices = (rho_x_indices * (y_center_grid.elements()) +
                     rho_y_indices)

    rho, temp = np.histogram(input_indices,
                             bins=elements,
                             range=(0, elements),
                             weights=rho_values_at_these_indices)
    rho = af.data.moddims(af.to_array(rho), y_center_grid.elements(),
                          x_center_grid.elements())

    # Periodic BC's for charge deposition

    rho[0, :] = rho[-1, :] + rho[0, :]
    rho[-1, :] = rho[0, :].copy()
    rho[:, 0] = rho[:, -1] + rho[:, 0]
    rho[:, -1] = rho[:, 0].copy()

    af.eval(rho)

    return rho
Esempio n. 22
0
def test_calculate_q():
    obj = test()
    q1, q2 = calculate_q_center(obj)

    q1_expected = obj.q1_start + \
        (0.5 + np.arange(-obj.N_ghost, obj.N_q1 + obj.N_ghost)) * obj.dq1
    q2_expected = obj.q2_start + \
        (0.5 + np.arange(-obj.N_ghost, obj.N_q2 + obj.N_ghost)) * obj.dq2

    q2_expected, q1_expected = np.meshgrid(q2_expected, q1_expected)

    q1_expected = af.reorder(af.to_array(q1_expected), 2, 0, 1)
    q2_expected = af.reorder(af.to_array(q2_expected), 2, 0, 1)

    assert (af.sum(af.abs(q1_expected - q1)) == 0)
    assert (af.sum(af.abs(q2_expected - q2)) == 0)
Esempio n. 23
0
def load_distribution_function(self, file_name):
    """
    This function is used to load the distribution function from the
    dump file that was created by dump_distribution_function.

    Parameters
    ----------

    file_name : The distribution_function array will be loaded from this
                provided file name.

    Examples
    --------
    
    >> solver.load_distribution_function('distribution_function')
    
    The above statemant will load the distribution function data stored in the file
    distribution_function.h5 into self.f
    """
    viewer = PETSc.Viewer().createHDF5(file_name + '.h5', PETSc.Viewer.Mode.READ)
    self._glob_f.load(viewer)
    self.f_hat =   2 * fft2(af.to_array(self._glob_f_array.reshape(self.N_p1 * self.N_p2 * self.N_p3,
                                                                   self.N_species, self.N_q1, self.N_q2
                                                                  )
                                       )
                           ) / (self.N_q1 * self.N_q2)

    return
Esempio n. 24
0
def load_EM_fields(self, file_name):
    """
    This function is used to load the EM fields from the
    dump file that was created by dump_EM_fields.

    Parameters
    ----------

    file_name : The EM_fields array will be loaded from this
                provided file name.

    Examples
    --------
    
    >> solver.load_EM_fields('data_EM_fields')
    """

    viewer = PETSc.Viewer().createHDF5(file_name + '.h5', PETSc.Viewer.Mode.READ)
    self.fields_solver._glob_fields.load(viewer)

    self.fields_solver.fields_hat = \
        2 * fft2(af.to_array(self.fields_solver._glob_fields_array.reshape(6, 1, 
                                                                           self.N_q1, 
                                                                           self.N_q2
                                                                          )
                            )
                ) / (self.N_q1 * self.N_q2)
Esempio n. 25
0
    def _calculate_q_center(self):
        """
        Initializes the cannonical variables q1, q2 using a centered
        formulation. The size, and resolution are the same as declared
        under domain of the physical system object.
        """
        q1_center = self.q1_start + (0.5 + np.arange(self.N_q1)) * self.dq1
        q2_center = self.q2_start + (0.5 + np.arange(self.N_q2)) * self.dq2

        q2_center, q1_center = np.meshgrid(q2_center, q1_center)

        q2_center = af.to_array(q2_center)
        q1_center = af.to_array(q1_center)

        af.eval(q1_center, q2_center)
        return(q1_center, q2_center)
Esempio n. 26
0
def calculate_x(config):
  """
  Returns the 2D array of x which is used in the computations of the Cheng-Knorr code.

  Parameters:
  -----------
    config : Object config which is obtained by set() is passed to this file

  Output:
  -------
    x : Array holding the values of x tiled along axis 1
  """
  N_x       = config.N_x
  N_vel_x   = config.N_vel_x
  N_ghost_x = config.N_ghost_x

  left_boundary  = config.left_boundary
  right_boundary = config.right_boundary

  x  = np.linspace(left_boundary, right_boundary, N_x)
  dx = x[1] - x[0]

  x_ghost_left  = np.linspace(-(N_ghost_x)*dx + left_boundary, left_boundary - dx, N_ghost_x)
  x_ghost_right = np.linspace(right_boundary + dx, right_boundary + N_ghost_x*dx , N_ghost_x)

  x  = np.concatenate([x_ghost_left, x, x_ghost_right])
  x  = af.Array.as_type(af.to_array(x), af.Dtype.f64)
  x  = af.tile(x, 1, N_vel_x)

  af.eval(x)
  return x
Esempio n. 27
0
def load_distribution_function(self, file_name):
    """
    This function is used to load the distribution function from the
    dump file that was created by dump_distribution_function.

    Parameters
    ----------

    file_name : The distribution_function array will be loaded from this
                provided file name.

    Examples
    --------
    
    >> solver.load_distribution_function('distribution_function')
    
    The above statemant will load the distribution function data stored in the file
    distribution_function.h5 into self.f
    """
    viewer = PETSc.Viewer().createHDF5(file_name + '.h5', 
                                       PETSc.Viewer.Mode.READ, 
                                       comm=self._comm
                                      )
    self._glob_f.load(viewer)

    N_g = self.N_ghost
    self.f[:, N_g:-N_g, N_g:-N_g] = af.moddims(af.to_array(self._glob_f_array),
                                               self.N_p1 * self.N_p2 * self.N_p3,
                                               self.N_q1, self.N_q2
                                              )

    return
Esempio n. 28
0
def test_dump_moments():
    test_obj = test()
    dump_moments(test_obj, 'test_file')

    h5f = h5py.File('test_file.h5', 'r')
    moments_read = h5f['moments'][:]
    h5f.close()

    moments_read = np.swapaxes(moments_read, 0, 1)

    assert (af.sum(
        af.to_array(moments_read[:, :, 0]) -
        compute_moments_imported(test_obj, 'density')) == 0)

    assert (af.sum(
        af.to_array(moments_read[:, :, 1]) -
        compute_moments_imported(test_obj, 'energy')) == 0)
Esempio n. 29
0
def calculate_k(N_q1, N_q2, dq1, dq2):
    """
    Initializes the wave numbers k_q1 and k_q2 which will be 
    used when solving in fourier space.
    """
    k_q1 = 2 * np.pi * np.fft.fftfreq(N_q1, dq1)
    k_q2 = 2 * np.pi * np.fft.fftfreq(N_q2, dq2)

    k_q2, k_q1 = np.meshgrid(k_q2, k_q1)

    k_q1 = af.to_array(k_q1)
    k_q2 = af.to_array(k_q2)

    k_q1 = af.reorder(k_q1, 2, 3, 0, 1)
    k_q2 = af.reorder(k_q2, 2, 3, 0, 1)

    af.eval(k_q1, k_q2)
    return (k_q1, k_q2)
Esempio n. 30
0
def Umeda_2003(charge,\
               no_of_particles,\
               positions_x,\
               velocities_x,\
               x_center_grid,\
               ghost_cells,\
               Lx,\
               dx,\
               dt\
              ):
    '''
    function set_up_perturbation(positions_x, number_particles, N_divisions,\
                                 amplitude , k, length_domain_x\
                                ):
    -----------------------------------------------------------------------  
    Input variables: positions_x, number_particles, N_divisions, amplitude, k,length_domain_x

        positions_x: An one dimensional array of size equal to number of particles taken in the PIC code.
        It contains the positions of particles.

        number_particles: The number of electrons /macro particles

        N_divisions: The number of divisions considered for placing the macro particles

        amplitude: This is the amplitude of the density perturbation

        k_x: The is the wave number of the cosine density pertubation

        length_domain_x: This is the length of the domain in x direction

    -----------------------------------------------------------------------      
    returns: Jx
        This function returns a array positions_x such that there is a cosine density perturbation 
        of the given amplitude

    '''
    elements = x_center_grid.elements()

    Jx_x_indices, Jx_values_at_these_indices = Umeda_b1_deposition(charge,\
                                                                 positions_x,\
                                                                 velocities_x,\
                                                                 x_center_grid,\
                                                                 ghost_cells,\
                                                                 Lx,\
                                                                 dt\
                                                                )

    input_indices = (Jx_x_indices)
    Jx, temp = np.histogram(input_indices,
                            bins=elements,
                            range=(0, elements),
                            weights=Jx_values_at_these_indices)

    Jx = af.to_array(Jx)
    af.eval(Jx)

    return Jx
Esempio n. 31
0
def simple_interop(verbose = False):
    if af.AF_NUMPY_FOUND:
        import numpy as np
        n = np.random.random((5,))
        a = af.to_array(n)
        n2 = np.array(a)
        assert((n==n2).all())
        n2[:] = 0
        a.to_ndarray(n2)
        assert((n==n2).all())

        n = np.random.random((5,3))
        a = af.to_array(n)
        n2 = np.array(a)
        assert((n==n2).all())
        n2[:] = 0
        a.to_ndarray(n2)
        assert((n==n2).all())

        n = np.random.random((5,3,2))
        a = af.to_array(n)
        n2 = np.array(a)
        assert((n==n2).all())
        n2[:] = 0
        a.to_ndarray(n2)
        assert((n==n2).all())

        n = np.random.random((5,3,2,2))
        a = af.to_array(n)
        n2 = np.array(a)
        assert((n==n2).all())
        n2[:] = 0
        a.to_ndarray(n2)
        assert((n==n2).all())

    if af.AF_PYCUDA_FOUND and af.get_active_backend() == 'cuda':
        import pycuda.autoinit
        import pycuda.gpuarray as cudaArray
        n = np.random.random((5,))
        c = cudaArray.to_gpu(n)
        a = af.to_array(c)
        n2 = np.array(a)
        assert((n==n2).all())

        n = np.random.random((5,3))
        c = cudaArray.to_gpu(n)
        a = af.to_array(c)
        n2 = np.array(a)
        assert((n==n2).all())

        n = np.random.random((5,3,2))
        c = cudaArray.to_gpu(n)
        a = af.to_array(c)
        n2 = np.array(a)
        assert((n==n2).all())

        n = np.random.random((5,3,2,2))
        c = cudaArray.to_gpu(n)
        a = af.to_array(c)
        n2 = np.array(a)
        assert((n==n2).all())

    if af.AF_PYOPENCL_FOUND and af.backend.name() == 'opencl':
        # This needs fixing upstream
        # https://github.com/arrayfire/arrayfire/issues/1728

        # import pyopencl as cl
        # import pyopencl.array as clArray
        # ctx = cl.create_some_context()
        # queue = cl.CommandQueue(ctx)

        # n = np.random.random((5,))
        # c = cl.array.to_device(queue, n)
        # a = af.to_array(c)
        # n2 = np.array(a)
        # assert((n==n2).all())

        # n = np.random.random((5,3))
        # c = cl.array.to_device(queue, n)
        # a = af.to_array(c)
        # n2 = np.array(a)
        # assert((n==n2).all())

        # n = np.random.random((5,3,2))
        # c = cl.array.to_device(queue, n)
        # a = af.to_array(c)
        # n2 = np.array(a)
        # assert((n==n2).all())

        # n = np.random.random((5,3,2,2))
        # c = cl.array.to_device(queue, n)
        # a = af.to_array(c)
        # n2 = np.array(a)
        # assert((n==n2).all())
        pass

    if af.AF_NUMBA_FOUND and af.get_active_backend() == 'cuda':

        import numba
        from numba import cuda

        n = np.random.random((5,))
        c = cuda.to_device(n)
        a = af.to_array(c)
        n2 = np.array(a)
        assert((n==n2).all())

        n = np.random.random((5,3))
        c = cuda.to_device(n)
        a = af.to_array(c)
        n2 = np.array(a)
        assert((n==n2).all())

        n = np.random.random((5,3,2))
        c = cuda.to_device(n)
        a = af.to_array(c)
        n2 = np.array(a)
        assert((n==n2).all())

        n = np.random.random((5,3,2,2))
        c = cuda.to_device(n)
        a = af.to_array(c)
        n2 = np.array(a)
        assert((n==n2).all())