Example #1
0
def test_matmul_3D():
    '''
    '''
    M = 3
    N = 2
    P = 4
    Q = 2

    a = af.range(M * N * Q, dtype=af.Dtype.u32)
    b = af.range(N * P * Q, dtype=af.Dtype.u32)

    a = af.moddims(a, d0=M, d1=N, d2=Q)
    b = af.moddims(b, d0=N, d1=P, d2=Q)

    a_init = a
    b_init = b

    ref_a_0 = np.matmul(np.array(a_init[:, :, 0]), np.array(b_init[:, :, 0]))

    ref_a_1 = np.matmul(np.array(a_init[:, :, 1]), np.array(b_init[:, :, 1]))

    test_matmul = np.array(utils.matmul_3D(a, b))

    diff_mat_0 = np.abs(test_matmul[:, :, 0] - ref_a_0)
    diff_mat_1 = np.abs(test_matmul[:, :, 1] - ref_a_1)

    assert np.all(diff_mat_0 == 0) and np.all(diff_mat_1 == 0)
Example #2
0
def test_poly1d_prod():
    '''
    Checks the product of the polynomials of different degrees using the
    poly1d_product function and compares it to the analytically calculated
    product coefficients.
    '''

    N = 3

    N_a = 3
    poly_a = af.range(N * N_a, dtype=af.Dtype.u32)
    poly_a = af.moddims(poly_a, d0=N, d1=N_a)

    N_b = 2
    poly_b = af.range(N * N_b, dtype=af.Dtype.u32)
    poly_b = af.moddims(poly_b, d0=N, d1=N_b)

    ref_poly = af.np_to_af_array(
        np.array([[0., 0., 9., 18.], [1., 8., 23., 28.], [4., 20., 41., 40.]]))

    test_poly1d_prod = utils.poly1d_product(poly_a, poly_b)
    test_poly1d_prod_commutative = utils.poly1d_product(poly_b, poly_a)

    diff = af.abs(test_poly1d_prod - ref_poly)
    diff_commutative = af.abs(test_poly1d_prod_commutative - ref_poly)

    assert af.all_true(diff == 0.) and af.all_true(diff_commutative == 0.)
Example #3
0
def polyval_2d(poly_2d, xi, eta):
    '''
    '''
    poly_2d_shape = poly_2d.shape
    poly_xy = af.tile(poly_2d, d0 = 1, d1 = 1, d2 = 1, d3 = xi.shape[0])
    poly_xy_shape = poly_xy.shape
    # print(poly_xy)

    xi_power = af.flip(af.range(poly_xy_shape[1], dtype = af.Dtype.u32))
    xi_power = af.tile(af.transpose(xi_power), d0 = poly_xy_shape[0])
    xi_power = af.tile(xi_power, d0 = 1, d1 = 1, d2 = xi.shape[0])

    eta_power = af.flip(af.range(poly_xy_shape[0], dtype = af.Dtype.u32))
    eta_power = af.tile(eta_power, d0 = 1, d1 = poly_xy_shape[1])
    eta_power = af.tile(eta_power, d0 = 1, d1 = 1, d2 = eta.shape[0])

    Xi = af.reorder(xi, d0 = 2, d1 = 1, d2 = 0)
    Xi = af.tile(Xi, d0 = poly_xy_shape[0], d1 = poly_xy_shape[1])
    Xi = af.pow(Xi, xi_power)
    Xi = af.reorder(Xi, d0 = 0, d1 = 1, d2 = 3, d3 = 2)
    # print(Xi)

    Eta = af.reorder(eta, d0 = 2, d1 = 1, d2 = 0)
    Eta = af.tile(Eta, d0 = poly_xy_shape[0], d1 = poly_xy_shape[1])
    Eta = af.pow(Eta, eta_power)
    Eta = af.reorder(Eta, d0 = 0, d1 = 1, d2 = 3, d3 = 2)
    # print(Eta)

    Xi_Eta = Xi * Eta

    poly_val = af.broadcast(multiply, poly_xy, Xi_Eta)
    poly_val = af.sum(af.sum(poly_val, dim = 1), dim = 0)
    poly_val = af.reorder(poly_val, d0 = 2, d1 = 3, d2 = 0, d3 = 1)

    return poly_val
Example #4
0
def integrate(integrand_coeffs):
    '''
    Performs integration according to the given quadrature method
    by taking in the coefficients of the polynomial and the number of
    quadrature points.
    The number of quadrature points and the quadrature scheme are set
    in params.py module.
    
    Parameters
    ----------
    
    integrand_coeffs : arrayfire.Array [M N 1 1]
                       The coefficients of M number of polynomials of order N
                       arranged in a 2D array.
    Returns
    -------
    
    Integral : arrayfire.Array [M 1 1 1]
               The value of the definite integration performed using the
               specified quadrature method for M polynomials.

    '''

    integrand = integrand_coeffs

    if (params.scheme == 'gauss_quadrature'):
        #print('gauss_quad')

        gaussian_nodes = params.gauss_points
        Gauss_weights = params.gauss_weights

        nodes_tile = af.transpose(
            af.tile(gaussian_nodes, 1, integrand.shape[1]))
        power = af.flip(af.range(integrand.shape[1]))
        nodes_power = af.broadcast(utils.power, nodes_tile, power)
        weights_tile = af.transpose(
            af.tile(Gauss_weights, 1, integrand.shape[1]))
        nodes_weight = nodes_power * weights_tile

        value_at_gauss_nodes = af.matmul(integrand, nodes_weight)
        integral = af.sum(value_at_gauss_nodes, 1)

    if (params.scheme == 'lobatto_quadrature'):
        #print('lob_quad')

        lobatto_nodes = params.lobatto_quadrature_nodes
        Lobatto_weights = params.lobatto_weights_quadrature

        nodes_tile = af.transpose(af.tile(lobatto_nodes, 1,
                                          integrand.shape[1]))
        power = af.flip(af.range(integrand.shape[1]))
        nodes_power = af.broadcast(utils.power, nodes_tile, power)
        weights_tile = af.transpose(
            af.tile(Lobatto_weights, 1, integrand.shape[1]))
        nodes_weight = nodes_power * weights_tile

        value_at_lobatto_nodes = af.matmul(integrand, nodes_weight)
        integral = af.sum(value_at_lobatto_nodes, 1)

    return integral
Example #5
0
    def calc_transfer_func(side,
                           wavelength,
                           defocus_change,
                           pad_periods=0,
                           spher_aber_coeff=None,
                           aperture_mask=None):

        px_dim = 1. + pad_periods

        ctf_coeff = np.pi * wavelength * defocus_change

        rec_px_width = 1.0 / (side * px_dim)
        rec_origin = -1.0 / (2.0 * px_dim)

        rec_x_dist = rec_origin + rec_px_width * af.range(side, side, dim=0)
        rec_y_dist = rec_origin + rec_px_width * af.range(side, side, dim=1)
        rec_dist2 = rec_x_dist * rec_x_dist + rec_y_dist * rec_y_dist

        ctf_phase = ctf_coeff * rec_dist2

        if spher_aber_coeff:
            ctf_phase += 0.5 * np.pi * wavelength**3 * spher_aber_coeff * rec_dist2**2

        ctf = af.cos(ctf_phase) + complex(0, 1) * af.sin(ctf_phase)

        if aperture_mask:
            ctf *= aperture_mask

        return ctf.as_type(af.Dtype.c32)
Example #6
0
def af_gaussianDerivative1D(s,order):
  radius = int(round(3*s + 0.5*order))
  size = radius*2+1
  csize = ct.c_int(size)
  csigma = ct.c_double(s)
  d_k = af.Array()
  af.safe_call(af.backend.get().af_gaussian_kernel(ct.pointer(d_k.arr),csize,1,csigma,0))
  if order == 1:
    afx=af.range(size)-radius
    return -afx/s/s*d_k
  if order == 2:
    afx=((af.range(size)-radius)**2-s*s)
    return afx/(s**4)*d_k
  return d_k
Example #7
0
def polyval_1d(polynomials, xi):
    '''
    Finds the value of the polynomials at the given :math:`\\xi` coordinates.

    Parameters
    ----------
    polynomials : af.Array [number_of_polynomials N 1 1]
                 ``number_of_polynomials`` :math:`2D` polynomials of degree
                 :math:`N - 1` of the form

                 .. math:: P(x) = a_0x^0 + a_1x^1 + ... \\
                           a_{N - 1}x^{N - 1} + a_Nx^N
    xi      : af.Array [N 1 1 1]
              :math:`\\xi` coordinates at which the :math:`i^{th}` Lagrange
              basis polynomial is to be evaluated.

    Returns
    -------
    af.Array [i.shape[0] xi.shape[0] 1 1]
        Evaluated polynomials at given :math:`\\xi` coordinates
    '''

    N = int(polynomials.shape[1])
    xi_ = af.tile(af.transpose(xi), d0=N)
    power = af.tile(af.flip(af.range(N), dim=0), d0=1, d1=xi.shape[0])

    xi_power = xi_**power

    return af.matmul(polynomials, xi_power)
Example #8
0
def simple_data(verbose=False):
    display_func = _util.display_func(verbose)

    display_func(af.constant(100, 3, 3, dtype=af.Dtype.f32))
    display_func(af.constant(25, 3, 3, dtype=af.Dtype.c32))
    display_func(af.constant(2**50, 3, 3, dtype=af.Dtype.s64))
    display_func(af.constant(2+3j, 3, 3))
    display_func(af.constant(3+5j, 3, 3, dtype=af.Dtype.c32))

    display_func(af.range(3, 3))
    display_func(af.iota(3, 3, tile_dims=(2, 2)))

    display_func(af.identity(3, 3, 1, 2, af.Dtype.b8))
    display_func(af.identity(3, 3, dtype=af.Dtype.c32))

    a = af.randu(3, 4)
    b = af.diag(a, extract=True)
    c = af.diag(a, 1, extract=True)

    display_func(a)
    display_func(b)
    display_func(c)

    display_func(af.diag(b, extract=False))
    display_func(af.diag(c, 1, extract=False))

    display_func(af.join(0, a, a))
    display_func(af.join(1, a, a, a))

    display_func(af.tile(a, 2, 2))

    display_func(af.reorder(a, 1, 0))

    display_func(af.shift(a, -1, 1))

    display_func(af.moddims(a, 6, 2))

    display_func(af.flat(a))

    display_func(af.flip(a, 0))
    display_func(af.flip(a, 1))

    display_func(af.lower(a, False))
    display_func(af.lower(a, True))

    display_func(af.upper(a, False))
    display_func(af.upper(a, True))

    a = af.randu(5, 5)
    display_func(af.transpose(a))
    af.transpose_inplace(a)
    display_func(a)

    display_func(af.select(a > 0.3, a, -0.3))

    af.replace(a, a > 0.3, -0.3)
    display_func(a)

    display_func(af.pad(a, (1, 1, 0, 0), (2, 2, 0, 0)))
Example #9
0
def simple_data(verbose=False):
    display_func = _util.display_func(verbose)
    print_func   = _util.print_func(verbose)

    display_func(af.constant(100, 3,3, dtype=af.Dtype.f32))
    display_func(af.constant(25, 3,3, dtype=af.Dtype.c32))
    display_func(af.constant(2**50, 3,3, dtype=af.Dtype.s64))
    display_func(af.constant(2+3j, 3,3))
    display_func(af.constant(3+5j, 3,3, dtype=af.Dtype.c32))

    display_func(af.range(3, 3))
    display_func(af.iota(3, 3, tile_dims=(2,2)))

    display_func(af.identity(3, 3, 1, 2, af.Dtype.b8))
    display_func(af.identity(3, 3, dtype=af.Dtype.c32))

    a = af.randu(3, 4)
    b = af.diag(a, extract=True)
    c = af.diag(a, 1, extract=True)

    display_func(a)
    display_func(b)
    display_func(c)

    display_func(af.diag(b, extract = False))
    display_func(af.diag(c, 1, extract = False))

    display_func(af.join(0, a, a))
    display_func(af.join(1, a, a, a))

    display_func(af.tile(a, 2, 2))


    display_func(af.reorder(a, 1, 0))

    display_func(af.shift(a, -1, 1))

    display_func(af.moddims(a, 6, 2))

    display_func(af.flat(a))

    display_func(af.flip(a, 0))
    display_func(af.flip(a, 1))

    display_func(af.lower(a, False))
    display_func(af.lower(a, True))

    display_func(af.upper(a, False))
    display_func(af.upper(a, True))

    a = af.randu(5,5)
    display_func(af.transpose(a))
    af.transpose_inplace(a)
    display_func(a)

    display_func(af.select(a > 0.3, a, -0.3))

    af.replace(a, a > 0.3, -0.3)
    display_func(a)
Example #10
0
def polynomial_derivative(polynomial):
    '''
    '''
    derivtive_multiplier = af.tile(af.transpose(af.flip(
        af.range(polynomial.shape[1]))),
                                   d0 = polynomial.shape[0])
    
    return (polynomial * derivtive_multiplier)[:, : -1]
Example #11
0
def lagrange_function_value(lagrange_coeff_array):
    '''

    Funtion to calculate the value of lagrange basis functions over LGL
    nodes.

    Parameters
    ----------
    
    lagrange_coeff_array : arrayfire.Array[N_LGL N_LGL 1 1]
                           Contains the coefficients of the
                           Lagrange basis polynomials
    
    Returns
    -------
    
    L_i : arrayfire.Array [N 1 1 1]
          The value of lagrange basis functions calculated over the LGL
          nodes.

    **Examples**
    
    lagrange_function_value(4) gives the value of the four
    Lagrange basis functions evaluated over 4 LGL points
    arranged in a 2D array where Lagrange polynomials
    evaluated at the same LGL point are in the same column.
    
    Also the value lagrange basis functions at LGL points has the property,
    
    L_i(xi_k) = 0 for i != k
              = 1 for i  = k
    
    It follows then that lagrange_function_value returns an identity matrix.
    
    '''
    xi_tile = af.transpose(af.tile(params.xi_LGL, 1, params.N_LGL))
    power = af.flip(af.range(params.N_LGL))
    power_tile = af.tile(power, 1, params.N_LGL)
    xi_pow = af.arith.pow(xi_tile, power_tile)
    index = af.range(params.N_LGL)
    L_i = af.blas.matmul(lagrange_coeff_array[index], xi_pow)

    return L_i
Example #12
0
def dct1(arr, norm=None):
    N = arr.dims()[0]
    out = 2 * af.real(
        af.exp(-0.5j * np.pi / N *
               af.range(*arr.dims(), dim=0, dtype=arr.dtype())) *
        af.fft(af.join(0, arr[0:N:2], af.flip(arr[1:N:2]))))
    if norm == 'ortho':
        out /= np.sqrt(2 * N)
        out[0] /= np.sqrt(2)
    return out
Example #13
0
    def gaussian(dims, sigmas, **kwargs):
        alpha = 1.0
        grid = af.constant(1.0, dims[0])
        multiplier = -0.5 * alpha / pow(sigmas[0], 2)
        exponent = af.pow(
            (af.range(dims[0], dim=0) - (dims[0] - 1) / 2.0), 2) * multiplier
        grid = grid * af.arith.exp(exponent)

        grid_tot = af.sum(grid, dim=0)
        grid_total = af.tile(grid_tot, dims[0])
        grid = grid / grid_total
        return grid
Example #14
0
 def predict(self, X):
     near_locs, near_dists = af.vision.nearest_neighbour(X, self._data, self._dim, \
                                                         self._num_nearest, self._match_type)
     weights = self._get_neighbor_weights(near_dists)
     top_labels = af.moddims(self._labels[near_locs], \
                             get_dims(near_locs)[0], get_dims(near_locs)[1])
     accum_weights = af.scan_by_key(
         top_labels, weights)  # reduce by key would be more ideal
     _, max_weight_locs = af.imax(accum_weights, dim=0)
     pred_idxs = af.range(get_dims(accum_weights)[1]) * get_dims(
         accum_weights)[0] + max_weight_locs.T
     top_labels_flat = af.flat(top_labels)
     pred_classes = top_labels_flat[pred_idxs]
     return pred_classes
Example #15
0
 def _predict(self, query, train_feats, train_labels, k, dist_type,
              weight_by_dist):
     near_locs, near_dists = af.vision.nearest_neighbour(query, train_feats, 1, \
                                                         k, dist_type)
     weights = self._get_neighbor_weights(near_dists, weight_by_dist, k)
     top_labels = af.moddims(train_labels[near_locs], \
                             near_locs.dims()[0], near_locs.dims()[1])
     accum_weights = af.scan_by_key(
         top_labels, weights)  # reduce by key would be more ideal
     _, max_weight_locs = af.imax(accum_weights, dim=0)
     pred_idxs = af.range(accum_weights.dims()
                          [1]) * accum_weights.dims()[0] + max_weight_locs.T
     top_labels_flat = af.flat(top_labels)
     pred_classes = top_labels_flat[pred_idxs]
     return pred_classes
Example #16
0
def linspace(start, end, number_of_points):
    '''
    Linspace implementation using arrayfire.

    Returns
    -------
    X : arrayfire.Array
        An array which contains ``number_of_points`` evenly spaced points
        between ``start`` and ``end``.
    '''
    X = af.range(number_of_points, dtype = af.Dtype.f64)
    d = (end - start) / (number_of_points - 1)
    X = X * d
    X = X + start

    return X
Example #17
0
def idct1(arr, norm=None):
    N = arr.dims()[0]
    tmp = arr.copy()
    offset = af.tile(tmp[0], N)
    tmp[0] = 0.
    tmp = 2 * af.real(
        af.ifft(
            af.exp(0.5j * np.pi / N *
                   af.range(*arr.dims(), dim=0, dtype=arr.dtype())) * tmp) * N)
    out = af.constant(0, *arr.dims(), dtype=arr.dtype())
    out[0:N:2] = tmp[:N // 2]
    out[1:N:2] = af.flip(tmp[N // 2:])
    if norm == 'ortho':
        offset /= np.sqrt(N)
        out /= np.sqrt(2 * N)
    out += offset
    tmp = offset = None
    return out
Example #18
0
def genGrid(size, dx, flag_shift=False):
    """
    This function generates 1D Fourier grid, and is centered at the middle of the array
    Inputs:
        size    - length of the array
        dx      - pixel size
    Optional parameters:
        flag_shift - flag indicating whether the final array is circularly shifted
                     should be false when computing real space coordinates
                     should be true when computing Fourier coordinates
    Outputs:
        xlin       - 1D Fourier grid

    """
    xlin = (af.range(size) - size // 2) * dx
    if flag_shift:
        xlin = af.shift(xlin, -1 * size // 2)
    return xlin.as_type(af_complex_datatype)
Example #19
0
# Copyright (c) 2015, ArrayFire
# All rights reserved.
#
# This file is distributed under 3-clause BSD license.
# The complete license agreement can be obtained at:
# http://arrayfire.com/licenses/BSD-3-Clause
########################################################

import arrayfire as af

af.info()

ITERATIONS = 200
POINTS = int(10.0 * ITERATIONS)

Z = 1 + af.range(POINTS) / ITERATIONS

win = af.Window(800, 800, "3D Plot example using ArrayFire")

t = 0.1
while not win.close():
    X = af.cos(Z * t + t) / Z
    Y = af.sin(Z * t + t) / Z

    X = af.maxof(af.minof(X, 1), -1)
    Y = af.maxof(af.minof(Y, 1), -1)

    Pts = af.join(1, X, Y, Z)
    win.plot3(Pts)
    t = t + 0.01
Example #20
0
A_1d = af.moddims(A, A.dims()[0]*A.dims()[1])

print ("A")
print (A)
print (A_1d)

# Aim : at each point in length, shift the array by a different value say [1, 2, 0, -1]
shifts = [1, 2, 0, -1]
shifts = af.Array(shifts) #Convert to af array

print ("Shifts")
print (shifts)


# Generate the shift_indices 2D array
temp = af.range(A.dims()[0])

shift_indices = 0.*A
index = 0
for value in shifts:
    print (value.scalar())
    shift_indices[:, index] = af.shift(temp.dims()[0]*index+temp, int(value.scalar()))
    index = index + 1


shift_indices_1d = af.moddims(shift_indices, shift_indices.dims()[0]*shift_indices.dims()[1])

print ("Shift indices")
print (shift_indices)
print (shift_indices_1d)
Example #21
0
def compute_shift_indices(q1, q2, p1, p2, p3, params):
    """
    Inject the shift_indices corresponding to a shift operation of -2*theta for the left boundary,
    where theta is the angular variation of the left boundary.
    """
    N_theta = domain.N_p2  # TODO run this and check
    N_g = domain.N_ghost

    d_q1 = (q1[0, 0, 1, 0] - q1[0, 0, 0, 0]).scalar()
    d_q2 = (q2[0, 0, 0, 1] - q2[0, 0, 0, 0]).scalar()

    N_q1_local = q1.dims()[2]
    N_q2_local = q2.dims()[3]

    # Define edge indices
    left_edge = N_g
    right_edge = -N_g - 1
    bottom_edge = N_g
    top_edge = -N_g - 1

    temp = af.range(N_theta)  # Indices with no shift. Shape : N_theta

    # Left boundary

    # Initialize to zero
    shift_indices = (0. * q1 * p1)[:, 0, 0, :]

    # Get the angular variation of the left boundary.
    theta_left = get_theta(q1, q2, "left", \
                           q1_start_local_left=params.q1_start_local_left, \
                           q2_start_local_bottom=params.q2_start_local_bottom)[0, 0, left_edge, :]

    theta_left = af.moddims(theta_left, N_q2_local)  # Convert to 1D array

    # Apply manually specified mirror angles only if left boundary of the zone is the left boundary of the device
    is_left_most_domain = abs(params.q1_start_local_left -
                              domain.q1_start) < 1e-13

    if (params.enable_manual_mirror and is_left_most_domain):
        theta_left = 0. * theta_left + params.mirror_angles[3]

    # TODO : Dumping theta for testing
#    if (params.rank == 5):
#        np.savetxt("/home/quazartech/bolt/example_problems/electronic_boltzmann/circular_domain_method_2/theta_right.txt", theta_left[N_g:-N_g])

# Calculate the number of shifts of the array along the p_theta axis
# required for an angular shift of -2*theta_left
    shifts = -((2 * theta_left) / (2 * np.pi)) * N_theta

    # Populate shift_indices 2D array using shifts.
    for index, value in enumerate(shifts):
        shift_indices[:, 0, 0, index] = af.shift(N_theta * index + temp,
                                                 int(value.scalar()))

    # Convert into a 1D array
    shift_indices_left = af.moddims(shift_indices, N_theta * N_q2_local)

    # Right boundary

    # Initialize to zero
    shift_indices = (0. * q1 *
                     p1)[:, 0, 0, :]  # Shape : N_theta x 1 x 1 x N_q2+2*N_g

    # Get the angular variation of the right boundary.
    theta_right = get_theta(q1, q2, "right", \
                            q1_start_local_left=params.q1_start_local_left, \
                            q2_start_local_bottom=params.q2_start_local_bottom)[0, 0, right_edge, :]
    theta_right = af.moddims(theta_right, N_q2_local)  # Convert to 1D array

    q1_end_local_right = params.q1_start_local_left + (N_q1_local -
                                                       2 * N_g) * d_q1

    # Apply manually specified mirror angles only if right boundary of the zone is the right boundary of the device
    is_right_most_domain = abs(q1_end_local_right - domain.q1_end) < 1e-13

    if (params.enable_manual_mirror and is_right_most_domain):
        theta_right = 0. * theta_right + params.mirror_angles[1]

    # TODO : Dumping theta for testing
#    if (params.rank == 3):
#        np.savetxt("/home/quazartech/bolt/example_problems/electronic_boltzmann/circular_domain_method_2/theta_left.txt", theta_right[N_g:-N_g])

#    if (params.rank == 1):
#        np.savetxt("/home/mchandra/gitansh/merge_to_master/example_problems/electronic_boltzmann/test_quadratic/theta_right.txt", theta_bottom[N_g:-N_g])

# Calculate the number of shifts of the array along the p_theta axis
# required for an angular shift of -2*theta_right
    shifts = -(theta_right / np.pi) * N_theta

    # Populate shift_indices 2D array using shifts.
    for index, value in enumerate(shifts):
        shift_indices[:, 0, 0, index] = af.shift(N_theta * index + temp,
                                                 int(value.scalar()))

    # Convert into a 1D array
    shift_indices_right = af.moddims(shift_indices, N_theta * N_q2_local)

    # Bottom boundary

    # Initialize to zero
    shift_indices = (0. * q1 * p1)[:, 0, :,
                                   0]  # Shape : N_theta x 1 x  N_q1+2*N_g x 1

    # Get the angular variation of the bottom boundary.
    theta_bottom = get_theta(q1, q2, "bottom", \
                             q1_start_local_left=params.q1_start_local_left, \
                             q2_start_local_bottom=params.q2_start_local_bottom)[0, 0, :, bottom_edge]
    theta_bottom = af.moddims(theta_bottom, N_q1_local)  # Convert to 1D array

    # TODO : Dumping theta for testing
    #    if (params.rank == 7):
    #        np.savetxt("/home/quazartech/bolt/example_problems/electronic_boltzmann/circular_domain_method_2/theta_top.txt", theta_bottom[N_g:-N_g])

    # Apply manually specified mirror angles only if bottom boundary of the zone is the bottom boundary of the device
    is_bottom_most_domain = abs(params.q2_start_local_bottom -
                                domain.q2_start) < 1e-13

    if (params.enable_manual_mirror and is_bottom_most_domain):
        theta_bottom = 0. * theta_bottom + params.mirror_angles[0]

    # Calculate the number of shifts of the array along the p_theta axis
    # required for an angular shift of -2*theta_bottom
    shifts = -(theta_bottom / np.pi) * N_theta

    # Populate shift_indices 2D array using shifts.
    for index, value in enumerate(shifts):
        shift_indices[:, 0, index, 0] = af.shift(N_theta * index + temp,
                                                 int(value.scalar()))

    # Convert into a 1D array
    shift_indices_bottom = af.moddims(shift_indices, N_theta * N_q1_local)

    # Top Boundary

    # Initialize to zero
    shift_indices = (0. * q1 * p1)[:, 0, :,
                                   0]  # Shape : N_theta x 1 x N_q1+2*N_g x 1

    # Get the angular variation of the top boundary.
    theta_top = get_theta(q1, q2, "top", \
                          q1_start_local_left=params.q1_start_local_left, \
                          q2_start_local_bottom=params.q2_start_local_bottom)[0, 0, :, top_edge]
    theta_top = af.moddims(theta_top, N_q1_local)  # Convert to 1D array

    q2_end_local_top = params.q2_start_local_bottom + (N_q2_local -
                                                       2 * N_g) * d_q2

    # Apply manually specified mirror angles only if top boundary of the zone is the top boundary of the device
    is_top_most_domain = abs((q2_end_local_top - domain.q2_end)) < 1e-13

    if (params.enable_manual_mirror and is_top_most_domain):
        theta_top = 0. * theta_top + params.mirror_angles[2]

    # TODO : Dumping theta for testing


#    if (params.rank == 1):
#        np.savetxt("/home/quazartech/bolt/example_problems/electronic_boltzmann/circular_domain_method_2/theta_bottom.txt", theta_top[N_g:-N_g])

# Calculate the number of shifts of the array along the p_theta axis
# required for an angular shift of -2*theta_top
    shifts = -(theta_top / np.pi) * N_theta

    # Populate shift_indices 2D array using shifts.
    for index, value in enumerate(shifts):
        shift_indices[:, 0, index, 0] = af.shift(N_theta * index + temp,
                                                 int(value.scalar()))

    #Convert to a 1D array
    shift_indices_top = af.moddims(shift_indices, N_theta * N_q1_local)

    return (shift_indices_left, shift_indices_right, shift_indices_bottom,
            shift_indices_top)
Example #22
0

# phase unwrapping, see DOI: 10.3390/jimaging1010031
def unwrap_dct(arr):
    return arr + af.round(
        (laplacian(af.cos(arr) * laplacian(af.sin(arr)) -
                   af.sin(arr) * laplacian(af.cos(arr)),
                   inverse=True) - arr) / 2 / np.pi) * 2 * np.pi


# phase map dims, zeropadding and masking should be avoided if possible
N = 1024
M = 1024

# make some coordinates for the synthetic phase map
x = af.range(N, M, dim=1)
y = af.range(N, M, dim=0)
x /= af.max(x) / np.pi / 2
y /= af.max(y) / np.pi / 2

snr = 10  # SNR for the Gaussian noise

# some synthetic phase maps
phase_orig = af.sin(x) * x + af.cos(y) * y
#phase_orig = af.sin(x*y)*x+af.cos(x*x+y*y)*y
#phase_orig = (x-af.max(x)/2)**2 + (y-af.max(y)/2)**2
x = y = None
phase_orig /= af.max(
    af.abs(phase_orig)) / np.pi / 4  # scale phase map amplitude
phase_orig += af.to_array(
    np.random.normal(scale=np.sqrt(0.5 / snr),
Example #23
0
# An array containing the coefficients of the lagrange basis polynomials.
lagrange_coeffs            = af.np_to_af_array(\
                                lagrange.lagrange_polynomials(xi_LGL)[1])

# Refer corresponding functions.
lagrange_basis_value = lagrange.lagrange_function_value(lagrange_coeffs)


# While evaluating the volume integral using N_LGL
# lobatto quadrature points, The integration can be vectorized
# and in this case the coefficients of the differential of the
# Lagrange polynomials is required


diff_pow      = (af.flip(af.transpose(af.range(N_LGL - 1) + 1), 1))
dl_dxi_coeffs = (af.broadcast(utils.multiply, lagrange_coeffs[:, :-1], diff_pow))

# Obtaining an array consisting of the LGL points mapped onto the elements.

element_size    = af.sum((x_nodes[1] - x_nodes[0]) / N_Elements)
elements_xi_LGL = af.constant(0, N_Elements, N_LGL)
elements        = utils.linspace(af.sum(x_nodes[0]),
                  af.sum(x_nodes[1] - element_size), N_Elements)

np_element_array   = np.concatenate((af.transpose(elements),
                                     af.transpose(elements + element_size)))
element_mesh_nodes = utils.linspace(af.sum(x_nodes[0]),
                                    af.sum(x_nodes[1]),
                                    N_Elements + 1)
Example #24
0
def compute_shift_indices(q1, q2, p1, p2, p3, params):
    """
    Inject the shift_indices corresponding to a shift operation of -2*theta for the left boundary,
    where theta is the angular variation of the left boundary.
    """
    N_theta = domain.N_p2

    # Define edge indices
    left_edge = 0
    right_edge = -1
    bottom_edge = 0
    top_edge = -1

    temp = af.range(N_theta)  # Indices with no shift. Shape : N_theta

    # Left boundary

    # Initialize to zero
    shift_indices = (0. * q1 * p1)[:, 0, 0, :]
    N_q2_local = shift_indices.dims()[3]

    # Get the angular variation of the left boundary.
    theta_left = coords.get_theta(q1, q2, "left")[0, 0, left_edge, :]
    theta_left = af.moddims(theta_left, N_q2_local)  # Convert to 1D array

    # Calculate the number of shifts of the array along the p_theta axis
    # required for an angular shift of -2*theta_left
    shifts = -((2 * theta_left) / (2 * np.pi)) * N_theta

    # Populate shift_indices 2D array using shifts.
    for index, value in enumerate(shifts):
        shift_indices[:, 0, 0, index] = af.shift(N_theta * index + temp,
                                                 int(value.scalar()))

    # Convert into a 1D array
    shift_indices_left = af.moddims(shift_indices, N_theta * N_q2_local)

    # Right boundary

    # Initialize to zero
    shift_indices = (0. * q1 *
                     p1)[:, 0, 0, :]  # Shape : N_theta x 1 x 1 x N_q2+2*N_g

    # Get the angular variation of the right boundary.
    theta_right = coords.get_theta(q1, q2, "right")[0, 0, right_edge, :]
    theta_right = af.moddims(theta_right, N_q2_local)  # Convert to 1D array

    # Calculate the number of shifts of the array along the p_theta axis
    # required for an angular shift of -2*theta_right
    shifts = -(theta_right / np.pi) * N_theta

    # Populate shift_indices 2D array using shifts.
    for index, value in enumerate(shifts):
        shift_indices[:, 0, 0, index] = af.shift(N_theta * index + temp,
                                                 int(value.scalar()))

    # Convert into a 1D array
    shift_indices_right = af.moddims(shift_indices, N_theta * N_q2_local)

    # Bottom boundary

    # Initialize to zero
    shift_indices = (0. * q1 * p1)[:, 0, :,
                                   0]  # Shape : N_theta x 1 x  N_q1+2*N_g x 1
    N_q1_local = shift_indices.dims()[2]

    # Get the angular variation of the bottom boundary.
    theta_bottom = coords.get_theta(q1, q2, "bottom")[0, 0, :, bottom_edge]
    theta_bottom = af.moddims(theta_bottom, N_q1_local)  # Convert to 1D array

    # Calculate the number of shifts of the array along the p_theta axis
    # required for an angular shift of -2*theta_bottom
    shifts = -(theta_bottom / np.pi) * N_theta

    # Populate shift_indices 2D array using shifts.
    for index, value in enumerate(shifts):
        shift_indices[:, 0, index, 0] = af.shift(N_theta * index + temp,
                                                 int(value.scalar()))

    # Convert into a 1D array
    shift_indices_bottom = af.moddims(shift_indices, N_theta * N_q1_local)

    # Top Boundary

    # Initialize to zero
    shift_indices = (0. * q1 * p1)[:, 0, :,
                                   0]  # Shape : N_theta x 1 x N_q1+2*N_g x 1

    # Get the angular variation of the top boundary.
    theta_top = coords.get_theta(q1, q2, "top")[0, 0, :, top_edge]
    theta_top = af.moddims(theta_top, N_q1_local)  # Convert to 1D array

    # Calculate the number of shifts of the array along the p_theta axis
    # required for an angular shift of -2*theta_top
    shifts = -(theta_top / np.pi) * N_theta

    # Populate shift_indices 2D array using shifts.
    for index, value in enumerate(shifts):
        shift_indices[:, 0, index, 0] = af.shift(N_theta * index + temp,
                                                 int(value.scalar()))

    #Convert to a 1D array
    shift_indices_top = af.moddims(shift_indices, N_theta * N_q1_local)

    return (shift_indices_left, shift_indices_right, shift_indices_bottom,
            shift_indices_top)
# All rights reserved.
#
# This file is distributed under 3-clause BSD license.
# The complete license agreement can be obtained at:
# http://arrayfire.com/licenses/BSD-3-Clause
########################################################

import arrayfire as af

af.display(af.constant(100, 3,3, dtype=af.f32))
af.display(af.constant(25, 3,3, dtype=af.c32))
af.display(af.constant(2**50, 3,3, dtype=af.s64))
af.display(af.constant(2+3j, 3,3))
af.display(af.constant(3+5j, 3,3, dtype=af.c32))

af.display(af.range(3, 3))
af.display(af.iota(3, 3, tile_dims=(2,2)))

af.display(af.randu(3, 3, 1, 2))
af.display(af.randu(3, 3, 1, 2, af.b8))
af.display(af.randu(3, 3, dtype=af.c32))

af.display(af.randn(3, 3, 1, 2))
af.display(af.randn(3, 3, dtype=af.c32))

af.set_seed(1024)
assert(af.get_seed() == 1024)

af.display(af.identity(3, 3, 1, 2, af.b8))
af.display(af.identity(3, 3, dtype=af.c32))
Example #26
0
def volume_integral_flux(u_n):
    '''

    Calculates the volume integral of flux in the wave equation.

    :math:`\\int_{-1}^1 f(u) \\frac{d L_p}{d\\xi} d\\xi`

    This will give N values of flux integral as p varies from 0 to N - 1.
    
    This integral is carried out using the analytical form of the integrand
    obtained as a linear combination of Lagrange basis polynomials.

    This integrand is the used in the integrate() function.

    Calculation of volume integral flux using N_LGL Lobatto quadrature points
    can be vectorized and is much faster.
    
    Parameters
    ----------

    u : arrayfire.Array [N_LGL N_Elements M 1]
        Amplitude of the wave at the mapped LGL nodes of each element. This
        function can computer flux for :math:`M` :math:`u`.
            
    Returns
    -------

    flux_integral : arrayfire.Array [N_LGL N_Elements M 1]
                    Value of the volume integral flux. It contains the integral
                    of all N_LGL * N_Element integrands.

    '''
    shape_u_n = utils.shape(u_n)

    # The coefficients of dLp / d\xi
    diff_lag_coeff = params.dl_dxi_coeffs

    lobatto_nodes = params.lobatto_quadrature_nodes
    Lobatto_weights = params.lobatto_weights_quadrature

    nodes_tile = af.transpose(
        af.tile(lobatto_nodes, 1, diff_lag_coeff.shape[1]))
    power = af.flip(af.range(diff_lag_coeff.shape[1]))
    power_tile = af.tile(power, 1, params.N_quad)
    nodes_power = nodes_tile**power_tile
    weights_tile = af.transpose(
        af.tile(Lobatto_weights, 1, diff_lag_coeff.shape[1]))
    nodes_weight = nodes_power * weights_tile

    dLp_dxi = af.matmul(diff_lag_coeff, nodes_weight)

    # The first option to calculate the volume integral term, directly uses
    # the Lobatto quadrature instead of using the integrate() function by
    # passing the coefficients of the Lagrange interpolated polynomial.
    if(params.volume_integral_scheme == 'lobatto_quadrature' \
        and params.N_quad == params.N_LGL):

        # Flux using u_n, reordered to 1 X N_LGL X N_Elements array.
        F_u_n = af.reorder(flux_x(u_n), 3, 0, 1, 2)
        F_u_n = af.tile(F_u_n, d0=params.N_LGL)

        # Multiplying with dLp / d\xi
        integral_expansion = af.broadcast(utils.multiply, dLp_dxi, F_u_n)

        #     # Using the quadrature rule.
        flux_integral = af.sum(integral_expansion, 1)

        flux_integral = af.reorder(flux_integral, 0, 2, 3, 1)

    # Using the integrate() function to calculate the volume integral term
    # by passing the Lagrange interpolated polynomial.
    else:
        #print('option3')
        analytical_flux_coeffs = af.transpose(af.moddims(u_n,
                                                        d0 = params.N_LGL,
                                                        d1 = params.N_Elements \
                                                            * shape_u_n[2]))

        analytical_flux_coeffs = flux_x(
            lagrange.lagrange_interpolation(analytical_flux_coeffs))
        analytical_flux_coeffs = af.transpose(
            af.moddims(af.transpose(analytical_flux_coeffs),
                       d0=params.N_LGL,
                       d1=params.N_Elements,
                       d2=shape_u_n[2]))

        analytical_flux_coeffs = af.reorder(analytical_flux_coeffs,
                                            d0=3,
                                            d1=1,
                                            d2=0,
                                            d3=2)
        analytical_flux_coeffs = af.tile(analytical_flux_coeffs,
                                         d0=params.N_LGL)
        analytical_flux_coeffs = af.moddims(
            af.transpose(analytical_flux_coeffs),
            d0=params.N_LGL,
            d1=params.N_LGL * params.N_Elements,
            d2=1,
            d3=shape_u_n[2])

        analytical_flux_coeffs = af.moddims(analytical_flux_coeffs,
                                            d0=params.N_LGL,
                                            d1=params.N_LGL *
                                            params.N_Elements * shape_u_n[2],
                                            d2=1,
                                            d3=1)

        analytical_flux_coeffs = af.transpose(analytical_flux_coeffs)

        dl_dxi_coefficients    = af.tile(af.tile(params.dl_dxi_coeffs,
                                                 d0 = params.N_Elements), \
                                         d0 = shape_u_n[2])

        volume_int_coeffs = utils.poly1d_product(dl_dxi_coefficients,
                                                 analytical_flux_coeffs)

        flux_integral = lagrange.integrate(volume_int_coeffs)
        flux_integral = af.moddims(af.transpose(flux_integral),
                                   d0=params.N_LGL,
                                   d1=params.N_Elements,
                                   d2=shape_u_n[2])

    return flux_integral
def change_parameters(LGL, Elements, quad, wave='sin'):
    '''
    Changes the parameters of the simulation. Used only for convergence tests.
    Parameters
    ----------
    LGL      : int
               The new N_LGL.
    Elements : int
               The new N_Elements.
    '''
    # The domain of the function.
    params.x_nodes = af.np_to_af_array(np.array([-1., 1.]))

    # The number of LGL points into which an element is split.
    params.N_LGL = LGL

    # Number of elements the domain is to be divided into.
    params.N_Elements = Elements

    # The number quadrature points to be used for integration.
    params.N_quad = quad

    # Array containing the LGL points in xi space.
    params.xi_LGL = lagrange.LGL_points(params.N_LGL)

    # The weights of the lgl points
    params.weight_arr = lagrange.weight_arr_fun(params.xi_LGL)

    # N_Gauss number of Gauss nodes.
    params.gauss_points  = af.np_to_af_array(lagrange.gauss_nodes\
                                                    (params.N_quad))
    # The Gaussian weights.
    params.gauss_weights = lagrange.gaussian_weights(params.N_quad)

    # The lobatto nodes to be used for integration.
    params.lobatto_quadrature_nodes = lagrange.LGL_points(params.N_quad)

    # The lobatto weights to be used for integration.
    params.lobatto_weights_quadrature = lagrange.lobatto_weights\
                                        (params.N_quad)

    #The b matrix
    params.b_matrix = lagrange.b_matrix_eval()

    # A list of the Lagrange polynomials in poly1d form.
    #params.lagrange_product = lagrange.product_lagrange_poly(params.xi_LGL)

    # An array containing the coefficients of the lagrange basis polynomials.
    params.lagrange_coeffs  = af.np_to_af_array(\
                              lagrange.lagrange_polynomials(params.xi_LGL)[1])

    # Refer corresponding functions.
    params.lagrange_basis_value = lagrange.lagrange_function_value\
                                           (params.lagrange_coeffs)

    # While evaluating the volume integral using N_LGL
    # lobatto quadrature points, The integration can be vectorized
    # and in this case the coefficients of the differential of the
    # Lagrange polynomials is required
    params.diff_pow = (af.flip(af.transpose(af.range(params.N_LGL - 1) + 1),
                               1))
    params.dl_dxi_coeffs = (af.broadcast(utils.multiply,
                                         params.lagrange_coeffs[:, :-1],
                                         params.diff_pow))

    # Obtaining an array consisting of the LGL points mapped onto the elements.

    params.element_size    = af.sum((params.x_nodes[1] - params.x_nodes[0])\
                                                        / params.N_Elements)
    params.elements_xi_LGL = af.constant(0, params.N_Elements, params.N_LGL)
    params.elements        = utils.linspace(af.sum(params.x_nodes[0]),
                             af.sum(params.x_nodes[1] - params.element_size),\
                                                            params.N_Elements)
    params.np_element_array   = np.concatenate((af.transpose(params.elements),
                                   af.transpose(params.elements +\
                                                       params.element_size)))

    params.element_mesh_nodes = utils.linspace(af.sum(params.x_nodes[0]),
                                        af.sum(params.x_nodes[1]),\
                                               params.N_Elements + 1)

    params.element_array = af.transpose(af.np_to_af_array\
                                       (params.np_element_array))
    params.element_LGL   = wave_equation.mapping_xi_to_x(af.transpose\
                                          (params.element_array), params.xi_LGL)

    # The minimum distance between 2 mapped LGL points.
    params.delta_x = af.min(
        (params.element_LGL - af.shift(params.element_LGL, 1, 0))[1:, :])

    # dx_dxi for elements of equal size.
    params. dx_dxi = af.mean(wave_equation.dx_dxi_numerical((params.element_mesh_nodes[0 : 2]),\
                                   params.xi_LGL))

    # The value of time-step.
    params.delta_t = params.delta_x / (4 * params.c)

    # Array of timesteps seperated by delta_t.
    params.time = utils.linspace(
        0,
        int(params.total_time / params.delta_t) * params.delta_t,
        int(params.total_time / params.delta_t))

    # Initializing the amplitudes. Change u_init to required initial conditions.
    if (wave == 'sin'):
        params.u_init = af.sin(2 * np.pi * params.element_LGL)

    if (wave == 'gaussian'):
        params.u_init = np.e**(-(params.element_LGL)**2 / 0.4**2)

    params.u          = af.constant(0, params.N_LGL, params.N_Elements, params.time.shape[0],\
                                     dtype = af.Dtype.f64)
    params.u[:, :, 0] = params.u_init

    return
#!/usr/bin/python
import arrayfire as af

af.print_array(af.constant(100, 3,3, dtype=af.f32))
af.print_array(af.constant(25, 3,3, dtype=af.c32))
af.print_array(af.constant(2**50, 3,3, dtype=af.s64))
af.print_array(af.constant(2+3j, 3,3))
af.print_array(af.constant(3+5j, 3,3, dtype=af.c32))

af.print_array(af.range(3, 3))
af.print_array(af.iota(3, 3, tile_dims=(2,2)))

af.print_array(af.randu(3, 3, 1, 2))
af.print_array(af.randu(3, 3, 1, 2, af.b8))
af.print_array(af.randu(3, 3, dtype=af.c32))

af.print_array(af.randn(3, 3, 1, 2))
af.print_array(af.randn(3, 3, dtype=af.c32))

af.set_seed(1024)
assert(af.get_seed() == 1024)

af.print_array(af.identity(3, 3, 1, 2, af.b8))
af.print_array(af.identity(3, 3, dtype=af.c32))

a = af.randu(3, 4)
b = af.diag(a, extract=True)
c = af.diag(a, 1, extract=True)

af.print_array(a)
af.print_array(b)
Example #29
0
# Copyright (c) 2015, ArrayFire
# All rights reserved.
#
# This file is distributed under 3-clause BSD license.
# The complete license agreement can be obtained at:
# http://arrayfire.com/licenses/BSD-3-Clause
########################################################

import arrayfire as af
import math

POINTS = 10000
PRECISION = 1.0 / float(POINTS)

val = -math.pi
X = math.pi * (2 * (af.range(POINTS) / POINTS) - 1)

win = af.window(512, 512, "2D Plot example using ArrayFire")
sign = 1.0

while not win.close():
    Y = af.sin(X)
    win.plot(X, Y)

    X += PRECISION * sign
    val += PRECISION * sign

    if (val > math.pi):
        sign = -1.0
    elif (val < -math.pi):
        sign = 1.0
Example #30
0
    def __init__(self, N_LGL, N_quad, x_nodes, N_elements, c, total_time, wave,
                 c_x, c_y, courant, mesh_file, total_time_2d):
        '''
        Initializes the variables using the user parameters.
        
        Parameters
        ----------
        N_LGL : int
                Number of LGL points(for both :math:`2D` and :math:`1D` wave
                equation solver).
        N_quad : int
                 Number of the quadrature points to use in Gauss-Lobatto or
                 Gauss-Legendre quadrature.
        x_nodes : af.Array [2 1 1 1]
                  :math:`x` nodes for the :math:`1D` wave equation elements.
                  
        N_elements : int
                     Number of elements in a :math:`1D` domain.
                     
        c : float64
            Wave speed for 1D wave equation.
            
        total_time : float64
                     Total time for which :math:`1D` wave equation is to be
                     evolved.
                     
        wave : str
               Used to set u_init to ``sin`` or ``cos``.
               
        c_x : float64
              :math:`x` component of wave speed for a :math:`2D` wave.
              
        c_y : float64
              :math:`y` component of wave speed for a :math:`2D` wave.
              
        courant : float64
                  Courant parameter used for the time evolution of the wave.
                  
        mesh_file : str
                    Path of the mesh file for the 2D wave equation.
                    
        total_time_2d : float64
                        Total time for which the wave is to propogated.
        
        Returns
        -------
        None
        '''

        self.xi_LGL = lagrange.LGL_points(N_LGL)

        # N_Gauss number of Gauss nodes.
        self.gauss_points = af.np_to_af_array(lagrange.gauss_nodes(N_quad))

        # The Gaussian weights.
        self.gauss_weights = lagrange.gaussian_weights(N_quad)

        # The lobatto nodes to be used for integration.
        self.lobatto_quadrature_nodes = lagrange.LGL_points(N_quad)

        # The lobatto weights to be used for integration.
        self.lobatto_weights_quadrature = lagrange.lobatto_weights(N_quad)

        # An array containing the coefficients of the lagrange basis polynomials.
        self.lagrange_coeffs = lagrange.lagrange_polynomial_coeffs(self.xi_LGL)

        self.lagrange_basis_value = lagrange.lagrange_function_value(
            self.lagrange_coeffs, self.xi_LGL)

        self.diff_pow = af.flip(af.transpose(af.range(N_LGL - 1) + 1), 1)
        self.dl_dxi_coeffs = af.broadcast(utils.multiply,
                                          self.lagrange_coeffs[:, :-1],
                                          self.diff_pow)

        self.element_size = af.sum((x_nodes[1] - x_nodes[0]) / N_elements)
        self.elements_xi_LGL = af.constant(0, N_elements, N_LGL)
        self.elements = utils.linspace(af.sum(x_nodes[0]),
                                       af.sum(x_nodes[1] - self.element_size),
                                       N_elements)

        self.np_element_array = np.concatenate(
            (af.transpose(self.elements),
             af.transpose(self.elements + self.element_size)))

        self.element_mesh_nodes = utils.linspace(af.sum(x_nodes[0]),
                                                 af.sum(x_nodes[1]),
                                                 N_elements + 1)

        self.element_array = af.transpose(
            af.interop.np_to_af_array(self.np_element_array))
        self.element_LGL = wave_equation.mapping_xi_to_x(
            af.transpose(self.element_array), self.xi_LGL)

        # The minimum distance between 2 mapped LGL points.
        self.delta_x = af.min(
            (self.element_LGL - af.shift(self.element_LGL, 1, 0))[1:, :])

        # dx_dxi for elements of equal size.
        self.dx_dxi = af.mean(
            wave_equation.dx_dxi_numerical(self.element_mesh_nodes[0:2],
                                           self.xi_LGL))

        # The value of time-step.
        self.delta_t = self.delta_x / (4 * c)

        # Array of timesteps seperated by delta_t.
        self.time = utils.linspace(
            0,
            int(total_time / self.delta_t) * self.delta_t,
            int(total_time / self.delta_t))

        # Initializing the amplitudes. Change u_init to required initial conditions.
        if (wave == 'sin'):
            self.u_init = af.sin(2 * np.pi * self.element_LGL)

        if (wave == 'gaussian'):
            self.u_init = np.e**(-(self.element_LGL)**2 / 0.4**2)

        self.test_array = af.np_to_af_array(np.array(self.u_init))

        # The parameters below are for 2D advection
        # -----------------------------------------

        ########################################################################
        #######################2D Wave Equation#################################
        ########################################################################

        self.xi_i = af.flat(af.transpose(af.tile(self.xi_LGL, 1, N_LGL)))
        self.eta_j = af.tile(self.xi_LGL, N_LGL)

        self.dLp_xi_ij = af.moddims(
            af.reorder(
                af.tile(utils.polyval_1d(self.dl_dxi_coeffs, self.xi_i), 1, 1,
                        N_LGL), 1, 2, 0), N_LGL**2, 1, N_LGL**2)
        self.Lp_xi_ij = af.moddims(
            af.reorder(
                af.tile(utils.polyval_1d(self.lagrange_coeffs, self.xi_i), 1,
                        1, N_LGL), 1, 2, 0), N_LGL**2, 1, N_LGL**2)

        self.dLq_eta_ij = af.tile(
            af.reorder(utils.polyval_1d(self.dl_dxi_coeffs, self.eta_j), 1, 2,
                       0), 1, 1, N_LGL)

        self.Lq_eta_ij = af.tile(
            af.reorder(utils.polyval_1d(self.lagrange_coeffs, self.eta_j), 1,
                       2, 0), 1, 1, N_LGL)

        self.dLp_Lq = self.Lq_eta_ij * self.dLp_xi_ij
        self.dLq_Lp = self.Lp_xi_ij * self.dLq_eta_ij

        self.Li_Lj_coeffs = wave_equation_2d.Li_Lj_coeffs(N_LGL)

        self.delta_y = self.delta_x

        self.delta_t_2d = courant * self.delta_x * self.delta_y \
                        / (self.delta_x * c_x + self.delta_y * c_y)

        self.c_lax_2d_x = c_x
        self.c_lax_2d_y = c_y

        self.nodes, self.elements = msh_parser.read_order_2_msh(mesh_file)

        self.x_e_ij = af.np_to_af_array(
            np.zeros([N_LGL * N_LGL, len(self.elements)]))
        self.y_e_ij = af.np_to_af_array(
            np.zeros([N_LGL * N_LGL, len(self.elements)]))

        for element_tag, element in enumerate(self.elements):
            self.x_e_ij[:, element_tag] = isoparam.isoparam_x_2D(
                self.nodes[element, 0], self.xi_i, self.eta_j)
            self.y_e_ij[:, element_tag] = isoparam.isoparam_y_2D(
                self.nodes[element, 1], self.xi_i, self.eta_j)

        self.u_e_ij = af.sin(self.x_e_ij * 2 * np.pi + self.y_e_ij * 4 * np.pi)

        # Array of timesteps seperated by delta_t.
        self.time_2d = utils.linspace(
            0,
            int(total_time_2d / self.delta_t_2d) * self.delta_t_2d,
            int(total_time_2d / self.delta_t_2d))
        self.sqrt_det_g = wave_equation_2d.sqrt_det_g(self.nodes[self.elements[0]][:, 0], \
                        self.nodes[self.elements[0]][:, 1], np.array(self.xi_i), np.array(self.eta_j))

        self.elements_nodes = (af.reorder(
            af.transpose(af.np_to_af_array(self.nodes[self.elements[:]])), 0,
            2, 1))

        self.sqrt_g = af.reorder(wave_equation_2d.trial_sqrt_det_g(self.elements_nodes[:, 0, :],\
                      self.elements_nodes[:, 1, :], self.xi_i, self.eta_j), 0, 2, 1)

        return