Example #1
0
def get_cartesian_coords(q1, q2, 
                         q1_start_local_left=None, 
                         q2_start_local_bottom=None,
                         return_jacobian = False
                        ):

    q1_midpoint = 0.5*(af.max(q1) + af.min(q1))
    q2_midpoint = 0.5*(af.max(q2) + af.min(q2))

    x = q1
    y = q2
    jacobian = [[1. + 0.*q1,      0.*q1],
                [     0.*q1, 1. + 0.*q1]
               ]

    print("coords.py : ", q1_midpoint, q2_midpoint)

    if (q1_start_local_left != None and q2_start_local_bottom != None):
        

        if (return_jacobian):
            return(x, y, jacobian)
        else:
            return(x, y)

    else:
        print("Error in get_cartesian_coords(): q1_start_local_left or q2_start_local_bottom not provided")

    return(x, y)
Example #2
0
def get_cartesian_coords(q1, q2, 
                         q1_start_local_left=None, 
                         q2_start_local_bottom=None,
                         return_jacobian = False
                        ):

    q1_midpoint = 0.5*(af.max(q1) + af.min(q1))
    q2_midpoint = 0.5*(af.max(q2) + af.min(q2))

    # Default initializsation to rectangular grid
    x = q1
    y = q2
    jacobian = None

    if (q1_start_local_left != None and q2_start_local_bottom != None):

        if (return_jacobian):
            return (x, y, jacobian)
        else: 
            return(x, y)

    else:
        print("Error in get_cartesian_coords(): q1_start_local_left or q2_start_local_bottom not provided")

    return(x, y)
Example #3
0
def get_cartesian_coords(q1,
                         q2,
                         q1_start_local_left=None,
                         q2_start_local_bottom=None,
                         return_jacobian=False):

    q1_midpoint = 0.5 * (af.max(q1) + af.min(q1))
    q2_midpoint = 0.5 * (af.max(q2) + af.min(q2))

    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()

    # Default initializsation to rectangular grid
    x = q1
    y = q2
    #x = q1*(2+q2)
    #y = q2
    jacobian = None  #[[1. + 0.*q1,      0.*q1],
    #[     0.*q1, 1. + 0.*q1]
    #]

    if (q1_start_local_left != None and q2_start_local_bottom != None):

        if (return_jacobian):
            return (x, y, jacobian)
        else:
            return (x, y)

    else:
        print(
            "Error in get_cartesian_coords(): q1_start_local_left or q2_start_local_bottom not provided"
        )
Example #4
0
def get_cartesian_coords(q1, q2, 
                         q1_start_local_left=None, 
                         q2_start_local_bottom=None,
                         return_jacobian = False
                        ):

    q1_midpoint = 0.5*(af.max(q1) + af.min(q1))
    q2_midpoint = 0.5*(af.max(q2) + af.min(q2))

    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_g      = domain.N_ghost
    N_q1     = q1.dims()[2] - 2*N_g # Manually apply quadratic transformation for each zone along q1
    N_q2     = q2.dims()[3] - 2*N_g # Manually apply quadratic transformation for each zone along q1

    # Default initializsation to rectangular grid
    x = q1
    y = q2
    jacobian = [[1. + 0.*q1,      0.*q1],
                [     0.*q1, 1. + 0.*q1]
               ]


    if (q1_start_local_left != None and q2_start_local_bottom != None):


        if (return_jacobian):
            return (x, y, jacobian)
        else: 
            return(x, y)

    else:
        print("Error in get_cartesian_coords(): q1_start_local_left or q2_start_local_bottom not provided")
Example #5
0
def get_cartesian_coords(q1, q2):

    q1_midpoint = 0.5*(af.max(q1) + af.min(q1))
    q2_midpoint = 0.5*(af.max(q2) + af.min(q2))

    x = q1
    y = q2

    return(x, y)
Example #6
0
def tau_defect(q1, q2, p1, p2, p3):

    q1_midpoint = 0.5 * (af.max(q1) + af.min(q1))
    q2_midpoint = 0.5 * (af.max(q2) + af.min(q2))

    if (q2_midpoint < 0.75):
        tau_mr = np.inf
    else:
        tau_mr = 0.01

    return (tau_mr * q1**0 * p1**0)
Example #7
0
def get_cartesian_coords(q1, q2):

    q1_midpoint = 0.5 * (af.max(q1) + af.min(q1))
    q2_midpoint = 0.5 * (af.max(q2) + af.min(q2))

    x = q1
    y = q2

    #    if (q1_midpoint > 1.) and (q1_midpoint < 4.):
    #        y = 0.5*q2+0.125

    return (x, y)
Example #8
0
def get_cartesian_coords(q1, q2):

    q1_midpoint = 0.5 * (af.max(q1) + af.min(q1))
    q2_midpoint = 0.5 * (af.max(q2) + af.min(q2))

    x = q1
    y = q2

    #    if (q1_midpoint > 4.25):
    #        y = 3*q2-1

    return (x, y)
Example #9
0
def get_cartesian_coords(q1,
                         q2,
                         q1_start_local_left=None,
                         q2_start_local_bottom=None,
                         return_jacobian=False):

    q1_midpoint = 0.5 * (af.max(q1) + af.min(q1))
    q2_midpoint = 0.5 * (af.max(q2) + af.min(q2))

    x = q1
    y = q2
    jacobian = None

    if (q1_start_local_left != None and q2_start_local_bottom != None):

        if (q1_midpoint < -4.62):  # Domain 1 and 7
            y = 0.816 * q2

        elif ((q1_midpoint > -4.62) and (q1_midpoint < 0)):  # Domain 2 and 8
            y = (q2 * (1 + 0.04 * (q1)))

        elif ((q1_midpoint > 29.46) and (q1_midpoint < 32.98)
              and (q2_midpoint < 12)):  # Domain 5
            y = ((q2 - 12) * (1 - 0.1193 * (q1 - 29.46))) + 12

        elif ((q1_midpoint > 32.98) and (q2_midpoint < 12)):  # Domain 6
            y = 0.58 * (q2 - 12) + 12

        elif ((q1_midpoint > 26.3) and (q1_midpoint < 29.46)
              and (q2_midpoint > 12)):  # Domain 10
            y = ((q2 - 12) * (1 - 2 * 0.0451 * (q1 - 26.3))) + 12

        elif ((q1_midpoint > 29.46) and (q1_midpoint < 32.98)
              and (q2_midpoint > 12)):  # Domain 11
            y = ((q2 - 12) * (1 - 2 * 0.0451 * (q1 - 26.3))) + 12

        elif ((q1_midpoint > 32.98) and (q2_midpoint > 12)):  # Domain 12
            y = 0.40 * (q2 - 12) + 12

        # Numerically calculate Jacobian
        jacobian = None

        if (return_jacobian):
            return (x, y, jacobian)
        else:
            return (x, y)

    else:
        print(
            "Error in get_cartesian_coords(): q1_start_local_left or q2_start_local_bottom not provided"
        )
Example #10
0
def get_cartesian_coords(q1,
                         q2,
                         q1_start_local_left=None,
                         q2_start_local_bottom=None,
                         return_jacobian=False):

    q1_midpoint = 0.5 * (af.max(q1) + af.min(q1))
    q2_midpoint = 0.5 * (af.max(q2) + af.min(q2))

    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()

    # Default initializsation to rectangular grid
    x = q1
    y = q2
    #x = q1*(2+q2)
    #y = q2
    jacobian = None  #[[1. + 0.*q1,      0.*q1],
    #[     0.*q1, 1. + 0.*q1]
    #]

    if (q1_start_local_left != None and q2_start_local_bottom != None):

        #        X_Y_top_right    = [1,   1]
        #        X_Y_top_left     = [-1,  1]
        #        X_Y_bottom_left  = [-1, -1]
        #        X_Y_bottom_right = [1,  -1]
        #
        #        x_y_top_right    = [1,   1]
        #        x_y_top_left     = [-1,  1]
        #        x_y_bottom_left  = [-1, -0.5]
        #        x_y_bottom_right = [1,  -1]
        #
        #        x, y =  affine(q1, q2,
        #                       x_y_bottom_left, x_y_bottom_right,
        #                       x_y_top_right,   x_y_top_left,
        #                       X_Y_bottom_left, X_Y_bottom_right,
        #                       X_Y_top_right,   X_Y_top_left,
        #                      )
        #        # Numerically calculate Jacobian
        #        jacobian = None

        if (return_jacobian):
            return (x, y, jacobian)
        else:
            return (x, y)

    else:
        print(
            "Error in get_cartesian_coords(): q1_start_local_left or q2_start_local_bottom not provided"
        )
Example #11
0
def _bps_idx_af(E, angles, symbols, N):
    global NMAX
    prec_dtype = E.dtype
    Ntestangles = angles.shape[1]
    Nmax = NMAX // Ntestangles // symbols.shape[0] // 16
    L = E.shape[0]
    EE = E[:, np.newaxis] * np.exp(1.j * angles)
    syms = af.np_to_af_array(symbols.astype(prec_dtype).reshape(1, 1, -1))
    idxnd = np.zeros(L, dtype=np.int32)
    if L <= Nmax + N:
        Eaf = af.np_to_af_array(EE.astype(prec_dtype))
        tmp = af.min(af.abs(af.broadcast(lambda x, y: x - y, Eaf[0:L, :],
                                         syms))**2,
                     dim=2)
        cs = _movavg_af(tmp, 2 * N, axis=0)
        val, idx = af.imin(cs, dim=1)
        idxnd[N:-N] = np.array(idx)
    else:
        K = L // Nmax
        R = L % Nmax
        if R < N:
            R = R + Nmax
            K -= 1
        Eaf = af.np_to_af_array(EE[0:Nmax + N].astype(prec_dtype))
        tmp = af.min(af.abs(af.broadcast(lambda x, y: x - y, Eaf, syms))**2,
                     dim=2)
        tt = np.array(tmp)
        cs = _movavg_af(tmp, 2 * N, axis=0)
        val, idx = af.imin(cs, dim=1)
        idxnd[N:Nmax] = np.array(idx)
        for i in range(1, K):
            Eaf = af.np_to_af_array(EE[i * Nmax - N:(i + 1) * Nmax + N].astype(
                np.complex128))
            tmp = af.min(af.abs(af.broadcast(lambda x, y: x - y, Eaf,
                                             syms))**2,
                         dim=2)
            cs = _movavg_af(tmp, 2 * N, axis=0)
            val, idx = af.imin(cs, dim=1)
            idxnd[i * Nmax:(i + 1) * Nmax] = np.array(idx)
        Eaf = af.np_to_af_array(EE[K * Nmax - N:K * Nmax + R].astype(
            np.complex128))
        tmp = af.min(af.abs(af.broadcast(lambda x, y: x - y, Eaf, syms))**2,
                     dim=2)
        cs = _movavg_af(tmp, 2 * N, axis=0)
        val, idx = af.imin(cs, dim=1)
        idxnd[K * Nmax:-N] = np.array(idx)
    return idxnd
Example #12
0
def get_cartesian_coords(q1, q2):

    q1_midpoint = 0.5 * (af.max(q1) + af.min(q1))
    q2_midpoint = 0.5 * (af.max(q2) + af.min(q2))

    y = q2

    if (q2_midpoint < 0):
        x = q1
    else:
        x = q1 * (1 + q2)

    #x = q1
    #indices = q2>0
    #x[indices] = (q1*(1 + q2))[indices]

    return (x, y)
Example #13
0
    def min(self, axis: tp.Optional[int] = None):
        """
        Returns the minimum along given axis.
        """

        new_array = af.min(self._af_array, dim=axis)
        if isinstance(new_array, af.Array):
            return ndarray(new_array)
        else:
            return new_array
Example #14
0
def lowpass_filter(f):
    f_hat = af.fft(f)
    dp1 = (domain.p1_end[0] - domain.p1_start[0]) / domain.N_p1
    k_v = af.tile(af.to_array(np.fft.fftfreq(domain.N_p1, dp1)), 1, 1,
                  f.shape[2], f.shape[3])

    # Applying the filter:
    f_hat_filtered = 0.5 * (f_hat * (af.tanh(
        (k_v + 0.9 * af.max(k_v)) / 0.5) - af.tanh(
            (k_v + 0.9 * af.min(k_v)) / 0.5)))

    f_hat = af.select(af.abs(k_v) < 0.8 * af.max(k_v), f_hat, f_hat_filtered)
    f = af.real(af.ifft(f_hat))
    return (f)
Example #15
0
File: main.py Project: shyams2/Bolt
def time_evolution():

    for time_index, t0 in enumerate(time_array):
        print('For Time =', t0)
        print('MIN(f) =', af.min(nls.f[3:-3, 3:-3]))
        print('MAX(f) =', af.max(nls.f[3:-3, 3:-3]))
        print('SUM(f) =', af.sum(nls.f[3:-3, 3:-3]))
        print()

        nls.strang_timestep(dt)
        n_nls = nls.compute_moments('density')

        h5f = h5py.File('dump/%04d' % (time_index + 1) + '.h5', 'w')
        h5f.create_dataset('n', data=n_nls)
        h5f.close()
Example #16
0
 def min(self, s, axis):
     return arrayfire.min(s, axis)
Example #17
0
def get_cartesian_coords(q1, q2, 
                         q1_start_local_left=None, 
                         q2_start_local_bottom=None,
                         return_jacobian = False
                        ):


    q1_midpoint = 0.5*(af.max(q1) + af.min(q1))
    q2_midpoint = 0.5*(af.max(q2) + af.min(q2))

    N_g = domain.N_ghost

    # Default initialisation to rectangular grid
    x = q1
    y = q2
    jacobian = [[1. + 0.*q1,      0.*q1],
                [     0.*q1, 1. + 0.*q1]
               ]
    [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]] = jacobian

    # Radius and center of circular region
    radius          = 0.5
    center          = [0, 0]

    if (q1_start_local_left != None and q2_start_local_bottom != None):

        N_q1     = q1.dims()[2] - 2*N_g # Manually apply quadratic transformation for each zone along q1
        N_q2     = q2.dims()[3] - 2*N_g # Manually apply quadratic transformation for each zone along q1
        N_i      = N_q1
        N_j      = N_q2

        # Bottom-left most point of the transformation
        x_0      = -radius/np.sqrt(2)
        y_0      = np.sqrt(radius**2 - x_0**2)

        # Initialize to zero
        x = 0*q1
        y = 0*q2


        # Loop over each zone in x
        #for i in range(N_g, N_q1 + N_g):
        for i in range(0, N_q1 + 2*N_g):

            #for j in range(N_g, N_q2 + N_g):
            for j in range(0, N_q2 + 2*N_g):
                index_i = i - N_g # Index of the vertical slice, left-most being 0
                index_j = j - N_g # Index of the horizontal slice, bottom-most being 0
    
                # q1, q2 grid slices to be passed into quadratic for transformation
                q1_slice = q1[0, 0, i, j]
                q2_slice = q2[0, 0, i, j]

                x_step = 0.66666666/N_i
                y_step = 1./N_j
    
                # Compute the x, y points using which the transformation will be defined
                # x, y nodes remain the same for each point on a vertical slice
 
#                y_n           = y_0 + y_step*index_j   # Bottom
#                y_n_plus_half = y_0 + y_step*(index_j+0.5) # y-center
#                y_n_plus_1    = y_0 + y_step*(index_j+1) # Top

                x_n           = x_0 + x_step*index_i       #+ x_step*(np.abs(index_j - N_j/2.))# Left
                x_n_plus_half = x_0 + x_step*(index_i+0.5) #+ x_step*(np.abs(index_j - N_j/2.))# x-center
                x_n_plus_1    = x_0 + x_step*(index_i+1)   #+ x_step*(np.abs(index_j - N_j/2.))# Right

                x_y_bottom_left   = [x_n,           np.sqrt(np.abs(radius**2 - x_n**2))           + index_j*y_step]
                x_y_bottom_center = [x_n_plus_half, np.sqrt(np.abs(radius**2 - x_n_plus_half**2)) + index_j*y_step]
                x_y_bottom_right  = [x_n_plus_1,    np.sqrt(np.abs(radius**2 - x_n_plus_1**2))    + index_j*y_step]
    
                x_y_left_center   = [x_n,           np.sqrt(np.abs(radius**2 - x_n**2))        + (index_j+0.5)*y_step]
                x_y_right_center  = [x_n_plus_1,    np.sqrt(np.abs(radius**2 - x_n_plus_1**2)) + (index_j+0.5)*y_step]
    
                x_y_top_left      = [x_n,           np.sqrt(np.abs(radius**2 - x_n**2))           + (index_j+1)*y_step]
                x_y_top_center    = [x_n_plus_half, np.sqrt(np.abs(radius**2 - x_n_plus_half**2)) + (index_j+1)*y_step]
                x_y_top_right     = [x_n_plus_1,    np.sqrt(np.abs(radius**2 - x_n_plus_1**2))    + (index_j+1)*y_step]

                # Get the transformation (x_i, y_i) for each point (q1_i, q2_i)
                q1_i = q1[0, 0, i, j]
                q2_i = q2[0, 0, i, j]

                x_i, y_i, jacobian_i = quadratic_test(q1_i, q2_i, q1_slice, q2_slice,
                                   x_y_bottom_left,   x_y_bottom_right,
                                   x_y_top_right,     x_y_top_left,
                                   x_y_bottom_center, x_y_right_center,
                                   x_y_top_center,    x_y_left_center,
                                   q1_start_local_left + index_i*domain.dq1,
                                   q2_start_local_bottom + index_j*domain.dq2
                                  )

                # Reconstruct the x,y grid from the loop
                x[0, 0, i, j] = x_i
                y[0, 0, i, j] = y_i

                # TODO : Reconstruct jacobian
                [[dx_dq1_i, dx_dq2_i], [dy_dq1_i, dy_dq2_i]] = jacobian_i
                dx_dq1[0, 0, i, j] = dx_dq1_i.scalar()
                dx_dq2[0, 0, i, j] = dx_dq2_i.scalar()
                dy_dq1[0, 0, i, j] = dy_dq1_i.scalar()
                dy_dq2[0, 0, i, j] = dy_dq2_i.scalar()

            pl.plot(af.moddims(dx_dq1[0, 0, i, :], q1.dims()[2]).to_ndarray(), '-o', color = 'C0', alpha = 0.1, label = "dx_dq1")
            pl.plot(af.moddims(dy_dq1[0, 0, i, :], q1.dims()[2]).to_ndarray(), '-o', color = 'k',  alpha = 0.1, label = "dy_dq1")
            pl.plot(af.moddims(dx_dq2[0, 0, i, :], q1.dims()[2]).to_ndarray(), '-o', color = 'C2', alpha = 0.1, label = "dx_dq2")
            pl.plot(af.moddims(dy_dq2[0, 0, i, :], q1.dims()[2]).to_ndarray(), '-o', color = 'C3', alpha = 0.1, label = "dy_dq2")

        jacobian = [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]]

#        pl.plot(af.moddims(dx_dq1[0, 0, :, N_g], q1.dims()[2]).to_ndarray(), '-o', color = 'C0', alpha = 0.5, label = "dx_dq1")
#        pl.plot(af.moddims(dy_dq1[0, 0, :, N_g], q1.dims()[2]).to_ndarray(), '-o', color = 'k', alpha = 0.5, label = "dy_dq1")
#        pl.plot(af.moddims(dx_dq2[0, 0, :, N_g], q1.dims()[2]).to_ndarray(), '-o', color = 'C2', alpha = 0.5, label = "dx_dq2")
#        pl.plot(af.moddims(dy_dq2[0, 0, :, N_g], q1.dims()[2]).to_ndarray(), '-o', color = 'C3', alpha = 0.5, label = "dy_dq2")

        #pl.legend(loc='best')

        pl.savefig("/home/quazartech/bolt/example_problems/electronic_boltzmann/test_quadratic_2/iv.png")
        pl.clf()

        if (return_jacobian):
            return (x, y, jacobian)
        else: 
            return(x, y)

    else:
        print("Error in get_cartesian_coords(): q1_start_local_left or q2_start_local_bottom not provided")
Example #18
0
def get_cartesian_coords(q1,
                         q2,
                         q1_start_local_left=None,
                         q2_start_local_bottom=None,
                         return_jacobian=False):

    q1_midpoint = 0.5 * (af.max(q1) + af.min(q1))
    q2_midpoint = 0.5 * (af.max(q2) + af.min(q2))

    # Default initializsation to rectangular grid
    x = q1
    y = q2

    jacobian = None  # Numerically compute the Jacobian

    if (q1_start_local_left != None and q2_start_local_bottom != None):

        if ((q2_midpoint < 0.5) and (q1_midpoint > -1.)
                and (q1_midpoint < 0.)):
            x0 = -1.
            y0 = -2.0  # Bottom-left
            x1 = 0
            y1 = -2.0  # Bottom-right
            x2 = 0
            y2 = -0.5  # Top-right
            x3 = -1.
            y3 = 0.5  # Top-left
            x, y = \
              affine(q1, q2,
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [-1., -2.0], [0, -2.0],
               [0, 0.5], [-1., 0.5]
                    )

        elif ((q2_midpoint < 0.5) and (q1_midpoint > 0)
              and (q1_midpoint < 1.)):

            x0 = 0.
            y0 = -2.0  # Bottom-left
            x1 = 1.0
            y1 = -2.0  # Bottom-right
            x2 = 1.0
            y2 = 0.5  # Top-right
            x3 = 0
            y3 = -0.5  # Top-left
            x, y = \
              affine(q1, q2,
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [0., -2.0], [1., -2.],
               [1., 0.5], [0., 0.5]
                    )

        if (return_jacobian):
            return (x, y, jacobian)
        else:
            return (x, y)

    else:
        print(
            "Error in get_cartesian_coords(): q1_start_local_left or q2_start_local_bottom not provided"
        )
Example #19
0
#!/usr/bin/python

#######################################################
# 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

# Display backend information
af.info()

# Generate a uniform random array with a size of 5 elements
a = af.randu(5, 1)

# Print a and its minimum value
print(a)

# Print min and max values of a
print("Minimum, Maximum: ", af.min(a), af.max(a))
Example #20
0
# Defining the physical system to be solved:
system = physical_system(domain, boundary_conditions, params, initialize,
                         advection_terms, collision_operator.BGK, moments)

# Declaring a linear system object which will evolve the defined physical system:
nls = nonlinear_solver(system)
N_g = nls.N_ghost

# Time parameters:
dt = 0.001 * 32 / nls.N_q1
t_final = params.t_final

time_array = np.arange(dt, t_final + dt, dt)

print('Printing the minimum and maximum of the distribution functions :')
print('f_min:', af.min(nls.f))
print('f_max:', af.max(nls.f))

# Dumping the distribution function at t = 0:
nls.dump_distribution_function('dump_f/t=0.000')
# nls.dump_moments('dump_moments/t=0.000')

for time_index, t0 in enumerate(time_array):

    nls.strang_timestep(dt)
    PETSc.Sys.Print('Computing For Time =', t0)

    delta_dt =   (1 - math.modf(t0/params.dt_dump_moments)[0]) \
               * params.dt_dump_moments

    # nls.dump_moments('dump_moments/t=' + '%.3f'%t0)
Example #21
0
    A[1,:] = B[2,:]
    af.display(A)

    print("\n---- Bitwise operations\n")
    af.display(A & B)
    af.display(A | B)
    af.display(A ^ B)

    print("\n---- Transpose\n")
    af.display(A)
    af.display(af.transpose(A))

    print("\n---- Flip Vertically / Horizontally\n")
    af.display(A)
    af.display(af.flip(A, 0))
    af.display(af.flip(A, 1))

    print("\n---- Sum, Min, Max along row / columns\n")
    af.display(A)
    af.display(af.sum(A, 0))
    af.display(af.min(A, 0))
    af.display(af.max(A, 0))
    af.display(af.sum(A, 1))
    af.display(af.min(A, 1))
    af.display(af.max(A, 1))

    print("\n---- Get minimum with index\n")
    (min_val, min_idx) = af.imin(A, 0)
    af.display(min_val)
    af.display(min_idx)
#!/usr/bin/python
import arrayfire as af

a = af.randu(3, 3)

print(af.sum(a), af.product(a), af.min(a), af.max(a), af.count(a), af.any_true(a), af.all_true(a))

af.print_array(af.sum(a, 0))
af.print_array(af.sum(a, 1))

af.print_array(af.product(a, 0))
af.print_array(af.product(a, 1))

af.print_array(af.min(a, 0))
af.print_array(af.min(a, 1))

af.print_array(af.max(a, 0))
af.print_array(af.max(a, 1))

af.print_array(af.count(a, 0))
af.print_array(af.count(a, 1))

af.print_array(af.any_true(a, 0))
af.print_array(af.any_true(a, 1))

af.print_array(af.all_true(a, 0))
af.print_array(af.all_true(a, 1))

af.print_array(af.accum(a, 0))
af.print_array(af.accum(a, 1))
def Umeda_b1_deposition( charge_electron, positions_x, positions_y, velocity_x, velocity_y,\
                            x_grid, y_grid, ghost_cells, length_domain_x, length_domain_y, dt  ):
    '''
    A modified Umeda's scheme was implemented to handle a pure one dimensional case.

    function Umeda_b1_deposition( charge, x, velocity_x,\
                                  x_grid, ghost_cells, length_domain_x, dt\
                                )
    -----------------------------------------------------------------------
    Input variables: charge, x, velocity_required_x, x_grid, ghost_cells, length_domain_x, dt

        charge: This is an array containing the charges deposited at the density grid nodes.

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

        velocity_x: An one dimensional array of size equal to number of particles taken in the PIC code.
        It contains the velocities of particles in y direction.
        
        velocity_y: An one dimensional array of size equal to number of particles taken in the PIC code.
        It contains the velocities of particles in x direction.

        x_grid: This is an array denoting the position grid in x direction chosen in the PIC simulation
        
        y_grid: This is an array denoting the position grid in y direction chosen in the PIC simulation

        ghost_cells: This is the number of ghost cells used in the simulation domain.

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

        dt: this is the dt/time step chosen in the simulation
    -----------------------------------------------------------------------
    returns: Jx_x_indices, Jx_y_indices, Jx_values_at_these_indices,\
           Jy_x_indices, Jy_y_indices, Jy_values_at_these_indices

        Jx_x_indices: This returns the x indices (columns) of the array where the respective currents stored in
        Jx_values_at_these_indices have to be deposited
      
        Jx_y_indices: This returns the y indices (rows) of the array where the respective currents stored in
        Jx_values_at_these_indices have to be deposited      

        Jx_values_at_these_indices: This is an array containing the currents to be deposited.
        
        Jy_x_indices, Jy_y_indices and Jy_values_at_these_indices are similar to Jx_x_indices, 
        Jx_y_indices and Jx_values_at_these_indices for Jy

    For further details on the scheme refer to Umeda's paper provided in the sagemath folder as the
    naming conventions used in the function use the papers naming convention.(x_1, x_2, x_r, F_x, )

    '''

    nx = (x_grid.elements() - 1 - 2 * ghost_cells)  # number of zones
    ny = (y_grid.elements() - 1 - 2 * ghost_cells)  # number of zones

    dx = length_domain_x / nx
    dy = length_domain_y / ny

    # Start location x_1, y_1 at t = n * dt
    # Start location x_2, y_2 at t = (n+1) * dt

    x_1 = (positions_x).as_type(af.Dtype.f64)
    x_2 = (positions_x + (velocity_x * dt)).as_type(af.Dtype.f64)

    y_1 = (positions_y).as_type(af.Dtype.f64)
    y_2 = (positions_y + (velocity_y * dt)).as_type(af.Dtype.f64)

    # Calculation i_1 and i_2, indices of left corners of cells containing the particles
    # at x_1 and x_2 respectively and j_1 and j_2: indices of bottoms of cells containing the particles
    # at y_1 and y_2 respectively

    i_1 = af.arith.floor(((af.abs(x_1 - af.sum(x_grid[0]))) / dx) -
                         ghost_cells)
    j_1 = af.arith.floor(((af.abs(y_1 - af.sum(y_grid[0]))) / dy) -
                         ghost_cells)

    i_2 = af.arith.floor(((af.abs(x_2 - af.sum(x_grid[0]))) / dx) -
                         ghost_cells)
    j_2 = af.arith.floor(((af.abs(y_2 - af.sum(y_grid[0]))) / dy) -
                         ghost_cells)

    i_dx = dx * af.join(1, i_1, i_2)
    j_dy = dy * af.join(1, j_1, j_2)

    i_dx_x_avg = af.join(1, af.max(i_dx, 1), ((x_1 + x_2) / 2))
    j_dy_y_avg = af.join(1, af.max(j_dy, 1), ((y_1 + y_2) / 2))

    x_r_term_1 = dx + af.min(i_dx, 1)
    x_r_term_2 = af.max(i_dx_x_avg, 1)

    y_r_term_1 = dy + af.min(j_dy, 1)
    y_r_term_2 = af.max(j_dy_y_avg, 1)

    x_r_combined_term = af.join(1, x_r_term_1, x_r_term_2)
    y_r_combined_term = af.join(1, y_r_term_1, y_r_term_2)

    # Computing the relay point (x_r, y_r)

    x_r = af.min(x_r_combined_term, 1)
    y_r = af.min(y_r_combined_term, 1)

    # Calculating the fluxes and the weights

    F_x_1 = charge_electron * (x_r - x_1) / dt
    F_x_2 = charge_electron * (x_2 - x_r) / dt

    F_y_1 = charge_electron * (y_r - y_1) / dt
    F_y_2 = charge_electron * (y_2 - y_r) / dt

    W_x_1 = (x_1 + x_r) / (2 * dx) - i_1
    W_x_2 = (x_2 + x_r) / (2 * dx) - i_2

    W_y_1 = (y_1 + y_r) / (2 * dy) - j_1
    W_y_2 = (y_2 + y_r) / (2 * dy) - j_2

    # computing the charge densities at the grid nodes using the
    # fluxes and the weights

    J_x_1_1 = (1 / (dx * dy)) * (F_x_1 * (1 - W_y_1))
    J_x_1_2 = (1 / (dx * dy)) * (F_x_1 * (W_y_1))

    J_x_2_1 = (1 / (dx * dy)) * (F_x_2 * (1 - W_y_2))
    J_x_2_2 = (1 / (dx * dy)) * (F_x_2 * (W_y_2))

    J_y_1_1 = (1 / (dx * dy)) * (F_y_1 * (1 - W_x_1))
    J_y_1_2 = (1 / (dx * dy)) * (F_y_1 * (W_x_1))

    J_y_2_1 = (1 / (dx * dy)) * (F_y_2 * (1 - W_x_2))
    J_y_2_2 = (1 / (dx * dy)) * (F_y_2 * (W_x_2))

    # concatenating the x, y indices for Jx

    Jx_x_indices = af.join(0,\
                           i_1 + ghost_cells,\
                           i_1 + ghost_cells,\
                           i_2 + ghost_cells,\
                           i_2 + ghost_cells\
                          )

    Jx_y_indices = af.join(0,\
                           j_1 + ghost_cells,\
                           (j_1 + 1 + ghost_cells),\
                            j_2 + ghost_cells,\
                           (j_2 + 1 + ghost_cells)\
                          )

    # concatenating the currents at x, y indices for Jx

    Jx_values_at_these_indices = af.join(0,\
                                         J_x_1_1,\
                                         J_x_1_2,\
                                         J_x_2_1,\
                                         J_x_2_2\
                                        )

    # concatenating the x, y indices for Jy

    Jy_x_indices = af.join(0,\
                           i_1 + ghost_cells,\
                           (i_1 + 1 + ghost_cells),\
                            i_2 + ghost_cells,\
                           (i_2 + 1 + ghost_cells)\
                          )

    Jy_y_indices = af.join(0,\
                           j_1 + ghost_cells,\
                           j_1 + ghost_cells,\
                           j_2 + ghost_cells,\
                           j_2 + ghost_cells\
                          )

    # concatenating the currents at x, y indices for Jx

    Jy_values_at_these_indices = af.join(0,\
                                         J_y_1_1,\
                                         J_y_1_2,\
                                         J_y_2_1,\
                                         J_y_2_2\
                                        )

    af.eval(Jx_x_indices, Jx_y_indices, Jy_x_indices, Jy_y_indices)

    af.eval(Jx_values_at_these_indices, Jy_values_at_these_indices)

    return Jx_x_indices, Jx_y_indices, Jx_values_at_these_indices,\
           Jy_x_indices, Jy_y_indices, Jy_values_at_these_indices
Example #24
0
 def min(self, s, axis):
     return arrayfire.min(s, axis)
Example #25
0
def simple_algorithm(verbose = False):
    display_func = _util.display_func(verbose)
    print_func   = _util.print_func(verbose)

    a = af.randu(3, 3)

    print_func(af.sum(a), af.product(a), af.min(a), af.max(a),
               af.count(a), af.any_true(a), af.all_true(a))

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

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

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

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

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

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

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

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

    display_func(af.sort(a, is_ascending=True))
    display_func(af.sort(a, is_ascending=False))

    b = (a > 0.1) * a
    c = (a > 0.4) * a
    d = b / c
    print_func(af.sum(d));
    print_func(af.sum(d, nan_val=0.0));
    display_func(af.sum(d, dim=0, nan_val=0.0));

    val,idx = af.sort_index(a, is_ascending=True)
    display_func(val)
    display_func(idx)
    val,idx = af.sort_index(a, is_ascending=False)
    display_func(val)
    display_func(idx)

    b = af.randu(3,3)
    keys,vals = af.sort_by_key(a, b, is_ascending=True)
    display_func(keys)
    display_func(vals)
    keys,vals = af.sort_by_key(a, b, is_ascending=False)
    display_func(keys)
    display_func(vals)

    c = af.randu(5,1)
    d = af.randu(5,1)
    cc = af.set_unique(c, is_sorted=False)
    dd = af.set_unique(af.sort(d), is_sorted=True)
    display_func(cc)
    display_func(dd)

    display_func(af.set_union(cc, dd, is_unique=True))
    display_func(af.set_union(cc, dd, is_unique=False))

    display_func(af.set_intersect(cc, cc, is_unique=True))
    display_func(af.set_intersect(cc, cc, is_unique=False))
Example #26
0
dt_fdtd = params.N_cfl * dq1 \
                       / params.c # lightspeed

dt = min(dt_fvm, dt_fdtd)
params.dt = dt

# Defining the physical system to be solved:
system = physical_system(domain, boundary_conditions, params, initialize,
                         advection_terms, collision_operator.BGK, moments)

# Declaring a linear system object which will evolve the defined physical system:
nls = nonlinear_solver(system)
N_g = nls.N_ghost

print('Minimum Value of f_e:', af.min(nls.f[:, 0]))
print('Minimum Value of f_i:', af.min(nls.f[:, 1]))

print('Error in density_e:',
      af.mean(af.abs(nls.compute_moments('density')[:, 0] - 1)))
print('Error in density_i:',
      af.mean(af.abs(nls.compute_moments('density')[:, 1] - 1)))

v2_bulk = nls.compute_moments('mom_v2_bulk') / nls.compute_moments('density')
v3_bulk = nls.compute_moments('mom_v3_bulk') / nls.compute_moments('density')

v2_bulk_i =   params.amplitude * -4.801714581503802e-15 * af.cos(params.k_q1 * nls.q1_center) \
            - params.amplitude * -0.3692429960259134 * af.sin(params.k_q1 * nls.q1_center)

v2_bulk_e =   params.amplitude * -4.85722573273506e-15 * af.cos(params.k_q1 * nls.q1_center) \
            - params.amplitude * - 0.333061857862197* af.sin(params.k_q1 * nls.q1_center)
Example #27
0
dt      = 0.001
t_final = 1.0

time_array = np.arange(dt, t_final + dt, dt)

n_nls = nls.compute_moments('density')

h5f = h5py.File('dump/0000.h5', 'w')
h5f.create_dataset('q1', data = nls.q1_center[:, :, N_g:-N_g, N_g:-N_g])
h5f.create_dataset('q2', data = nls.q2_center[:, :, N_g:-N_g, N_g:-N_g])
h5f.create_dataset('n', data = n_nls[:, :, N_g:-N_g, N_g:-N_g])
h5f.close()

init_sum = af.sum(nls.f[:, :, N_g:-N_g, N_g:-N_g])

for time_index, t0 in enumerate(time_array):

    # Used to debug:    
    print('For Time =', t0)
    print('MIN(f) =', af.min(nls.f[:, :, N_g:-N_g, N_g:-N_g]))
    print('MAX(f) =', af.max(nls.f[:, :, N_g:-N_g, N_g:-N_g]))
    print('d(SUM(f)) =', af.sum(nls.f[:, :, N_g:-N_g, N_g:-N_g]) - init_sum)
    print()

    nls.strang_timestep(dt)
    n_nls = nls.compute_moments('density')
    
    h5f = h5py.File('dump/%04d'%(time_index+1) + '.h5', 'w')
    h5f.create_dataset('n', data = n_nls[:, :, N_g:-N_g, N_g:-N_g])
    h5f.close()
Example #28
0
# Defining the physical system to be solved:
system = physical_system(domain, boundary_conditions, params, initialize,
                         advection_terms, collision_operator.BGK, moments)

# Declaring a linear system object which will evolve the defined physical system:
nls = nonlinear_solver(system)
N_g = nls.N_ghost

# Time parameters:
dt = params.N_cfl * min(nls.dq1, nls.dq2) \
                  / max(domain.p1_end + domain.p2_end + domain.p3_end)

print(
    'Printing the minimum of the distribution functions for electrons and ions:'
)
print('f_min_electron:', af.min(nls.f[:, 0, :, :]))
print('f_min_ion:', af.min(nls.f[:, 1, :, :]))

if (params.t_restart == 0):
    time_elapsed = 0
    nls.dump_distribution_function('dump_f/t=0.000')
    nls.dump_moments('dump_moments/t=0.000')
    nls.dump_EM_fields('dump_fields/t=0.000')

else:
    time_elapsed = params.t_restart
    nls.load_distribution_function('dump_f/t=' + '%.3f' % time_elapsed)
    nls.load_EM_fields('dump_fields/t=' + '%.3f' % time_elapsed)

# Checking that the file writing intervals are greater than dt:
assert (params.dt_dump_f > dt)
Example #29
0
def get_cartesian_coords(q1, q2, 
                         q1_start_local_left=None, 
                         q2_start_local_bottom=None,
                         return_jacobian = False
                        ):


    q1_midpoint = 0.5*(af.max(q1) + af.min(q1))
    q2_midpoint = 0.5*(af.max(q2) + af.min(q2))

    # Default initializsation to rectangular grid
    x = q1
    y = q2
    
    jacobian = None # Numerically compute the Jacobian
    
    if (q1_start_local_left != None and q2_start_local_bottom != None):

        # Bottom center patch
        if ((q2_midpoint < 0.3) and (q1_midpoint > 1.) and (q1_midpoint < 2.)):
            x0 = 1.;  y0 = 0  # Bottom-left
            x1 = 2;   y1 = 0  # Bottom-right
            x2 = 2;   y2 = 0.45  # Top-right
            x3 = 1.;  y3 = 0.1  # Top-left
            x, y = \
              affine(q1, q2, 
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [1., 0], [2, 0],
               [2, 0.3], [1., 0.3]
                    )

        # Bottom left patch
        elif ((q2_midpoint < 0.3) and (q1_midpoint > 0.) and (q1_midpoint < 1.)):
            x0 = 0.;  y0 = 0  # Bottom-left
            x1 = 1;   y1 = 0  # Bottom-right
            x2 = 1;   y2 = 0.1  # Top-right
            x3 = 0.;  y3 = 0.1  # Top-left
            x, y = \
              affine(q1, q2, 
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [0., 0], [1, 0],
               [1, 0.3], [0., 0.3]
                    )
        
        # Bottom right patch
        elif ((q2_midpoint < 0.3) and (q1_midpoint > 2.) and (q1_midpoint < 3.)):
            x0 = 2.;  y0 = 0  # Bottom-left
            x1 = 3;   y1 = 0  # Bottom-right
            x2 = 3;   y2 = 0.1  # Top-right
            x3 = 2.;  y3 = 0.45  # Top-left
            x, y = \
              affine(q1, q2, 
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [2., 0], [3, 0],
               [3, 0.3], [2., 0.3]
                    )
        
        # Top right patch
        elif ((q2_midpoint > 0.7) and (q1_midpoint > 2.) and (q1_midpoint < 3.)):
            x0 = 2.;  y0 = 0.55  # Bottom-left
            x1 = 3;   y1 = 0.9  # Bottom-right
            x2 = 3;   y2 = 1.  # Top-right
            x3 = 2.;  y3 = 1.  # Top-left
            x, y = \
              affine(q1, q2, 
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [2., 0.7], [3, 0.7],
               [3, 1.], [2., 1.]
                    )
        # Top left patch
        elif ((q2_midpoint > 0.7) and (q1_midpoint > 0.) and (q1_midpoint < 1.)):
            x0 = 0.;  y0 = 0.9  # Bottom-left
            x1 = 1;   y1 = 0.9  # Bottom-right
            x2 = 1;   y2 = 1.  # Top-right
            x3 = 0.;  y3 = 1.  # Top-left
            x, y = \
              affine(q1, q2, 
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [0., 0.7], [1, 0.7],
               [1, 1.], [0., 1.]
                    )
        
        # Top center patch
        elif ((q2_midpoint > 0.7) and (q1_midpoint > 1.) and (q1_midpoint < 2.)):
            x0 = 1.;  y0 = 0.9  # Bottom-left
            x1 = 2;   y1 = 0.55  # Bottom-right
            x2 = 2;   y2 = 1.  # Top-right
            x3 = 1.;  y3 = 1.  # Top-left
            x, y = \
              affine(q1, q2, 
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [1., 0.7], [2, 0.7],
               [2, 1.], [1., 1.]
                    )
        
        # Center center patch
        elif ((q2_midpoint > 0.3) and (q2_midpoint < 0.7) and (q1_midpoint > 1.) and (q1_midpoint < 2.)):
            x0 = 1.;  y0 = 0.1  # Bottom-left
            x1 = 2;   y1 = 0.45  # Bottom-right
            x2 = 2;   y2 = 0.55  # Top-right
            x3 = 1.;  y3 = 0.9  # Top-left
            x, y = \
              affine(q1, q2, 
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [1., 0.3], [2, 0.3],
               [2, 0.7], [1., 0.7]
                    )
        
        # Left center patch
        elif ((q2_midpoint > 0.3) and (q2_midpoint < 0.7) and (q1_midpoint > 0.) and (q1_midpoint < 1.)):
            x0 = 0.;  y0 = 0.1  # Bottom-left
            x1 = 1;   y1 = 0.1  # Bottom-right
            x2 = 1;   y2 = 0.9  # Top-right
            x3 = 0.;  y3 = 0.9  # Top-left
            x, y = \
              affine(q1, q2, 
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [0., 0.3], [1, 0.3],
               [1, 0.7], [0., 0.7]
                    )
        
        # Right center patch
        elif ((q2_midpoint > 0.3) and (q2_midpoint < 0.7) and (q1_midpoint > 2.) and (q1_midpoint < 3.)):
            x0 = 2.;  y0 = 0.45  # Bottom-left
            x1 = 3;   y1 = 0.1  # Bottom-right
            x2 = 3;   y2 = 0.9  # Top-right
            x3 = 2.;  y3 = 0.55  # Top-left
            x, y = \
              affine(q1, q2, 
               [x0, y0], [x1, y1],
               [x2, y2], [x3, y3],
               [2., 0.3], [3, 0.3],
               [3, 0.7], [2., 0.7]
                    )


        if (return_jacobian):
            return (x, y, jacobian)
        else: 
            return(x, y)

    else:
        print("Error in get_cartesian_coords(): q1_start_local_left or q2_start_local_bottom not provided")
Example #30
0
def normalize(a):
    max_ = float(af.max(a))
    min_ = float(af.min(a))
    return (a - min_) / (max_ - min_)
Example #31
0
def normalize(a):
    mx = af.max(a)
    mn = af.min(a)
    return (a - mn)/(mx - mn)
Example #32
0
                         advection_terms, collision_operator.BGK, moments)

# Declaring a linear system object which will evolve the defined physical system:
nls = nonlinear_solver(system)
N_g = nls.N_ghost

# Time parameters:
dt_fvm = params.N_cfl * min(nls.dq1, nls.dq2) \
                      / max(domain.p1_end + domain.p2_end + domain.p3_end) # joining elements of the list

dt_fdtd = params.N_cfl * min(nls.dq1, nls.dq2) \
                       / params.c # lightspeed

dt = dt_fvm  # min(dt_fvm, dt_fdtd)

print('Minimum Value of f:', af.min(nls.f))
print('Error in density:', af.mean(af.abs(nls.compute_moments('density') - 1)))

v2_bulk = nls.compute_moments('mom_v2_bulk') / nls.compute_moments('density')
v3_bulk = nls.compute_moments('mom_v3_bulk') / nls.compute_moments('density')

v2_bulk_ana =   params.amplitude * -1.7450858652952794e-15 * af.cos(params.k_q1 * nls.q1_center) \
              - params.amplitude * 0.5123323181646575      * af.sin(params.k_q1 * nls.q1_center)

v3_bulk_ana =   params.amplitude * 0.5123323181646597 * af.cos(params.k_q1 * nls.q1_center) \
              - params.amplitude * 0                  * af.sin(params.k_q1 * nls.q1_center)

print('Error in v2_bulk:',
      af.mean(af.abs((v2_bulk - v2_bulk_ana) / v2_bulk_ana)))
print('Error in v3_bulk:',
      af.mean(af.abs((v3_bulk - v3_bulk_ana) / v3_bulk_ana)))
Example #33
0
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)

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

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

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


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

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


# The wave to be advected is either a sin or a Gaussian wave.
Example #34
0
def get_cartesian_coords(q1,
                         q2,
                         q1_start_local_left=None,
                         q2_start_local_bottom=None,
                         return_jacobian=False):

    q1_midpoint = 0.5 * (af.max(q1) + af.min(q1))
    q2_midpoint = 0.5 * (af.max(q2) + af.min(q2))

    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_g = domain.N_ghost
    N_q1 = q1.dims(
    )[2] - 2 * N_g  # Manually apply quadratic transformation for each zone along q1
    N_q2 = q2.dims(
    )[3] - 2 * N_g  # Manually apply quadratic transformation for each zone along q1

    # Default initializsation to rectangular grid
    x = q1
    y = q2
    jacobian = [[1. + 0. * q1, 0. * q1], [0. * q1, 1. + 0. * q1]]

    [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]] = jacobian

    # Radius and center of circular region
    radius = 0.5
    center = [0, 0]

    shift_x = 0. * d_q1 / 2
    shift_y = 0. * d_q2 / 2

    x_y_circle_top_left = [
        -radius / np.sqrt(2) + shift_x, radius / np.sqrt(2) - shift_y
    ]
    x_y_circle_bottom_left = [
        -radius / np.sqrt(2) + shift_x, -radius / np.sqrt(2) + shift_y
    ]
    x_y_circle_top_right = [
        radius / np.sqrt(2) - shift_x, radius / np.sqrt(2) - shift_y
    ]
    x_y_circle_bottom_right = [
        radius / np.sqrt(2) - shift_x, -radius / np.sqrt(2) + shift_y
    ]

    if (q1_start_local_left != None and q2_start_local_bottom != None):

        # Bottom-center domain
        if ((q2_midpoint < -0.33) and (q1_midpoint > -0.33)
                and (q1_midpoint < 0.33)):

            # Note : Never specify the x, y coordinates below in terms of q1 and q2 coordinates. Specify only in
            # physical x, y values.

            N = N_q1
            x_0 = -radius / np.sqrt(2)

            # Initialize to zero
            x = 0 * q1
            y = 0 * q2

            # Loop over each zone in x
            for i in range(0, N_q1 + 2 * N_g):

                index = i - N_g  # Index of the vertical slice, left-most being 0

                # q1, q2 grid slices to be passed into quadratic for transformation
                q1_slice = q1[0, 0, i, N_g:-N_g]
                q2_slice = q2[0, 0, i, N_g:-N_g]

                # Compute the x, y points using which the transformation will be defined
                # x, y nodes remain the same for each point on a vertical slice
                x_n = x_0 + np.sqrt(2) * radius * index / N  # Top-left
                y_n = -np.sqrt(radius**2 - x_n**2)

                x_n_plus_1 = x_0 + np.sqrt(2) * radius * (index +
                                                          1) / N  # Top-right
                y_n_plus_1 = -np.sqrt(radius**2 - x_n_plus_1**2)

                x_n_plus_half = x_0 + np.sqrt(2) * radius * (
                    index + 0.5) / N  # Top-center
                y_n_plus_half = -np.sqrt(radius**2 - x_n_plus_half**2)

                x_y_bottom_left = [x_n, -1]
                x_y_bottom_center = [x_n_plus_half, -1]
                x_y_bottom_right = [x_n_plus_1, -1]

                x_y_left_center = [x_n, (-1 + y_n) / 2]
                x_y_right_center = [x_n_plus_1, (-1 + y_n_plus_1) / 2]

                x_y_top_left = [x_n, y_n]
                x_y_top_center = [x_n_plus_half, y_n_plus_half]
                x_y_top_right = [x_n_plus_1, y_n_plus_1]

                for j in range(0, N_q2 + 2 * N_g):

                    # Get the transformation (x_i, y_i) for each point (q1_i, q2_i)
                    q1_i = q1[0, 0, i, j]
                    q2_i = q2[0, 0, i, j]

                    x_i, y_i, jacobian_i = quadratic_test(
                        q1_i,
                        q2_i,
                        q1_slice,
                        q2_slice,
                        x_y_bottom_left,
                        x_y_bottom_right,
                        x_y_top_right,
                        x_y_top_left,
                        x_y_bottom_center,
                        x_y_right_center,
                        x_y_top_center,
                        x_y_left_center,
                        q1_start_local_left + index * domain.dq1,
                        q2_start_local_bottom,
                    )

                    # Reconstruct the x,y grid from the loop
                    x[0, 0, i, j] = x_i
                    y[0, 0, i, j] = y_i

                    # TODO : Reconstruct jacobian
                    [[dx_dq1_i, dx_dq2_i], [dy_dq1_i, dy_dq2_i]] = jacobian_i
                    dx_dq1[0, 0, i, j] = dx_dq1_i.scalar()
                    dx_dq2[0, 0, i, j] = dx_dq2_i.scalar()
                    dy_dq1[0, 0, i, j] = dy_dq1_i.scalar()
                    dy_dq2[0, 0, i, j] = dy_dq2_i.scalar()

            jacobian = [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]]

        # Bottom-left domain
        elif ((q2_midpoint < -0.33) and (q1_midpoint > -1)
              and (q1_midpoint < -0.33)):

            N = N_q1
            x_0 = -1

            # Initialize to zero
            x = 0 * q1
            y = 0 * q2

            # Loop over each zone in x
            for i in range(0, N_q1 + 2 * N_g):

                index = i - N_g  # Index of the vertical slice, left-most being 0

                # q1, q2 grid slices to be passed into quadratic for transformation
                q1_slice = q1[0, 0, i, N_g:-N_g]
                q2_slice = q2[0, 0, i, N_g:-N_g]

                # Compute the x, y points using which the transformation will be defined
                # x, y nodes remain the same for each point on a vertical slice
                x_n = x_0 + (1 - radius / np.sqrt(2)) * index / N  # Top-left
                y_n = -radius / np.sqrt(2)

                x_n_plus_1 = x_0 + (1 - radius / np.sqrt(2)) * (
                    index + 1) / N  # Top-right
                y_n_plus_1 = -radius / np.sqrt(2)

                x_n_plus_half = x_0 + (1 - radius / np.sqrt(2)) * (
                    index + 0.5) / N  # Top-center
                y_n_plus_half = -radius / np.sqrt(2)

                x_y_bottom_left = [x_n, -1]
                x_y_bottom_center = [x_n_plus_half, -1]
                x_y_bottom_right = [x_n_plus_1, -1]

                x_y_left_center = [x_n, (-1 + y_n) / 2]
                x_y_right_center = [x_n_plus_1, (-1 + y_n_plus_1) / 2]

                x_y_top_left = [x_n, y_n]
                x_y_top_center = [x_n_plus_half, y_n_plus_half]
                x_y_top_right = [x_n_plus_1, y_n_plus_1]

                for j in range(0, N_q2 + 2 * N_g):

                    # Get the transformation (x_i, y_i) for each point (q1_i, q2_i)
                    q1_i = q1[0, 0, i, j]
                    q2_i = q2[0, 0, i, j]

                    x_i, y_i, jacobian_i = quadratic_test(
                        q1_i,
                        q2_i,
                        q1_slice,
                        q2_slice,
                        x_y_bottom_left,
                        x_y_bottom_right,
                        x_y_top_right,
                        x_y_top_left,
                        x_y_bottom_center,
                        x_y_right_center,
                        x_y_top_center,
                        x_y_left_center,
                        q1_start_local_left + index * domain.dq1,
                        q2_start_local_bottom,
                    )

                    # Reconstruct the x,y grid from the loop
                    x[0, 0, i, j] = x_i
                    y[0, 0, i, j] = y_i

                    # TODO : Reconstruct jacobian
                    [[dx_dq1_i, dx_dq2_i], [dy_dq1_i, dy_dq2_i]] = jacobian_i
                    dx_dq1[0, 0, i, j] = dx_dq1_i.scalar()
                    dx_dq2[0, 0, i, j] = dx_dq2_i.scalar()
                    dy_dq1[0, 0, i, j] = dy_dq1_i.scalar()
                    dy_dq2[0, 0, i, j] = dy_dq2_i.scalar()

            jacobian = [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]]

        # Bottom-right domain
        elif ((q2_midpoint < -0.33) and (q1_midpoint > 0.33)
              and (q1_midpoint < 1.)):

            N = N_q1
            x_0 = radius / np.sqrt(2)

            # Initialize to zero
            x = 0 * q1
            y = 0 * q2

            # Loop over each zone in x
            for i in range(0, N_q1 + 2 * N_g):

                index = i - N_g  # Index of the vertical slice, left-most being 0

                # q1, q2 grid slices to be passed into quadratic for transformation
                q1_slice = q1[0, 0, i, N_g:-N_g]
                q2_slice = q2[0, 0, i, N_g:-N_g]

                # Compute the x, y points using which the transformation will be defined
                # x, y nodes remain the same for each point on a vertical slice
                x_n = x_0 + (1 - x_0) * index / N  # Top-left
                y_n = -radius / np.sqrt(2)

                x_n_plus_1 = x_0 + (1 - x_0) * (index + 1) / N  # Top-right
                y_n_plus_1 = -radius / np.sqrt(2)

                x_n_plus_half = x_0 + (1 - x_0) * (index +
                                                   0.5) / N  # Top-center
                y_n_plus_half = -radius / np.sqrt(2)

                x_y_bottom_left = [x_n, -1]
                x_y_bottom_center = [x_n_plus_half, -1]
                x_y_bottom_right = [x_n_plus_1, -1]

                x_y_left_center = [x_n, (-1 + y_n) / 2]
                x_y_right_center = [x_n_plus_1, (-1 + y_n_plus_1) / 2]

                x_y_top_left = [x_n, y_n]
                x_y_top_center = [x_n_plus_half, y_n_plus_half]
                x_y_top_right = [x_n_plus_1, y_n_plus_1]

                for j in range(0, N_q2 + 2 * N_g):

                    # Get the transformation (x_i, y_i) for each point (q1_i, q2_i)
                    q1_i = q1[0, 0, i, j]
                    q2_i = q2[0, 0, i, j]

                    x_i, y_i, jacobian_i = quadratic_test(
                        q1_i,
                        q2_i,
                        q1_slice,
                        q2_slice,
                        x_y_bottom_left,
                        x_y_bottom_right,
                        x_y_top_right,
                        x_y_top_left,
                        x_y_bottom_center,
                        x_y_right_center,
                        x_y_top_center,
                        x_y_left_center,
                        q1_start_local_left + index * domain.dq1,
                        q2_start_local_bottom,
                    )

                    # Reconstruct the x,y grid from the loop
                    x[0, 0, i, j] = x_i
                    y[0, 0, i, j] = y_i

                    # TODO : Reconstruct jacobian
                    [[dx_dq1_i, dx_dq2_i], [dy_dq1_i, dy_dq2_i]] = jacobian_i
                    dx_dq1[0, 0, i, j] = dx_dq1_i.scalar()
                    dx_dq2[0, 0, i, j] = dx_dq2_i.scalar()
                    dy_dq1[0, 0, i, j] = dy_dq1_i.scalar()
                    dy_dq2[0, 0, i, j] = dy_dq2_i.scalar()

            jacobian = [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]]

        # Top-center domain
        if ((q2_midpoint > 0.33) and (q1_midpoint > -0.33)
                and (q1_midpoint < 0.33)):

            N = N_q1
            x_0 = -radius / np.sqrt(2)

            # Initialize to zero
            x = 0 * q1
            y = 0 * q2

            # Loop over each zone in x
            for i in range(0, N_q1 + 2 * N_g):

                index = i - N_g  # Index of the vertical slice, left-most being 0

                # q1, q2 grid slices to be passed into quadratic for transformation
                q1_slice = q1[0, 0, i, N_g:-N_g]
                q2_slice = q2[0, 0, i, N_g:-N_g]

                # Compute the x, y points using which the transformation will be defined
                # x, y nodes remain the same for each point on a vertical slice
                x_n = x_0 + np.sqrt(2) * radius * index / N  # Bottom-left
                y_n = np.sqrt(radius**2 - x_n**2)

                x_n_plus_1 = x_0 + np.sqrt(2) * radius * (
                    index + 1) / N  # Bottom-right
                y_n_plus_1 = np.sqrt(radius**2 - x_n_plus_1**2)

                x_n_plus_half = x_0 + np.sqrt(2) * radius * (
                    index + 0.5) / N  # Bottom-center
                y_n_plus_half = np.sqrt(radius**2 - x_n_plus_half**2)

                x_y_bottom_left = [x_n, y_n]
                x_y_bottom_center = [x_n_plus_half, y_n_plus_half]

                x_y_bottom_right = [x_n_plus_1, y_n_plus_1]

                x_y_left_center = [x_n, (1 + y_n) / 2]
                x_y_right_center = [x_n_plus_1, (1 + y_n_plus_1) / 2]

                x_y_top_left = [x_n, 1]
                x_y_top_center = [x_n_plus_half, 1]
                x_y_top_right = [x_n_plus_1, 1]

                for j in range(0, N_q2 + 2 * N_g):

                    # Get the transformation (x_i, y_i) for each point (q1_i, q2_i)
                    q1_i = q1[0, 0, i, j]
                    q2_i = q2[0, 0, i, j]

                    x_i, y_i, jacobian_i = quadratic_test(
                        q1_i,
                        q2_i,
                        q1_slice,
                        q2_slice,
                        x_y_bottom_left,
                        x_y_bottom_right,
                        x_y_top_right,
                        x_y_top_left,
                        x_y_bottom_center,
                        x_y_right_center,
                        x_y_top_center,
                        x_y_left_center,
                        q1_start_local_left + index * domain.dq1,
                        q2_start_local_bottom,
                    )

                    # Reconstruct the x,y grid from the loop
                    x[0, 0, i, j] = x_i
                    y[0, 0, i, j] = y_i

                    # TODO : Reconstruct jacobian
                    [[dx_dq1_i, dx_dq2_i], [dy_dq1_i, dy_dq2_i]] = jacobian_i
                    dx_dq1[0, 0, i, j] = dx_dq1_i.scalar()
                    dx_dq2[0, 0, i, j] = dx_dq2_i.scalar()
                    dy_dq1[0, 0, i, j] = dy_dq1_i.scalar()
                    dy_dq2[0, 0, i, j] = dy_dq2_i.scalar()

            jacobian = [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]]

        # Top-left domain
        elif ((q2_midpoint > 0.33) and (q1_midpoint > -1)
              and (q1_midpoint < -0.33)):

            N = N_q1
            x_0 = -1  #-radius/np.sqrt(2)

            # Initialize to zero
            x = 0 * q1
            y = 0 * q2

            # Loop over each zone in x
            for i in range(0, N_q1 + 2 * N_g):

                index = i - N_g  # Index of the vertical slice, left-most being 0

                # q1, q2 grid slices to be passed into quadratic for transformation
                q1_slice = q1[0, 0, i, N_g:-N_g]
                q2_slice = q2[0, 0, i, N_g:-N_g]

                # Compute the x, y points using which the transformation will be defined
                # x, y nodes remain the same for each point on a vertical slice
                x_n = x_0 + (1 -
                             radius / np.sqrt(2)) * index / N  # Bottom-left
                y_n = radius / np.sqrt(2)

                x_n_plus_1 = x_0 + (1 - radius / np.sqrt(2)) * (
                    index + 1) / N  # Bottom-right
                y_n_plus_1 = radius / np.sqrt(2)

                x_n_plus_half = x_0 + (1 - radius / np.sqrt(2)) * (
                    index + 0.5) / N  # Bottom-center
                y_n_plus_half = radius / np.sqrt(2)

                x_y_bottom_left = [x_n, y_n]
                x_y_bottom_center = [x_n_plus_half, y_n_plus_half]

                x_y_bottom_right = [x_n_plus_1, y_n_plus_1]

                x_y_left_center = [x_n, (1 + y_n) / 2]
                x_y_right_center = [x_n_plus_1, (1 + y_n_plus_1) / 2]

                x_y_top_left = [x_n, 1]
                x_y_top_center = [x_n_plus_half, 1]
                x_y_top_right = [x_n_plus_1, 1]

                for j in range(0, N_q2 + 2 * N_g):

                    # Get the transformation (x_i, y_i) for each point (q1_i, q2_i)
                    q1_i = q1[0, 0, i, j]
                    q2_i = q2[0, 0, i, j]

                    x_i, y_i, jacobian_i = quadratic_test(
                        q1_i,
                        q2_i,
                        q1_slice,
                        q2_slice,
                        x_y_bottom_left,
                        x_y_bottom_right,
                        x_y_top_right,
                        x_y_top_left,
                        x_y_bottom_center,
                        x_y_right_center,
                        x_y_top_center,
                        x_y_left_center,
                        q1_start_local_left + index * domain.dq1,
                        q2_start_local_bottom,
                    )

                    # Reconstruct the x,y grid from the loop
                    x[0, 0, i, j] = x_i
                    y[0, 0, i, j] = y_i

                    # TODO : Reconstruct jacobian
                    [[dx_dq1_i, dx_dq2_i], [dy_dq1_i, dy_dq2_i]] = jacobian_i
                    dx_dq1[0, 0, i, j] = dx_dq1_i.scalar()
                    dx_dq2[0, 0, i, j] = dx_dq2_i.scalar()
                    dy_dq1[0, 0, i, j] = dy_dq1_i.scalar()
                    dy_dq2[0, 0, i, j] = dy_dq2_i.scalar()

            jacobian = [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]]

        # Top-right domain
        elif ((q2_midpoint > 0.33) and (q1_midpoint > 0.33)
              and (q1_midpoint < 1)):

            N = N_q1
            x_0 = radius / np.sqrt(2)

            # Initialize to zero
            x = 0 * q1
            y = 0 * q2

            # Loop over each zone in x
            for i in range(0, N_q1 + 2 * N_g):

                index = i - N_g  # Index of the vertical slice, left-most being 0

                # q1, q2 grid slices to be passed into quadratic for transformation
                q1_slice = q1[0, 0, i, N_g:-N_g]
                q2_slice = q2[0, 0, i, N_g:-N_g]

                # Compute the x, y points using which the transformation will be defined
                # x, y nodes remain the same for each point on a vertical slice
                x_n = x_0 + (1 - x_0) * index / N  # Bottom-left
                y_n = radius / np.sqrt(2)

                x_n_plus_1 = x_0 + (1 - x_0) * (index + 1) / N  # Bottom-right
                y_n_plus_1 = radius / np.sqrt(2)

                x_n_plus_half = x_0 + (1 - x_0) * (index +
                                                   0.5) / N  # Bottom-center
                y_n_plus_half = radius / np.sqrt(2)

                x_y_bottom_left = [x_n, y_n]
                x_y_bottom_center = [x_n_plus_half, y_n_plus_half]

                x_y_bottom_right = [x_n_plus_1, y_n_plus_1]

                x_y_left_center = [x_n, (1 + y_n) / 2]
                x_y_right_center = [x_n_plus_1, (1 + y_n_plus_1) / 2]

                x_y_top_left = [x_n, 1]
                x_y_top_center = [x_n_plus_half, 1]
                x_y_top_right = [x_n_plus_1, 1]

                for j in range(0, N_q2 + 2 * N_g):

                    # Get the transformation (x_i, y_i) for each point (q1_i, q2_i)
                    q1_i = q1[0, 0, i, j]
                    q2_i = q2[0, 0, i, j]

                    x_i, y_i, jacobian_i = quadratic_test(
                        q1_i,
                        q2_i,
                        q1_slice,
                        q2_slice,
                        x_y_bottom_left,
                        x_y_bottom_right,
                        x_y_top_right,
                        x_y_top_left,
                        x_y_bottom_center,
                        x_y_right_center,
                        x_y_top_center,
                        x_y_left_center,
                        q1_start_local_left + index * domain.dq1,
                        q2_start_local_bottom,
                    )

                    # Reconstruct the x,y grid from the loop
                    x[0, 0, i, j] = x_i
                    y[0, 0, i, j] = y_i

                    # TODO : Reconstruct jacobian
                    [[dx_dq1_i, dx_dq2_i], [dy_dq1_i, dy_dq2_i]] = jacobian_i
                    dx_dq1[0, 0, i, j] = dx_dq1_i.scalar()
                    dx_dq2[0, 0, i, j] = dx_dq2_i.scalar()
                    dy_dq1[0, 0, i, j] = dy_dq1_i.scalar()
                    dy_dq2[0, 0, i, j] = dy_dq2_i.scalar()

            jacobian = [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]]

        # Center-Right domain
        elif ((q2_midpoint > -0.33) and (q2_midpoint < 0.33)
              and (q1_midpoint > 0.33)):

            N = N_q1
            y_0 = -radius / np.sqrt(2)

            # Initialize to zero
            x = 0 * q1
            y = 0 * q2

            # Loop over each zone in y
            for j in range(0, N_q2 + 2 * N_g):
                print(j)
                index = j - N_g  # Index of the vertical slice, left-most being 0

                # q1, q2 grid slices to be passed into quadratic for transformation
                q1_slice = q1[0, 0, N_g:-N_g, j]
                q2_slice = q2[0, 0, N_g:-N_g, j]

                # Compute the x, y points using which the transformation will be defined
                # x, y nodes remain the same for each point on a vertical slice
                y_n = y_0 + np.sqrt(2) * radius * index / N
                x_n = np.sqrt(radius**2 - y_n**2)  # Bottom-left

                y_n_plus_1 = y_0 + np.sqrt(2) * radius * (index +
                                                          1) / N  # top-left
                x_n_plus_1 = np.sqrt(radius**2 - y_n_plus_1**2)

                y_n_plus_half = y_0 + np.sqrt(2) * radius * (
                    index + 0.5) / N  # Center-left
                x_n_plus_half = np.sqrt(radius**2 - y_n_plus_half**2)

                x_y_bottom_left = [x_n, y_n]
                x_y_bottom_center = [(1 + x_n) / 2, y_n]
                x_y_bottom_right = [1, y_n]

                x_y_left_center = [x_n_plus_half, y_n_plus_half]
                x_y_right_center = [1, y_n_plus_half]

                x_y_top_left = [x_n_plus_1, y_n_plus_1]
                x_y_top_center = [(1 + x_n_plus_1) / 2, y_n_plus_1]
                x_y_top_right = [1, y_n_plus_1]

                for i in range(0, N_q1 + 2 * N_g):

                    # Get the transformation (x_i, y_i) for each point (q1_i, q2_i)
                    q1_i = q1[0, 0, i, j]
                    q2_i = q2[0, 0, i, j]

                    x_i, y_i, jacobian_i = quadratic_test(
                        q1_i,
                        q2_i,
                        q1_slice,
                        q2_slice,
                        x_y_bottom_left,
                        x_y_bottom_right,
                        x_y_top_right,
                        x_y_top_left,
                        x_y_bottom_center,
                        x_y_right_center,
                        x_y_top_center,
                        x_y_left_center,
                        q1_start_local_left,
                        q2_start_local_bottom + index * domain.dq2,
                    )

                    # Reconstruct the x,y grid from the loop
                    x[0, 0, i, j] = x_i
                    y[0, 0, i, j] = y_i

                    # TODO : Reconstruct jacobian
                    [[dx_dq1_i, dx_dq2_i], [dy_dq1_i, dy_dq2_i]] = jacobian_i
                    dx_dq1[0, 0, i, j] = dx_dq1_i.scalar()
                    dx_dq2[0, 0, i, j] = dx_dq2_i.scalar()
                    dy_dq1[0, 0, i, j] = dy_dq1_i.scalar()
                    dy_dq2[0, 0, i, j] = dy_dq2_i.scalar()

            jacobian = [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]]

        # Center-Left domain
        elif ((q2_midpoint > -0.33) and (q2_midpoint < 0.33)
              and (q1_midpoint < -0.33)):

            N = N_q1
            #x_0      = -radius/np.sqrt(2)
            y_0 = -radius / np.sqrt(2)

            # Initialize to zero
            x = 0 * q1
            y = 0 * q2

            # Loop over each zone in y
            for j in range(0, N_q2 + 2 * N_g):
                print(j)
                index = j - N_g  # Index of the vertical slice, left-most being 0

                # q1, q2 grid slices to be passed into quadratic for transformation
                q1_slice = q1[0, 0, N_g:-N_g, j]
                q2_slice = q2[0, 0, N_g:-N_g, j]

                # Compute the x, y points using which the transformation will be defined
                # x, y nodes remain the same for each point on a vertical slice
                y_n = y_0 + np.sqrt(2) * radius * index / N
                x_n = -np.sqrt(radius**2 - y_n**2)  # Bottom-right

                y_n_plus_1 = y_0 + np.sqrt(2) * radius * (index +
                                                          1) / N  # top-right
                x_n_plus_1 = -np.sqrt(radius**2 - y_n_plus_1**2)

                y_n_plus_half = y_0 + np.sqrt(2) * radius * (
                    index + 0.5) / N  # Center-right
                x_n_plus_half = -np.sqrt(radius**2 - y_n_plus_half**2)

                x_y_bottom_left = [-1, y_n]
                x_y_bottom_center = [(-1 + x_n) / 2, y_n]
                x_y_bottom_right = [x_n, y_n]

                x_y_left_center = [-1, y_n_plus_half]
                x_y_right_center = [x_n_plus_half, y_n_plus_half]

                x_y_top_left = [-1, y_n_plus_1]
                x_y_top_center = [(-1 + x_n_plus_1) / 2, y_n_plus_1]
                x_y_top_right = [x_n_plus_1, y_n_plus_1]

                for i in range(0, N_q1 + 2 * N_g):

                    # Get the transformation (x_i, y_i) for each point (q1_i, q2_i)
                    q1_i = q1[0, 0, i, j]
                    q2_i = q2[0, 0, i, j]

                    x_i, y_i, jacobian_i = quadratic_test(
                        q1_i,
                        q2_i,
                        q1_slice,
                        q2_slice,
                        x_y_bottom_left,
                        x_y_bottom_right,
                        x_y_top_right,
                        x_y_top_left,
                        x_y_bottom_center,
                        x_y_right_center,
                        x_y_top_center,
                        x_y_left_center,
                        q1_start_local_left,
                        q2_start_local_bottom + index * domain.dq2,
                    )

                    # Reconstruct the x,y grid from the loop
                    x[0, 0, i, j] = x_i
                    y[0, 0, i, j] = y_i

                    # TODO : Reconstruct jacobian
                    [[dx_dq1_i, dx_dq2_i], [dy_dq1_i, dy_dq2_i]] = jacobian_i
                    dx_dq1[0, 0, i, j] = dx_dq1_i.scalar()
                    dx_dq2[0, 0, i, j] = dx_dq2_i.scalar()
                    dy_dq1[0, 0, i, j] = dy_dq1_i.scalar()
                    dy_dq2[0, 0, i, j] = dy_dq2_i.scalar()

            jacobian = [[dx_dq1, dx_dq2], [dy_dq1, dy_dq2]]

        # Center domain
        elif ((q2_midpoint > -0.33) and (q2_midpoint < 0.33)
              and (q1_midpoint > -0.33) and (q1_midpoint < 0.33)):

            x_y_bottom_left = x_y_circle_bottom_left
            x_y_bottom_center = [0., -radius]
            x_y_bottom_right = x_y_circle_bottom_right

            x_y_left_center = [-radius, 0]
            x_y_right_center = [radius, 0]

            x_y_top_left = x_y_circle_top_left
            x_y_top_center = [0., radius]
            x_y_top_right = x_y_circle_top_right

            x, y, jacobian = quadratic(
                q1,
                q2,
                x_y_bottom_left,
                x_y_bottom_right,
                x_y_top_right,
                x_y_top_left,
                x_y_bottom_center,
                x_y_right_center,
                x_y_top_center,
                x_y_left_center,
                q1_start_local_left,
                q2_start_local_bottom,
            )

        if (return_jacobian):
            return (x, y, jacobian)
        else:
            return (x, y)

    else:
        print(
            "Error in get_cartesian_coords(): q1_start_local_left or q2_start_local_bottom not provided"
        )