CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > General Forums > Main CFD Forum

Switching between single and double precision in Fortran

Register Blogs Community New Posts Updated Threads Search

Like Tree9Likes
  • 1 Post By sbaffini
  • 3 Post By agd
  • 1 Post By praveen
  • 1 Post By sbaffini
  • 1 Post By sbaffini
  • 1 Post By el_mojito
  • 1 Post By Gerry Kan

 
 
LinkBack Thread Tools Search this Thread Display Modes
Prev Previous Post   Next Post Next
Old   November 8, 2020, 19:43
Default Switching between single and double precision in Fortran
  #1
Senior Member
 
Sayan Bhattacharjee
Join Date: Mar 2020
Posts: 495
Rep Power: 8
aerosayan is on a distinguished road
I want to write fortran 90 or fortran 2003 code and be able to select between either single/double precision at compile time.


In C++ it is extremely easy to do this using template meta-programming.


Code:
template<typename T>
T sum(T a, T b)
{
    return a+b;

}
I can use the sum function for adding any type that supports the + operator.


However I have very little idea on how to implement such a generic function in Fortran.


I can select between single and double precision for basic arithmetic using selected_real_kind method and using real(xp) to define the required precision.



Code:
! Define single & double precision
integer, parameter :: sp = selected_real_kind(6, 37)
integer, parameter :: dp = selected_real_kind(15, 307)


! The selected precision level
integer, parameter :: xp = selected_real_kind(precision(1.0_dp))
Using this, I can simply write code that would allow simple arithmetic operations in my preferred precision.


Code:
! Constant fractions
real(xp), parameter ::             &
    half        = 0.5_xp,          &
    third       = 1.0_xp / 3.0_xp, &
    fourth      = 1.0_xp / 4.0_xp, &
    fifth       = 1.0_xp / 5.0_xp, &
    sixth       = 1.0_xp / 6.0_xp
This is somewhat good, but I face an issue when I try to call fortran functions and subroutines. Since fortran functions and subroutines are not meta-programmable, we can only pass arguments of valid type. For example, we can only get correct square root for double precision arithmetic if I use dsqrt. When I change the value of xp to selected_real_kind(precision(1.0_sp)), the code obviously no longer works correctly when I use dsqrt.


So, I tried to define generic interfaces to mathematical functions like :


Code:
!==-------------------------------------------------------------------------==!
!{{{ > MODULE : NCX_GENERIC_MATH
!==-------------------------------------------------------------------------==!
! - Generic interfaces to mathematical functions
!==----                                                                -----==!
module ncx_generic_math
use ncx_precision

private
public :: sqrt_gn, abs_gn

!==-----------------                                       -----------------==!
! > INTERFACE : SQRT_GN
!==----                                                                -----==!
! - Generic interface for SQRT
!==----                                                                -----==!
interface sqrt_gn

pure function sqrt_dp(x)
use ncx_precision, only : dp
implicit none
real(dp), intent(in) :: x
real(dp)             :: sqrt_dp
end function

pure function sqrt_sp(x)
use ncx_precision, only : sp
implicit none
real(sp), intent(in) :: x
real(sp)             :: sqrt_sp
end function

end interface
Then I could define pure functions to use these interfaces:


Code:
pure function sqrt_dp(x)
use ncx_precision, only : dp
implicit none
real(dp), intent(in) :: x
real(dp)             :: sqrt_dp
sqrt_dp = dsqrt(x)
end function

pure function sqrt_sp(x)
use ncx_precision, only : sp
implicit none
real(sp), intent(in) :: x
real(sp)             :: sqrt_sp
sqrt_sp = sqrt(x)
end function
Now, my code compiles and works correctly.

I can use sqrt_gn(9.0_xp) to get the correct square root value for my preferred precision and the code works just fine.



But I have some questions....


QUESTIONS :

+ Is there a better way to do this? <-- MOST IMPORTANT REQUEST

+ Is there any performance loss due to using this indirection through the interface and then to the pure functions?
aerosayan is offline   Reply With Quote

 

Tags
fortran 90, solver deveopment


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Warning message C4133 while compiling Arminius Fluent UDF and Scheme Programming 0 October 2, 2017 11:44
Interpret-Real Gas UDF ndabir Fluent UDF and Scheme Programming 3 November 18, 2015 07:29
Single precision better than double precision? 140raiders CFX 1 July 30, 2015 02:32
Parallel User Defined Real Gas Model aeroman FLUENT 4 July 1, 2015 06:09
Double precision & User Fortran Martijn CFX 3 April 4, 2009 05:43


All times are GMT -4. The time now is 16:42.