!fpx3_header(0.13_3a)
!
!dependencies
!   dir: ~/devel/gyre-4/src/utils 
!   sources: -
!   includes: ../extern/core/core.inc ../rot/gyre_trad_rot.inc
!   uses: gyre_rot gyre_trad gyre_model core_kinds ISO_FORTRAN_ENV gyre_modepar
!   provides: gyre_r_trad_rot
!end dependencies
!
!end fpx3_header
! Module   : gyre_r_trad_rot
! Purpose  : rotational effects (traditional approximation, real)
!
! Copyright 2013-2014 Rich Townsend
!
! This file is part of GYRE. GYRE is free software: you can
! redistribute it and/or modify it under the terms of the GNU General
! Public License as published by the Free Software Foundation, version 3.
!
! GYRE is distributed in the hope that it will be useful, but WITHOUT
! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
! License for more details.
!
! You should have received a copy of the GNU General Public License
! along with this program.  If not, see <http://www.gnu.org/licenses/>.

! Incfile  : gyre_trad_rot
! Purpose  : rotational effects (traditional approximation, template)
!
! Copyright 2013-2014 Rich Townsend
!
! This file is part of GYRE. GYRE is free software: you can
! redistribute it and/or modify it under the terms of the GNU General
! Public License as published by the Free Software Foundation, version 3.
!
! GYRE is distributed in the hope that it will be useful, but WITHOUT
! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
! License for more details.
!
! You should have received a copy of the GNU General Public License
! along with this program.  If not, see <http://www.gnu.org/licenses/>.

! Incfile  : core
! Purpose  : fpx3 macros

!****

!****

!****

!****

!****

!****

!****

!****

!****

module gyre_r_trad_rot

  ! Uses

  use core_kinds

  use gyre_model
  use gyre_modepar
  use gyre_trad
  use gyre_rot

  use ISO_FORTRAN_ENV

  ! No implicit typing

  implicit none

  ! Derived-type definitions

  type, extends (r_rot_t) :: r_trad_rot_t
     private
     class(model_t), pointer :: ml => null()
   contains
     private
     procedure, public :: omega => omega_
     procedure         :: omega_c_1_
     procedure         :: omega_c_v_
     procedure         :: lambda_1_
     procedure         :: lambda_v_
  end type r_trad_rot_t

  ! Interfaces

  interface r_trad_rot_t
     module procedure r_trad_rot_t_
  end interface r_trad_rot_t

  ! Access specifiers

  private

  public :: r_trad_rot_t

  ! Procedures

contains

  function r_trad_rot_t_ (ml, mp) result (rt)

    class(model_t), pointer, intent(in) :: ml
    type(modepar_t), intent(in)         :: mp
    type(r_trad_rot_t)               :: rt

    ! Construct the trad_rot_t

    rt%ml => ml
    rt%mp = mp

    ! Finish

    return

  end function r_trad_rot_t_

!****

  function omega_ (this, x, omega_c) result (omega)

    class(r_trad_rot_t), intent(in) :: this
    real(WP), intent(in)               :: x
    real(WP), intent(in)              :: omega_c
    real(WP)                          :: omega

    ! Evaluate the inertial-frame frequency from the corotating-frame
    ! frequency

    omega = omega_c + this%mp%m*this%ml%Omega_rot(x)

    ! Finish

    return

  end function omega_

!****

  function omega_c_1_ (this, x, omega) result (omega_c)

    class(r_trad_rot_t), intent(in) :: this
    real(WP), intent(in)               :: x
    real(WP), intent(in)              :: omega
    real(WP)                          :: omega_c

    ! Evaluate the corotating-frame frequency from the inertial-frame
    ! frequency (scalar)

    omega_c = omega - this%mp%m*this%ml%Omega_rot(x)

    ! Finish

    return

  end function omega_c_1_

!****

  function omega_c_v_ (this, x, omega) result (omega_c)

    class(r_trad_rot_t), intent(in) :: this
    real(WP), intent(in)               :: x(:)
    real(WP), intent(in)              :: omega
    real(WP)                          :: omega_c(SIZE(x))

    ! Evaluate the corotating-frame frequency from the inertial-frame
    ! frequency (vector)

    omega_c = omega - this%mp%m*this%ml%Omega_rot(x)

    ! Finish

    return

  end function omega_c_v_

!****

  function lambda_1_ (this, x, omega) result (lambda)

    class(r_trad_rot_t), intent(in) :: this
    real(WP), intent(in)               :: x
    real(WP), intent(in)              :: omega
    real(WP)                          :: lambda

    real(WP) :: nu

    ! Evaluate the angular eigenvalue (scalar)

    nu = 2._WP*this%ml%Omega_rot(x)/this%omega_c(x, omega)

    lambda = trad_lambda(nu, this%mp%l, this%mp%m)

    ! Finish

    return

  end function lambda_1_

!****

  function lambda_v_ (this, x, omega) result (lambda)

    class(r_trad_rot_t), intent(in) :: this
    real(WP), intent(in)               :: x(:)
    real(WP), intent(in)              :: omega
    real(WP)                          :: lambda(SIZE(x))

    integer :: i

    ! Evaluate the angular eigenvalue (vector)

    do i = 1, SIZE(x)
       lambda(i) = this%lambda(x(i), omega)
    end do

    ! Finish

    return

  end function lambda_v_

end module gyre_r_trad_rot

