MODULE moduleMath
  IMPLICIT NONE

  CONTAINS
    !Outer product of two tensors
    PURE FUNCTION outerProduct(a,b) RESULT(s)
      IMPLICIT NONE

      REAL(8), DIMENSION(1:3), INTENT(in):: a, b
      REAL(8):: s(1:3,1:3)

      s = SPREAD(a, dim = 2, ncopies = 3)*SPREAD(b, dim = 1, ncopies = 3)

    END FUNCTION outerProduct

    !Cross product of two 3D vectors
    PURE FUNCTION crossProduct(a, b) RESULT(c)
      IMPLICIT NONE

      REAL(8), DIMENSION(1:3), INTENT(in):: a, b
      REAL(8), DIMENSION(1:3):: c

      c = 0.D0

      c(1) =   a(2)*b(3) - a(3)*b(2)
      c(2) = -(a(1)*b(3) - a(3)*b(1))
      c(3) =   a(1)*b(2) - a(2)*b(1)

    END FUNCTION crossProduct

    !Normalizes a 3D vector
    PURE FUNCTION normalize(a) RESULT(b)
      IMPLICIT NONE

      REAL(8), DIMENSION(1:3), INTENT(in):: a
      REAL(8), DIMENSION(1:3):: b
      
      b = a / NORM2(a)

    END FUNCTION normalize

    !Norm 1 of vector
    PURE FUNCTION norm1(a) RESULT(b)
      IMPLICIT NONE
      REAL(8), DIMENSION(:), INTENT(in):: a
      REAL(8):: b

      b = SUM(DABS(a))

    END FUNCTION norm1

    PURE FUNCTION reducedMass(m_i, m_j) RESULT(rMass)
      IMPLICIT NONE

      REAL(8), INTENT(in):: m_i, m_j
      REAL(8):: rMass

      rMass = (m_i * m_j) / (m_i + m_j)

    END FUNCTION

    FUNCTION tensorTrace(a) RESULT(t)
      IMPLICIT NONE

      REAL(8), DIMENSION(1:3,1:3):: a
      REAL(8):: t

      t = 0.D0
      t = a(1,1)+a(2,2)+a(3,3)

    END FUNCTION tensorTrace

END MODULE moduleMath
