def createCurve(pt, n, ang=-20, HD = None):
    ###############################
    # circular curve consisting of n points
    # input:   pt (starting point: x,y,z)
    #          n  (numb of points in the curve)
    #          ang(angle in degrees till the curve goes)
    #          HD (height distribution
    # output:  x  (x array of the points)
    #          y  (y array of the points)
    #          z  (z array of the points)
    # description: the curve start in pt and then
    # it is rotated by "angle" degrees.

    x   = np.zeros(n)
    y   = np.zeros(n)
    z   = np.zeros(n)
    for i in range(n):
        tmp = Point(x=pt.X, y=pt.Y, z=pt.Z)
        tmp.rotZ(i*ang/n)
        x[i] = tmp.X
        y[i] = tmp.Y
        z[i] = tmp.Z
        if HD:
            z[i] = getHeight(tmp, HD)

    return x, y, z
def getAverage2D(IN, x, y, z, propName, typeline, typeavg, dtheta, dz=1.0):
    ###############################
    # calculate the mass/area average of a property over a line/arc
    # input:   IN       (input file)
    #          x, y, z  (coordinates of the curve (can be a line or arc))
    #          propName (name of the property that is being averaged)
    #          typeline (type of curve, can be either line or arc)
    #          typeavg  (type of average, can be either area or mass based)
    #          dtheta   (only for ARC curves, is the total arc lenght in degrees)
    #          dz       (only for 3D, is discretization in z-direction)
    # output:  average
    # observation: this function is used in getAverage3D() which is called at each z-coordinate. That is why dz
    # comes into the function. For quasi-3D we assumed dz=1.0

    # extracting the line from the tecplot file
    LINE    = tp.data.extract.extract_line(zip(x, y, z))
    n       = len(y) - 1

    # extracting variables
    rho     = (LINE.values('RHO').as_numpy_array())
    prop    = (LINE.values(propName).as_numpy_array())
    vel_x   = (LINE.values('vrel-X').as_numpy_array())
    vel_y   = (LINE.values('vrel-Y').as_numpy_array())
    vel_z   = (LINE.values('vrel-Z').as_numpy_array())
    angle   = np.arctan((LINE.values('Y').as_numpy_array())/(LINE.values('X').as_numpy_array()))/ (4 * np.arctan(1.0) / 180.)


    # to check if all the line is include in the domain. In the case it is not, the lenght is changed
    #  which corresponds to the amount of intersection with the tecplot file
    if (n+1)!=len(rho):
        n = len(rho) - 1

    momentum = np.zeros(n + 1)
    mom      = np.sqrt(vel_x ** 2 + vel_y ** 2 + vel_z ** 2) * rho
    m        = np.ones(n + 1)

    # calculating the total and partial area
    if typeline == 'ARC':
        pt1     = Point(x=x[0], y=y[0], z=z[0])
        radius  = pt1.rad
        dArea   = getArcLenght(IN, radius, dtheta) * dz / n

        for i in range(n+1):
            # calculating the normal unit vector to the surface
            normVect = Point(rad=radius, theta=angle[i], z=0)       # unit vector normal to the surface
            # normVect.rotZ(180)                                      # the flow goes inwards
            normVect.scale(1 / normVect.magnitude())                # making it unit vector
            # projecting the velocity to the normal vector
            momentum[i] = np.abs((vel_x[i] * normVect.X * rho[i]) + (vel_y[i] * normVect.Y * rho[i])
                                 + (vel_z[i] * normVect.Z * rho[i]))
    else:
        pt1     = Point(x=x[0], y=y[0], z=z[0])
        pt2     = Point(x=x[-1], y=y[-1], z=z[-1])
        dArea   = getLineDistance(IN,pt1, pt2,n+1) *dz

        # calculating the normal unit vector to the surface
        normVect = pt2 - pt1
        normVect.rotZ(-90)                                  # making it normal to the line
        normVect.scale(1/normVect.magnitude())              # making it unit vector
        # projecting the velocity to the normal vector
        for i in range(n + 1):
            momentum[i] = np.abs((vel_x[i] * normVect.X * rho[i]) + (vel_y[i] * normVect.Y * rho[i])
                                 + (vel_z[i] * normVect.Z * rho[i]))

     # calculating the average
    if typeavg == 'MASS':
        m_prop = np.sum(momentum * prop * dArea)
        m_mass = np.sum(momentum * dArea)
    elif typeavg == 'AREA':
        m_prop = np.sum(m * prop * dArea)
        m_mass = np.sum(m * dArea)
    else:
        m_prop = np.sum(mom*prop * dArea)
        m_mass = np.sum(mom*dArea)


    return m_prop, m_mass