Example #1
0
def del2(f, dx, dy, dz, x=None, y=None, coordinate_system="cartesian"):
    """
    del2(f, dx, dy, dz, x=None, y=None, coordinate_system="cartesian")

    Calculate del2, the Laplacian of a scalar field f.

    Parameters
    ----------
    x, y : ndarrays
        Radial (x) and polar (y) coordinates, 1d arrays.

    run2D : bool
        Deals with pure 2-D snapshots (solved the (x,z)-plane pb).
        !Only for Cartesian grids at the moment!

    coordinate_system : string
        Coordinate system under which to take the divergence.
        Takes 'cartesian', 'cylindrical' and 'spherical'.
    """

    import numpy as np
    from pencil.math.derivatives.der import xder2, yder2, zder2, xder, yder

    if coordinate_system == "cartesian":
        del2_value = xder2(f, dx) + yder2(f, dy) + zder2(f, dz)
    if coordinate_system == "cylindrical":
        if x is None:
            print("ERROR: need to specify x (radius)")
            raise ValueError
        # Make sure x has compatible dimensions.
        x = x[np.newaxis, np.newaxis, :]
        del2_value = (xder(f, dx) / x + xder2(f, dx) + yder2(f, dy) / (x**2) +
                      zder2(f, dz))
    if coordinate_system == "spherical":
        if x is None or y is None:
            print("ERROR: need to specify x (radius) and y (polar angle)")
            raise ValueError
        # Make sure x and y have compatible dimensions.
        x = x[np.newaxis, np.newaxis, :]
        y = y[np.newaxis, :, np.newaxis]
        del2_value = (2 * xder(f, dx) / x + xder2(f, dx) +
                      np.cos(y) * yder(f, dy) / ((x**2) * np.sin(y)) +
                      yder2(f, dy) / (x**2) + zder2(f, dz) /
                      ((x * np.sin(y))**2))
    return del2_value
Example #2
0
def gij(f, dx, dy, dz, nder=6):
    """
    Calculate del6 (defined here as d^6/dx^6 + d^6/dy^6 + d^6/dz^6, rather
    than del2^3) of a scalar f for hyperdiffusion.
    """

    import numpy as np

    if f.ndim != 4 or f.shape[0] != 3:
        print("curl3: must have vector 4-D array f[3, mz, my, mx] for curl3.")
        raise ValueError
    gij = np.array(f, f, f)
    for i in range(3):
        if nder == 1:
            from pencil.math.derivatives.der import xder, yder, zder

            gij[i, 0] = xder(f[i], dx, dy, dz)
            gij[i, 1] = yder(f[i], dx, dy, dz)
            gij[i, 2] = zder(f[i], dx, dy, dz)
        elif nder == 2:
            from pencil.math.derivatives.der import xder2, yder2, zder2

            gij[i, 0] = xder2(f[i], dx, dy, dz)
            gij[i, 1] = yder2(f[i], dx, dy, dz)
            gij[i, 2] = zder2(f[i], dx, dy, dz)
        elif nder == 3:
            from pencil.math.derivatives.der import xder3, yder3, zder3

            gij[i, 0] = xder3(f[i], dx, dy, dz)
            gij[i, 1] = yder3(f[i], dx, dy, dz)
            gij[i, 2] = zder3(f[i], dx, dy, dz)
        elif nder == 4:
            from pencil.math.derivatives.der import xder4, yder4, zder4

            gij[i, 0] = xder4(f[i], dx, dy, dz)
            gij[i, 1] = yder4(f[i], dx, dy, dz)
            gij[i, 2] = zder4(f[i], dx, dy, dz)
        elif nder == 5:
            from pencil.math.derivatives.der import xder5, yder5, zder5

            gij[i, 0] = xder5(f[i], dx, dy, dz)
            gij[i, 1] = yder5(f[i], dx, dy, dz)
            gij[i, 2] = zder5(f[i], dx, dy, dz)
        elif nder == 6:
            from pencil.math.derivatives.der import xder6, yder6, zder6

            gij[i, 0] = xder6(f[i], dx, dy, dz)
            gij[i, 1] = yder6(f[i], dx, dy, dz)
            gij[i, 2] = zder6(f[i], dx, dy, dz)

    return gij
Example #3
0
def curl3(f, dx, dy, dz, x=None, y=None, coordinate_system='cartesian'):
    """
    Take the triple curl of a pencil code vector array f.

    *x, y*:
      Radial (x) and polar (y) coordinates, 1d arrays.

    *run2D*:
      Deals with pure 2-D snapshots (solved the (x,z)-plane pb).
      !Only for Cartesian grids at the moment!

    *coordinate_system*:
      Coordinate system under which to take the divergence.
      Takes 'cartesian' and 'cylindrical'.
    """

    import numpy as np
    from pencil.math.derivatives.der import xder, yder, zder, xder2, yder2, zder2, xder3, yder3, zder3

    if (f.ndim != 4 or f.shape[0] != 3):
        print("curl3: must have vector 4-D array f[3, mz, my, mx] for curl3.")
        raise ValueError

    curl3_value = np.zeros(f.shape)

    if coordinate_system == 'cartesian':
        curl3_value[0] = zder(xder2(f[1], dx) + yder2(f[1], dy), dz) + zder3(f[1], dz) - \
                         yder(xder2(f[2], dx) + zder2(f[2], dz), dy) - yder3(f[2], dy)
        curl3_value[1] = xder3(f[2], dx) + xder(yder2(f[2], dy) + zder2(f[2], dz), dx) - \
                         zder(xder2(f[0], dx) + yder2(f[0], dy), dz) - zder3(f[0], dz)
        curl3_value[2] = yder(xder2(f[0], dx) + zder2(f[0], dz), dy) + yder3(f[0], dy) - \
                         xder3(f[1], dx) - xder(yder2(f[1], dy) + zder2(f[1], dz), dx)
    if coordinate_system == 'cylindrical':
        if x is None:
            print(
                'ERROR: need to specify x (radius) for cylindrical coordinates.'
            )
            raise ValueError
        # Make sure x has compatible dimensions.
        x = x[np.newaxis, np.newaxis, :]
        curl3_value[0] = 2*yder(zder(f[0], dz), dy)/x**2 - yder(zder(f[2], dz), dy)/x**2 \
                         - xder2(yder(f[2], dy), dx)/x - yder3(f[2], dy)/x**3 \
                         + yder2(zder(f[1], dz), dy)/x**2 - yder(zder2(f[2], dz), dy)/x \
                         + zder3(f[1], dz) - zder(f[1], dz)/x**2 \
                         + xder(zder(f[1], dz), dx)/x + xder2(zder(f[1], dz), dx)
        curl3_value[1] = 2*yder(zder(f[1], dz), dy)/x**2 - yder2(zder(f[0], dz), dy)/x**2 \
                         - zder3(f[0], dz) + xder(zder2(f[2], dz), dx) \
                         - xder(zder(f[0], dz), dx)/x + zder(f[0], dz)/x**2 \
                         - xder2(zder(f[0], dz), dx) + xder(zder(f[2], dz), dx)/x \
                         - zder(f[2], dz)/x**2 + xder3(f[2], dx) \
                         + xder(yder2(f[2], dy), dx)/x**2 - 2*yder2(f[2], dy)/x**3
        curl3_value[2] = - xder(zder2(f[1], dz), dx) - zder2(f[1], dz)/x \
                         + xder(f[1], dx) /x**2 - f[1]/x**3 \
                         - xder3(f[1], dx) + xder2(yder(f[0], dy), dx)/x \
                         - xder(yder(f[0], dy), dx)/x**2 + yder(f[0], dy)/x**3 \
                         - yder2(f[1], dy)/x**3 - xder(yder2(f[1], dy), dx)/x**2 \
                         + yder3(f[0], dy)/x**3 + yder(zder2(f[0], dz), dy)/x \
                         -2*xder2(f[1], dx)/x
    if coordinate_system == 'spherical':
        if x is None or y is None:
            print(
                'ERROR: need to specify x (radius) and y (polar angle) for spherical coordinates'
            )
            raise ValueError
        # Make sure x and y have compatible dimensions.
        x = x[np.newaxis, np.newaxis, :]
        y = y[np.newaxis, :, np.newaxis]
        # TODO: This one needs some fixing.
        curl3_value[0] = (-1/x**3) * (np.sin(y)*((np.cos(y)**2 - 1)*(yder2(zder(f[1], dz), dy)) + \
                         (-np.cos(y)**2 * np.sin(y) + np.sin(y))*(yder3(f[2], dy)) \
                         -x**2 *(xder2(zder(f[1], dz), dx)) - zder3(f[1], dz) + \
                         np.sin(y)*(xder2(yder(f[2], dy), dx))*x**2 + (yder(zder2(f[2], dz), dy))*np.sin(y) \
                         +(-6*np.cos(y)**3 + 6* np.cos(y))*(yder2(f[2], dy))- 2*x*(xder(zder(f[1], dz), dx)) \
                         -3*np.sin(y)*np.cos(y)*(yder(zder(f[1], dz), dy)) + np.cos(y)*(xder2(f[2], dx))*x**2 + \
                         2*np.sin(y)*(xder(yder(f[2], dy), dx))*x + (zder2(f[2], dz))*np.cos(y) + \
                         (-2*np.cos(y)**2 + 1)*(zder(f[1], dz)) + (11*np.cos(y)**2 * np.sin(y) - 4*np.sin(y))*(yder(f[2], dy)) \
                         + 2*np.cos(y)*(xder(f[2], dx))*x + (6*np.cos(y)**3 - 5*np.cos(y))*f[2]))
        curl3_value[1] = 1/(x**3*np.sin(y)) * ((np.cos(y)**2 - 1)*(yder2(zder(f[0], dz), dy)) + \
                         (-x * np.cos(y)**2 + x)*np.sin(y)*(xder(yder2(f[2], dy), dx)) \
                         - (xder2(zder(f[0], dz), dx))*x**2 - zder3(f[0], dz) + x**3*(xder3(f[2], dx))*np.sin(y) + \
                         x*(xder(zder2(f[2], dz), dx))*np.sin(y) + (-2*np.cos(y)**2 + 2)*(yder(zder(f[1], dz), dy)) + \
                         3*x**2*xder2(f[2], dx)*np.sin(y) + zder2(f[2], dz)*np.sin(y) + (2*x*np.cos(y)**2 - x)*np.sin(y)*(xder(f[2], dx)) \
                         + (3*np.cos(y)**3 - 3*np.cos(y))*(yder(f[2], dy)) + 2*np.sin(y)*np.cos(y)*(zder(f[1], dz)) + \
                         (-2*np.cos(y)**2 + 1)*np.sin(y)*f[2])
        curl3_value[2] = 1/x**3 * ((yder3(f[0], dy))*(1-np.cos(y)**2) + (x*np.cos(y)**2 - x)*(xder(yder2(f[1], dy), dx)) + \
                         (xder2(yder(f[1], dy), dx))*x**2 + yder(zder2(f[0], dz), dy) - (xder3(f[1], dx))*x**3 - \
                         (xder(zder2(f[1], dz), dx))*x + (np.cos(y)**2 - 1)*(yder2(f[1], dy)) \
                         + 3*(yder2(f[1], dy))*np.sin(y)*np.cos(y) - 3*(xder2(f[1], dx))*x**2 - \
                         3*(xder(yder(f[1], dy), dx))*np.sin(y)*np.cos(y)*x + zder2(f[1], dz) - \
                         2*(yder(zder(f[2], dz), dy))*np.sin(y) + (2*np.cos(y)**2 - 1)*(yder(f[1], dy)) + \
                         (-2*np.cos(y)**2 + x)*(xder(f[1], dx)) - 3*(yder(f[1], dy))*np.sin(y)*np.cos(y) - \
                         2*(zder(f[2], dz))*np.cos(y) + (-2*np.cos(y)**2 +1)*f[1])
    return curl3_value
Example #4
0
def del2v(f, dx, dy, dz, x=None, y=None, coordinate_system='cartesian'):
    """
    Calculate del2, the Laplacian of a vector field f.

    *x, y*:
      Radial (x) and polar (y) coordinates, 1d arrays.

    *run2D*:
      Deals with pure 2-D snapshots (solved the (x,z)-plane pb).
      !Only for Cartesian grids at the moment!

    *coordinate_system*:
      Coordinate system under which to take the divergence.
      Takes 'cartesian', 'cylindrical' and 'spherical'.
    """

    if f.shape[0] != 3:
        print(
            "Vector Laplacian: must have a vector 4D array f(3, mz, my, mx) for Vector Laplacian"
        )
        raise ValueError

    import numpy as np
    from pencil.math.derivatives.der import xder2, yder2, zder2, yder, zder

    del2v_value = np.zeros(f.shape)

    if coordinate_system == 'cartesian':
        del2v_value[0] = xder2(f[0], dx) + yder2(f[0], dy) + zder2(f[0], dz)
        del2v_value[1] = xder2(f[1], dx) + yder2(f[1], dy) + zder2(f[1], dz)
        del2v_value[2] = xder2(f[2], dx) + yder2(f[2], dy) + zder2(f[2], dz)
    if coordinate_system == 'cylindrical':
        if x is None:
            print('Error: need to specify x (radius)')
            raise ValueError
        # Make sure x has compatible dimensions.
        x = x[np.newaxis, np.newaxis, :]
        del2v_value[0] = del2(f[0], dx, dy, dz, x=x, y=y, coordinate_system='cylindrical') \
                        - f[0]/(x**2) - 2*yder(f[1], dy)/x**2
        del2v_value[1] = del2(f[1], dx, dy, dz, x=x, y=y, coordinate_system='cylindrical') \
                         - f[1]/(x**2) + 2*yder(f[0], dy)/x**2
        del2v_value[2] = del2(f[2],
                              dx,
                              dy,
                              dz,
                              x=x,
                              y=y,
                              coordinate_system='cylindrical')
    if coordinate_system == 'spherical':
        if x is None or y is None:
            print('ERROR: need to specify x (radius) and y (polar angle)')
        # Make sure x and y have compatible dimensions.
        x = x[np.newaxis, np.newaxis, :]
        y = y[np.newaxis, :, np.newaxis]
        del2v_value[0] = del2(f[0], dx, dy, dz, x=x, y=y, coordinate_system='spherical') \
                         - 2*f[0]/x**2 - 2*yder(f[1], dy)/x**2 - 2*np.cos(y)*f[1]/(x**2*np.sin(y)) - 2*zder(f[2], dz)/(x**2*np.sin(y))
        del2v_value[1] = del2(f[1], dx, dy, dz, x=x, y=y, coordinate_system='spherical') \
                         - f[1]/(x*np.sin(y))**2 + 2*yder(f[0], dy)/(x**2) - (2*np.cos(y))*zder(f[2], dz)/(x*np.sin(y))**2
        del2v_value[2] = del2(f[2], dx, dy, dz, x=x, y=y, coordinate_system='spherical') \
                         - f[2]/(x*np.sin(y))**2 + 2*zder(f[0], dz)/(np.sin(y)*x**2) - (2*np.cos(y))*zder(f[1], dz)/(x*np.sin(y))**2
    return del2v_value
Example #5
0
def curl2(f, dx, dy, dz, x=None, y=None, coordinate_system='cartesian'):
    """
    Take the double curl of a pencil code vector array f.

    *x, y*:
      Radial (x) and polar (y) coordinates, 1d arrays.

    *run2D*:
      Deals with pure 2-D snapshots (solved the (x,z)-plane pb).
      !Only for Cartesian grids at the moment!

    *coordinate_system*:
      Coordinate system under which to take the divergence.
      Takes 'cartesian', 'cylindrical' and 'spherical'.
    """

    import numpy as np
    from pencil.math.derivatives.der import xder, yder, zder, xder2, yder2, zder2

    if (f.ndim != 4 or f.shape[0] != 3):
        print("curl2: must have vector 4-D array f[3, mz, my, mx] for curl2.")
        raise ValueError

    curl2_value = np.zeros(f.shape)

    if coordinate_system == 'cartesian':
        curl2_value[0] = xder(yder(f[1], dy) + zder(f[2], dz), dx) \
                              -yder2(f[0], dy) - zder2(f[0], dz)
        curl2_value[1] = yder(xder(f[0], dx) + zder(f[2], dz), dy) \
                              -xder2(f[1], dx) - zder2(f[1], dz)
        curl2_value[2] = zder(xder(f[0], dx) + yder(f[1], dy), dz) \
                              -xder2(f[2], dx) - yder2(f[2], dy)
    if coordinate_system == 'cylindrical':
        if x is None:
            print(
                'ERROR: need to specify x (radius) for cylindrical coordinates.'
            )
            raise ValueError
        # Make sure x has compatible dimensions.
        x = x[np.newaxis, np.newaxis, :]
        curl2_value[0] = yder(f[1], dy)/x**2 + xder(yder(f[1], dy), dx)/x \
                         - yder2(f[0], dy)/x**2 - zder2(f[0], dz) + xder(zder(f[2], dz), dx)
        curl2_value[1] = yder(zder(f[2], dz), dy)/x - zder2(f[1], dz) + f[1]/x**2 \
                         - xder(f[1], dx)/x - xder2(f[1], dx) + xder(yder(f[0], dy), dx)/x \
                         - yder(f[0], dy)/x**2
        curl2_value[2] = zder(f[0], dz)/x + xder(zder(f[0], dz), dx) - zder(f[2], dx)/x \
                         - xder2(f[2], dx) - yder2(f[2], dy)/x**2 + yder(zder(f[1], dz), dy)/x
    if coordinate_system == 'spherical':
        if x is None or y is None:
            print(
                'ERROR: need to specify x (radius) and y (polar angle) for spherical coordinates.'
            )
            raise ValueError
        # Make sure x and y have compatible dimensions.
        x = x[np.newaxis, np.newaxis, :]
        y = y[np.newaxis, :, np.newaxis]
        curl2_value[0] = (yder(
            np.sin(y) * (xder(x * f[1], dx) - yder(f[0], dy)) / x, dy) - zder(
                (zder(f[0], dz) / np.sin(y) - xder(x * f[2], dx)) / x, dz)) / (
                    x * np.sin(y))
        curl2_value[1] = (zder(
            (yder(np.sin(y) * f[2], dy) - zder(f[1], dz)) /
            (x * np.sin(y)), dz) / np.sin(y) - xder(
                (xder(x * f[1], dx) - yder(f[0], dy)), dx)) / x
        curl2_value[2] = (xder(
            (zder(f[0], dz) / np.sin(y) - xder(x * f[2], dx)), dx) - yder(
                (yder(np.sin(y) * f[2], dy) - zder(f[1], dz)) /
                (x * np.sin(y)), dy)) / x
    return curl2_value
Example #6
0
def curl3(f, dx, dy, dz, x=None, y=None, coordinate_system="cartesian"):
    """
    curl3(f, dx, dy, dz, x=None, y=None, coordinate_system="cartesian")

    Take the triple curl of a pencil code vector array f.

    Parameters
    ----------
    x, y : ndarrays
        Radial (x) and polar (y) coordinates, 1d arrays.

    run2D : bool
        Deals with pure 2-D snapshots (solved the (x,z)-plane pb).
        !Only for Cartesian grids at the moment!

    coordinate_system : string
        Coordinate system under which to take the divergence.
        Takes 'cartesian' and 'cylindrical'.
    """

    import numpy as np
    from pencil.math.derivatives.der import (
        xder,
        yder,
        zder,
        xder2,
        yder2,
        zder2,
        xder3,
        yder3,
        zder3,
    )

    if f.ndim != 4 or f.shape[0] != 3:
        print("curl3: must have vector 4-D array f[3, mz, my, mx] for curl3.")
        raise ValueError

    curl3_value = np.zeros(f.shape)

    if coordinate_system == "cartesian":
        curl3_value[0] = (zder(xder2(f[1], dx) + yder2(f[1], dy), dz) +
                          zder3(f[1], dz) -
                          yder(xder2(f[2], dx) + zder2(f[2], dz), dy) -
                          yder3(f[2], dy))
        curl3_value[1] = (xder3(f[2], dx) +
                          xder(yder2(f[2], dy) + zder2(f[2], dz), dx) -
                          zder(xder2(f[0], dx) + yder2(f[0], dy), dz) -
                          zder3(f[0], dz))
        curl3_value[2] = (yder(xder2(f[0], dx) + zder2(f[0], dz), dy) +
                          yder3(f[0], dy) - xder3(f[1], dx) -
                          xder(yder2(f[1], dy) + zder2(f[1], dz), dx))
    if coordinate_system == "cylindrical":
        if x is None:
            print(
                "ERROR: need to specify x (radius) for cylindrical coordinates."
            )
            raise ValueError
        # Make sure x has compatible dimensions.
        x = x[np.newaxis, np.newaxis, :]
        curl3_value[0] = (2 * yder(zder(f[0], dz), dy) / x**2 -
                          yder(zder(f[2], dz), dy) / x**2 -
                          xder2(yder(f[2], dy), dx) / x -
                          yder3(f[2], dy) / x**3 +
                          yder2(zder(f[1], dz), dy) / x**2 -
                          yder(zder2(f[2], dz), dy) / x + zder3(f[1], dz) -
                          zder(f[1], dz) / x**2 +
                          xder(zder(f[1], dz), dx) / x +
                          xder2(zder(f[1], dz), dx))
        curl3_value[1] = (2 * yder(zder(f[1], dz), dy) / x**2 -
                          yder2(zder(f[0], dz), dy) / x**2 - zder3(f[0], dz) +
                          xder(zder2(f[2], dz), dx) -
                          xder(zder(f[0], dz), dx) / x +
                          zder(f[0], dz) / x**2 - xder2(zder(f[0], dz), dx) +
                          xder(zder(f[2], dz), dx) / x -
                          zder(f[2], dz) / x**2 + xder3(f[2], dx) +
                          xder(yder2(f[2], dy), dx) / x**2 -
                          2 * yder2(f[2], dy) / x**3)
        curl3_value[2] = (-xder(zder2(f[1], dz), dx) - zder2(f[1], dz) / x +
                          xder(f[1], dx) / x**2 - f[1] / x**3 -
                          xder3(f[1], dx) + xder2(yder(f[0], dy), dx) / x -
                          xder(yder(f[0], dy), dx) / x**2 +
                          yder(f[0], dy) / x**3 - yder2(f[1], dy) / x**3 -
                          xder(yder2(f[1], dy), dx) / x**2 +
                          yder3(f[0], dy) / x**3 +
                          yder(zder2(f[0], dz), dy) / x -
                          2 * xder2(f[1], dx) / x)
    if coordinate_system == "spherical":
        if x is None or y is None:
            print(
                "ERROR: need to specify x (radius) and y (polar angle) for spherical coordinates"
            )
            raise ValueError
        # Make sure x and y have compatible dimensions.
        x = x[np.newaxis, np.newaxis, :]
        y = y[np.newaxis, :, np.newaxis]
        # TODO: This one needs some fixing.
        curl3_value[0] = (-1 / x**3) * (np.sin(y) * (
            (np.cos(y)**2 - 1) * (yder2(zder(f[1], dz), dy)) +
            (-np.cos(y)**2 * np.sin(y) + np.sin(y)) *
            (yder3(f[2], dy)) - x**2 *
            (xder2(zder(f[1], dz), dx)) - zder3(f[1], dz) + np.sin(y) *
            (xder2(yder(f[2], dy), dx)) * x**2 +
            (yder(zder2(f[2], dz), dy)) * np.sin(y) +
            (-6 * np.cos(y)**3 + 6 * np.cos(y)) * (yder2(f[2], dy)) - 2 * x *
            (xder(zder(f[1], dz), dx)) - 3 * np.sin(y) * np.cos(y) *
            (yder(zder(f[1], dz), dy)) + np.cos(y) *
            (xder2(f[2], dx)) * x**2 + 2 * np.sin(y) *
            (xder(yder(f[2], dy), dx)) * x + (zder2(f[2], dz)) * np.cos(y) +
            (-2 * np.cos(y)**2 + 1) * (zder(f[1], dz)) +
            (11 * np.cos(y)**2 * np.sin(y) - 4 * np.sin(y)) *
            (yder(f[2], dy)) + 2 * np.cos(y) * (xder(f[2], dx)) * x +
            (6 * np.cos(y)**3 - 5 * np.cos(y)) * f[2]))
        curl3_value[1] = (1 / (x**3 * np.sin(y)) * (
            (np.cos(y)**2 - 1) * (yder2(zder(f[0], dz), dy)) +
            (-x * np.cos(y)**2 + x) * np.sin(y) * (xder(yder2(f[2], dy), dx)) -
            (xder2(zder(f[0], dz), dx)) * x**2 - zder3(f[0], dz) + x**3 *
            (xder3(f[2], dx)) * np.sin(y) + x *
            (xder(zder2(f[2], dz), dx)) * np.sin(y) + (-2 * np.cos(y)**2 + 2) *
            (yder(zder(f[1], dz), dy)) + 3 * x**2 * xder2(f[2], dx) * np.sin(y)
            + zder2(f[2], dz) * np.sin(y) +
            (2 * x * np.cos(y)**2 - x) * np.sin(y) * (xder(f[2], dx)) +
            (3 * np.cos(y)**3 - 3 * np.cos(y)) *
            (yder(f[2], dy)) + 2 * np.sin(y) * np.cos(y) * (zder(f[1], dz)) +
            (-2 * np.cos(y)**2 + 1) * np.sin(y) * f[2]))
        curl3_value[2] = (1 / x**3 * (
            (yder3(f[0], dy)) * (1 - np.cos(y)**2) + (x * np.cos(y)**2 - x) *
            (xder(yder2(f[1], dy), dx)) +
            (xder2(yder(f[1], dy), dx)) * x**2 + yder(zder2(f[0], dz), dy) -
            (xder3(f[1], dx)) * x**3 - (xder(zder2(f[1], dz), dx)) * x +
            (np.cos(y)**2 - 1) * (yder2(f[1], dy)) + 3 *
            (yder2(f[1], dy)) * np.sin(y) * np.cos(y) - 3 *
            (xder2(f[1], dx)) * x**2 - 3 *
            (xder(yder(f[1], dy), dx)) * np.sin(y) * np.cos(y) * x +
            zder2(f[1], dz) - 2 * (yder(zder(f[2], dz), dy)) * np.sin(y) +
            (2 * np.cos(y)**2 - 1) * (yder(f[1], dy)) +
            (-2 * np.cos(y)**2 + x) * (xder(f[1], dx)) - 3 *
            (yder(f[1], dy)) * np.sin(y) * np.cos(y) - 2 *
            (zder(f[2], dz)) * np.cos(y) + (-2 * np.cos(y)**2 + 1) * f[1]))
    return curl3_value