A good OOP design for a solver with modern Fortran

fortran, fortran2003, oop

Solution

I've been working with the OO features of Fortran for a year or so now, here are some extended comments masquerading as an answer.

If you are simply concerned with raw execution speed then you are probably, in general (and based on argument and my experience rather than data), better to steer clear of the OO features; but then in many cases the same argument can be made that you are better to steer clear of anything added to the language after FORTRAN77.

Arguments in favour of OO are stronger when founded on the issues of code design, comprehensibility, extendibility, that sort of thing. If these matter to you then you should be thinking about using the OO features.

As Vladimir has already commented, there doesn't seem to be much point in using the variable pointer. Don't forget that most Fortran implementations do call-by-reference specifically to avoid the effort of copying (large volumes of) data around.

Personally, I don't like the way you have defined your type-bound procedure `create`. I much prefer to implement that sort of operation as a function, so that I can write lines like this:

t = solver%new()

rather than your

call T%create()

Note this is a preference of mine, and it's more a question of style than of efficiency or correctness. I notice that you haven't declared the intents of the arguments to the subroutine `create`; perhaps because you've only posted a snippet of your code.

Because OO is relatively new to Fortran (and, arguably, relatively unfamiliar to most people working in the domains where Fortran is widely used) there isn't much useful material to guide us in adopting it. I would recommend Scientific Software Design. It gives the topic decent coverage and makes the argument about why scientific and engineering programmers should adopt OO.

Problem

I am designing a Fortran code for solving a PDE system. The way it is designed right now is that I have a type `Variable` that has several attributes, the most important of which is the array `val` that stores the value. Now I also have a `solver` class, which would perform calculations on a `variable`. I figured that passing the whole `variable` to the solver and working with `variable%val` each time I want to run it (several thousands of times during an exectution) would be inefficient, so I decided to to define pointer fields in the `solver` class to bind the to solver to the appropriate variable. For example ``` program example use variable use solvers type(Variable) T type(Solver) solver_temperature !Contructors call T%create() call solver_temperature%create(T) call solver_temperature%solve() end program example ``` And the solver module ``` module solvers type Solver real*8, pointer :: T(:,:) contains procedure :: create procedure :: solve end type contains subroutine create(this,T) type(Solver) :: this type(Variable) :: T this%T => T%val end subroutine end module ``` In my program I define different variable for different physical properties and different solvers that are associated with those variables in the way I showed above. I am new to OOP in general, so my question is if that is a decent design? Especially from a performance point of view. How does this compare with making `T` just an array and passing it to a subroutine `solve` in terms of speed? Is there some regular way to do this?

Original source