I want to know how to get fortran to return values

Hi all,
I would like to know how I can get a Fortran function to return one or two values. More specifically the f_b_check and f_c_check values.

Thanks

module reaction_calculation
  use OMP_LIB
  implicit none
  real :: q_check, f_b_check, f_c_check, l_b_check, l_c_check,l, dist_deflection_b,dist_deflection_c,reactionb_deflection,reactionc_deflection,total_deflection_b, total_deflection_c
  real,allocatable :: f_b_check_array(:),f_c_check_array(:)

  integer :: i, j
  


contains
  function reaction_b_c(f_b_check,f_c_check,l_b_check,l_c_check,l,q_check)

    allocate(f_b_check_array(4*q_check*l))
    allocate(f_c_check_array(4*q_check*l))

    !$OMP PARALLEL
    !$OMP DO
    do i = 1:4*q_check*l
       f_b_check_array(i) = (i/4.0)
       f_c_check_array(i) = (i/4.0)
    end do
    !$OMP END DO
    !$OMP END PARALLEL

     dist_deflection_b = -((q_check*(l_b_check**2))/24)*((6*(l**2))-(4*l*l_b_check)-(l_b_check**2))
     dist_deflection_c = -((q_check*(l_c_check**2))/24)*((6*(l**2))-(4*l*l_c_check)-(l_c_check**2))

    !$OMP PARALLEL
    !$OMP DO

    do i = 1:4*q_check*l
       do j = 1:4*q_check*l
          reactionb_deflection = (((f_b_check_array(i)*(l_b_check**2))*((3*l_b_check)-l_b_check))/6) +  (((f_c_check_array(j)*(l_b_check**2))*((3*l_c_check)-l_b_check))/6)
          reactionc_deflection =  (((f_b_check_array(i)*(l_b_check**2))*((3*l_c_check)-l_b_check))/6) + (((f_c_check_array(j)*(l_c_check**2))*((3*l_c_check)-l_c_check))/6)
          total_deflection_b = dist_deflection_b + reactionb_deflection
          total_deflection_c = dist_deflection_c + reactionc_deflection
          !$OMP CRITICAL
          if (total_deflection_b == 0 .and. total_deflection_c == 0) then
             f_b_check = f_b_check_array(i)
             f_c_check = f_c_check_array(j)
          end if
          !$OMP END CRITICAL
       end do
    end do
    
    !$OMP END DO
    !$OMP END PARALLEL

    deallocate(f_b_check_array)
    deallocate(f_c_check_array)

  end function reaction_b_c
  


end module reaction_calculation
1 Like

One way is to wrap them in an array:

module Return
    implicit none
    integer, parameter :: dp = kind(1.d0)

    contains
        function f(x)
            real(dp) :: x, y1, y2
            real(dp) :: f(2)
            y1 = x + 1_dp
            y2 = x + 2_dp
            f(1) = y1
            f(2) = y2
        end

end module Return

program main
    use Return
    real(dp) :: y(2)
    y = f(0.0_dp)
    y1 = y(1)
    y2 = y(2)
    print *, y1, y2
end program main

Is there a better way?

(side question: is there a syntax like

real(dp), dimension(2) :: function f(x)

to declare the type of the output in the function definition itself?)

do i = 1:4*q_check*l
Does this work in Fortran? Looks like Matlab and R syntax.

absolutely,
tried this code as an example and it works:

program do_loop_test
  implicit none

  integer :: i
  integer, parameter :: k = 10


  do i = 1,(10*k)/2
     print *, i
  end do


end program do_loop_test

Depends a bit on context which is preferable, but you could define a derived type and return that from a function,

type :: my_t
  real :: a, b
end type

function return_two(a, b) result(combined)
  real, intent(in) :: a, b
  type(my_t) :: combined

  combined%a = a
  combined%b = b
end function

or use a subroutine with multiple intent(out) arguments

subroutine return_two(a, b)
  real, intent(out) :: a, b

  a = 1.0
  b = 2.0
end subroutine
2 Likes