2

I have a subroutine that I use for root-finding. One of the inputs of the subroutine is the name of an objective function, which inside the subroutine is declared as an interface. I use this root-finding subroutine for several objective functions in my main program. So ideally, when the subroutine fails in solving the problem, I would like to see the name of the function for which it failed. Is this possible?

This is an example code

subroutine mysolver(xl,xr,FN, x_sol)
    real, intent(inout)       :: xl,xr
    real, intent(out)         :: x_sol
    real                      :: fl,fr
    interface
        real function FN(y)
            real, intent(in)           :: y
        end function FN
    end interface
    fl = FN(xl)
    fr = FN(xr)
    if (fl*fr > 0.0) then
        print *, 'Error solving function'
    end if
        
    ! More (non-relevant) stuff happens here        
end subroutine mysolver

When the solver fails, i.e. when fl*fr>0, the subroutine prints "Error solving function", but I would like it to print "Error solving function FN", for whatever FN is. How can I achieve this?

Looper
  • 352
  • 2
  • 15
  • The linked question may not immediately jump out as being relevant: it's mostly explaining how an entire class of functionality is not available to you as a Fortran programmer. This includes querying what a particular actual argument entity (variable, procedure, etc.) may be called. (Inside `mysolver` the procedure `FN` has name `FN`, but actual argument when calling `mysolver` may be `func` and that same procedure can have many other names, such as `sub123` as the ultimate argument.) – francescalus Jul 06 '22 at 15:39
  • 1
    A potential workaround: instead of passing `FN` functions around directly, pass around objects of a type that thas an `FN` type-bound function, and a `name` variable. – veryreverie Jul 06 '22 at 19:07
  • 1
    `FN` only gives a function interface, but you can always pass a `character(*)` variable as a name: `subroutine mysolver(xl,xr,FN,x_sol,whereAt)` with `character(*), intent(in) :: whereAt` so that later you can `print "('mySolver at ',a,': Error solving function')", whereAt` – Federico Perini Jul 07 '22 at 08:08
  • Thanks, @veryreverie @Federico Perini. Passing `FN` name as an additional character input is a good way of circumventing this problem. – Looper Jul 08 '22 at 16:26

0 Answers0