physics_utilities_mod.f90 Source File


This file depends on

sourcefile~~physics_utilities_mod.f90~~EfferentGraph sourcefile~physics_utilities_mod.f90 physics_utilities_mod.f90 sourcefile~utility_functions_mod.f90 utility_functions_mod.f90 sourcefile~physics_utilities_mod.f90->sourcefile~utility_functions_mod.f90 sourcefile~array_operations_mod.f90 array_operations_mod.f90 sourcefile~physics_utilities_mod.f90->sourcefile~array_operations_mod.f90 sourcefile~global_variables_mod.f90 global_variables_mod.f90 sourcefile~physics_utilities_mod.f90->sourcefile~global_variables_mod.f90

Files dependent on this one

sourcefile~~physics_utilities_mod.f90~~AfferentGraph sourcefile~physics_utilities_mod.f90 physics_utilities_mod.f90 sourcefile~pes_matrix_mod.f90 pes_matrix_mod.f90 sourcefile~pes_matrix_mod.f90->sourcefile~physics_utilities_mod.f90 sourcefile~channels_mod.f90 channels_mod.f90 sourcefile~channels_mod.f90->sourcefile~physics_utilities_mod.f90 sourcefile~state_to_state_cross_sections_mod.f90 state_to_state_cross_sections_mod.f90 sourcefile~state_to_state_cross_sections_mod.f90->sourcefile~physics_utilities_mod.f90 sourcefile~scattering.f90 scattering.f90 sourcefile~scattering.f90->sourcefile~physics_utilities_mod.f90 sourcefile~scattering.f90->sourcefile~pes_matrix_mod.f90 sourcefile~scattering.f90->sourcefile~channels_mod.f90 sourcefile~scattering.f90->sourcefile~state_to_state_cross_sections_mod.f90 sourcefile~input_reader_mod.f90 input_reader_mod.f90 sourcefile~scattering.f90->sourcefile~input_reader_mod.f90 sourcefile~boundary_conditions_mod.f90 boundary_conditions_mod.f90 sourcefile~scattering.f90->sourcefile~boundary_conditions_mod.f90 sourcefile~propagator_mod.f90 propagator_mod.f90 sourcefile~scattering.f90->sourcefile~propagator_mod.f90 sourcefile~input_reader_mod.f90->sourcefile~physics_utilities_mod.f90 sourcefile~boundary_conditions_mod.f90->sourcefile~physics_utilities_mod.f90 sourcefile~propagator_mod.f90->sourcefile~physics_utilities_mod.f90 sourcefile~propagator_mod.f90->sourcefile~pes_matrix_mod.f90

Contents


Source Code

module physics_utilities_mod
   !! This module provides helper functions: "units_conversion", "total_energy"
   !! "wavevector_squared_from_energy", and functions that count and save
   !! open levels in the rovibrational basis.
   !---------------------------------------------------------------------------!
   use, intrinsic :: iso_fortran_env, only: int32, sp => real32, dp => real64
   use utility_functions_mod, only: write_error
   use array_operations_mod, only: allocate_1d
   use global_variables_mod
   !---------------------------------------------------------------------------!
   implicit none
   !---------------------------------------------------------------------------!
   contains
      !------------------------------------------------------------------------!
      !------------------------------------------------------------------------!
      subroutine units_conversion
         !! converts all physical quantities to atomic units
         !---------------------------------------------------------------------!
         integer(int32) :: level_index_1_
         !---------------------------------------------------------------------!
         reduced_mass    = reduced_mass * amu_to_au
         energy          = energy / hartree_to_cm
         potential_depth = potential_depth / hartree_to_cm
         !---------------------------------------------------------------------!
         do level_index_1_ = 1, number_of_basis_levels
            internal_energies(level_index_1_) =                                &
               internal_energies(level_index_1_)/hartree_to_cm
         enddo
         !---------------------------------------------------------------------!
         units_converted = .true.
         !---------------------------------------------------------------------!
      end subroutine units_conversion
      !------------------------------------------------------------------------!
      !------------------------------------------------------------------------!
      function total_energy() result(etot_)
         !! returns the total energy
         !---------------------------------------------------------------------!
         real(dp) ::  etot_
         !---------------------------------------------------------------------!
         if (relative_energy_flag.eq.0) then
            etot_ = energy
         else if (relative_energy_flag.eq.1) then
            etot_ = energy+internal_energies(initial_level)
         endif
         !---------------------------------------------------------------------!
      end function total_energy
      !------------------------------------------------------------------------!
      !------------------------------------------------------------------------!
      function wavevector_squared_from_energy(energy_) result(k_)
         !! returns the squared wavevector, \\(k_{a}^{2}\\),
         !! given the energy of a given state, \\(E_{a}\\);
         !! calls etot() function; atomic units in the whole function
         !! \\( k_{a} = \sqrt(2 \mu (E_{tot} - E_{a}) \\)
         !! since it uses reduced_mass and total_energy(), the function checks
         !! if units are already converted
         !---------------------------------------------------------------------!
         real(dp), intent(in) :: energy_
            !! energy of a given state, \\( E_{a} \\), in a.u.
         real(dp) :: k_
            !! wavevector, \\(k_{a}\\), in a.u.
         !---------------------------------------------------------------------!
         if (units_converted) then
            k_ = 2*reduced_mass*(total_energy() - energy_)
         else
            call write_error("wavevector_squared_from_energy called " //       &
               "but units are not converted yet")
         endif
         !---------------------------------------------------------------------!
      end function wavevector_squared_from_energy
      !------------------------------------------------------------------------!
      !------------------------------------------------------------------------!
      function is_open(energy_) result(is_open_)
         !! checks if a channel/level is energetically accessible (open)
         !! by comparing energy with total_energy
         !---------------------------------------------------------------------!
         real(dp), intent(in) :: energy_
            !! level/channel energy
         logical :: is_open_
         !---------------------------------------------------------------------!
         is_open_ = ( energy_ <= total_energy() )
         !---------------------------------------------------------------------!
      end function is_open
      !------------------------------------------------------------------------!
      !------------------------------------------------------------------------!
      function count_open_basis_levels() result(open_)
         !! counts the energetically accessible levels in the basis
         !---------------------------------------------------------------------!
         integer(int32) :: open_, level_index_1_
         !---------------------------------------------------------------------!
         open_ = 0
         do level_index_1_ = 1, number_of_basis_levels
            if (is_open(internal_energies(level_index_1_))) open_ = open_ + 1
         enddo
         !---------------------------------------------------------------------!
      end function count_open_basis_levels
      !------------------------------------------------------------------------!
      !------------------------------------------------------------------------!
      subroutine save_open_basis_levels(number_of_open_basis_levels,           &
         open_basis_levels, basis_wavevectors)
         !! saves indices to open levels in the basis and corresponding
         !! wavevectors (in A^2)
         !---------------------------------------------------------------------!
         integer(int32), intent(in) :: number_of_open_basis_levels
            !! number of energetically accessible levels in the basis
         integer(int32), intent(inout), allocatable :: open_basis_levels(:)
            !! array holding indices to energetically accessible levels
            !! in the basis
         real(dp), intent(inout), allocatable :: basis_wavevectors(:)
            !! array holding wavevectors calculated w.r.t energetically
            !! accessible levels in the basis
         !---------------------------------------------------------------------!
         integer(int32) :: count_, level_index_1_
         !---------------------------------------------------------------------!
         call allocate_1d(open_basis_levels, number_of_open_basis_levels)
         call allocate_1d(basis_wavevectors, number_of_open_basis_levels)
         !---------------------------------------------------------------------!
         count_ = 0
         do level_index_1_ = 1, number_of_basis_levels
            if (is_open(internal_energies(level_index_1_))) then
               count_ = count_ + 1
               open_basis_levels(count_) = level_index_1_
               basis_wavevectors(count_) = sqrt(                               &
                  wavevector_squared_from_energy(internal_energies(            &
                  level_index_1_)) ) / bohr_to_angstrom 
            endif
         enddo
         !---------------------------------------------------------------------!
      end subroutine save_open_basis_levels
   !---------------------------------------------------------------------------!
end module physics_utilities_mod