Kyle_S-C
Kyle_S-C

Reputation: 1177

Undefined components of a derived type in Fortran

This is more a software design question than a technical problem.

I planned to use a derived type to define atomic configurations. These might have a number of properties, but not every type of configuration would have them all defined.

Here's my definition at the moment:

type config
  double precision                            :: potential_energy
  double precision                            :: free_energy
  double precision, dimension(:), allocatable :: coords
  integer                                     :: config_type
end type config

So, in this example, we may or may not define the free energy (because it's expensive to calculate). Is it safe to still use this derived type, which would be a superset of sensible cases I can think of? Should I set some sort of default values, which mean undefined (like Python None or a null pointer)?

I know about the extends F2003 feature, but I can't guarantee that all of our compilers will be F2003-compliant. Is there another better way to do this?

Upvotes: 1

Views: 213

Answers (2)

IanH
IanH

Reputation: 21451

Formally, operations that require the value of the object as a whole when one of its components are undefined, are prohibited (see 16.6.1p4 of the F2008 standard).

Practically you may not run into issues, but it is certainly conceivable that a compiler with appropriate debugging support might flag the undefined nature of the component when operations that require the entire value of the derived type object are carried out.

High Performance Mark's suggestion is a workaround for that, because a derived type scalar still has an "overall" value even if one of its allocatable components is not allocated (see 4.5.8). This suggestion might be useful in cases where the component is heavy in terms of memory use or similar.

But a single double precision component isn't particularly heavy - depending on the platform the descriptor for an allocatable scalar component may be of similar size. An even simpler workaround is to just give the component an arbitrary value. You could even use default initialization to do just that.

(Presumably you have some independent way of indicating whether that component contains a useful value.)

Upvotes: 2

High Performance Mark
High Performance Mark

Reputation: 78364

These days Fortran comprehends the concept of allocatable scalars. Like this:

type config
  double precision                            :: potential_energy
  double precision, allocatable               :: free_energy
  double precision, dimension(:), allocatable :: coords
  integer                                     :: config_type
end type config

If, however, you can't rely on having a Fortran 2003 compiler available this won't work. But such compilers (or rather versions) are becoming very scarce indeed.

But do go the whole hog, and drop double precision in favour of real(real64) or some other 21st century way of specifying the kind of real numbers. Using the predefined, and standard, constant real64 requires the inclusion of use iso_fortran_env in the scoping unit.

Upvotes: 2

Related Questions