support_functions.f90 Source File


Source Code

!-----------------------------------------------------------------------------------------------------------------------------------
! This file is part of ReMKiT1D.
!
! ReMKiT1D 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, either version 3 of the License, or (at your option) any later version.
!
! ReMKiT1D 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 ReMKiT1D. If not, see <https://www.gnu.org/licenses/>. 
!
! Copyright 2023 United Kingdom Atomic Energy Authority (stefan.mijin@ukaea.uk)
!-----------------------------------------------------------------------------------------------------------------------------------
module support_functions
    !! Contains various support and math functions

    use data_kinds                  ,only: rk, ik
    use runtime_constants           ,only: debugging ,assertions
    use assertion_utility       
    use support_types               

    implicit none 

!-----------------------------------------------------------------------------------------------------------------------------------
    interface findIndices
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function findIndicesMatrix(mask) result(indices)
        !! Find locations of .true. values in logical mask of rank 2

        logical     ,dimension(:,:) ,intent(in)   :: mask
        integer(ik) ,dimension(:,:) ,allocatable  :: indices

    end function findIndicesMatrix
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function findIndicesVector(mask) result(indices)
        !! Find locations of .true. values in logical mask of rank 1

        logical     ,dimension(:) ,intent(in)   :: mask
        integer(ik) ,dimension(:) ,allocatable  :: indices

    end function findIndicesVector
!-----------------------------------------------------------------------------------------------------------------------------------
    end interface
!-----------------------------------------------------------------------------------------------------------------------------------
    interface removeName
!-----------------------------------------------------------------------------------------------------------------------------------
    pure elemental module function removeNameIntArray(input) result(output)
        !! Remove name from named integer array and return IntArray

        type(NamedIntegerArray) ,intent(in) :: input 
        type(IntArray)                      :: output

    end function removeNameIntArray
!-----------------------------------------------------------------------------------------------------------------------------------
    pure elemental module function removeNameRealArray(input) result(output)
        !! Remove name from named real array and return RealArray

        type(NamedRealArray) ,intent(in) :: input 
        type(RealArray)                  :: output

    end function removeNameRealArray
!-----------------------------------------------------------------------------------------------------------------------------------
    pure elemental module function removeNameLogicalArray(input) result(output)
        !! Remove name from named logical array and return LogicalArray

        type(NamedLogicalArray) ,intent(in) :: input 
        type(LogicalArray)                  :: output

    end function removeNameLogicalArray
!-----------------------------------------------------------------------------------------------------------------------------------
    end interface
!-----------------------------------------------------------------------------------------------------------------------------------
    interface 
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function allCombinations(array) result(res)
        !! Convert IntArray(:) vector into a 2D array of shape (size(IntArray),:) containing all possible combination of IntArray(:)%entries.
        !! Works only for sizes 1 and 3

        type(IntArray) ,dimension(:)   ,intent(in)   :: array
        integer(ik)    ,dimension(:,:) ,allocatable  :: res

    end function allCombinations
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function findNearestPointsInArray(array,point) result(pair)
        !! Finds indices of two of the values nearest to a point in a monotonic array

        real(rk)       ,dimension(:)   ,intent(in)   :: array
        real(rk)                       ,intent(in)   :: point
        integer(ik)    ,dimension(2)                 :: pair

    end function findNearestPointsInArray
!-----------------------------------------------------------------------------------------------------------------------------------
    elemental module function expInt1(val) result(res)
        !! Allan and Hastings approximation of E1 exponential integral, with coefficients from routine in:
        !! Shanjie Zhang, Jianming Jin,
        !! Computation of Special Functions,
        !! Wiley, 1996,
        !! ISBN: 0-471-11963-6,
        !! LC: QA351.C45.

        real(rk) ,intent(in)   :: val
        real(rk)               :: res 

    end function expInt1
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function removeDupeInts(array) result(uniques)
        !! Removes duplicates from integer array - unoptimized

        integer(ik)    ,dimension(:)   ,intent(in)   :: array
        integer(ik) ,allocatable   ,dimension(:)     :: uniques

    end function removeDupeInts
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function withinBounds(array,lowerBound,upperBound) result(res)
        !! Returns map array >= lowerBound .and. array <= upperBound

        integer(ik)    ,dimension(:)   ,intent(in)   :: array
        integer(ik)                    ,intent(in)   :: lowerBound
        integer(ik)                    ,intent(in)   :: upperBound
        logical     ,allocatable   ,dimension(:)     :: res

    end function withinBounds
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function flatTensorProduct(array1,array2,array3) result(res)
        !! Takes a 3-fold tensor product of rank-1 real arrays and flattens it

        real(rk) ,dimension(:)   ,intent(in)  :: array1
        real(rk) ,dimension(:)   ,intent(in)  :: array2
        real(rk) ,dimension(:)   ,intent(in)  :: array3
        real(rk) ,dimension(:)   ,allocatable :: res

    end function flatTensorProduct
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function jaggedArray(array,mask) result(res)
        !! Takes rank-2 array and optional mask and produces rank-1 array of realArrays - a jagged array - by masking the first dimension

        real(rk)           ,dimension(:,:)   ,intent(in)  :: array
        logical  ,optional ,dimension(:,:)   ,intent(in)  :: mask
        type(RealArray) ,dimension(:)   ,allocatable :: res

    end function jaggedArray
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function allPl(points,maxL) result(res)
        !! Return rank-2 array of Legendre polynomials evaluated at given points. Result shape is (size(points),0:maxL). Uses recursion
        !! formula.

        real(rk)           ,dimension(:)   ,intent(in)  :: points
        integer(ik)                        ,intent(in)  :: maxL
        real(rk) ,allocatable ,dimension(:,:)           :: res

    end function allPl
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function shiftedFlatTensorProduct(array1,array2,shiftArray,power) result(res)
        !! Takes 2 arrays and produces a flattened tensor product, such that array1's dimension is the inner dimension. If present,
        !! shift array should conform to array2 and will be added to array1 as the product is taken
        !! The shifted array1 is then optionally raised to a power.

        real(rk)           ,dimension(:)   ,intent(in)  :: array1
        real(rk)           ,dimension(:)   ,intent(in)  :: array2
        real(rk) ,optional ,dimension(:)   ,intent(in)  :: shiftArray
        real(rk) ,optional                 ,intent(in)  :: power
        real(rk)           ,dimension(:)   ,allocatable :: res

    end function shiftedFlatTensorProduct
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function triangularIntArray(dim,lower) result(res)
        !! Returns upper or lower triangular pattern as IntArrays with dimension dim

        integer(ik)                    ,intent(in)  :: dim
        logical  ,optional             ,intent(in)  :: lower
        type(IntArray) ,dimension(:)   ,allocatable :: res

    end function triangularIntArray
!-----------------------------------------------------------------------------------------------------------------------------------
    end interface
!-----------------------------------------------------------------------------------------------------------------------------------
end module support_functions
!-----------------------------------------------------------------------------------------------------------------------------------