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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With