(j3.2006) How to assign to the declared-type part of a polymorphic allocatable array?

Van Snyder Van.Snyder
Wed Sep 21 22:57:43 EDT 2016


Is there a way to assign to the declared-type part of a polymorphic
allocatable array, other than one component at a time?

I have a type H_t (for horizontal geolocation) that contains latitude
and longitude.  It's agnostic whether the latitude is geocentric or
geodetic.  It has extensions H_Geoc (for geocentric latitude) and H_Geod
(for geodetic latitude), H_V_t (including a height component V, agnostic
whether geocentric or geodetic), H_V_Geoc (geocentric latitude and
height), H_V_Geod (geodetic latitude and height), and others.

I have an object

  class(h_t), allocatable :: Geo(:)

which I allocate

  if ( geodetic ) then
    allocate ( h_v_geod :: geo(n) )
  else
    allocate ( h_v_geoc :: geo(n) )
  end if

I then want to fill the horizontal geolocations by applying an elemental
type-bound function to an array of a type ZOT_t, from which latitudes
and longitudes are computed.  The type ZOT_t represents a uniform
triangular grid on a (-1:1 X -1:1) square, which is then projected by a
zenitial orthogonal transformation onto a sphere.  The grid is developed
to a specified refinement, without regard to whether latitudes computed
from it will be ultimately interpreted as geocentric or geodetic.
Therefore, the result of the type-bound function ZOT_to_Geo is
type(H_t), not class(H_t).  So after allocating Geo, I'd like to assign
to its horizontal geolocation components using

  geo%h_t = z%ZOT_to_geo()

(size(z) == n) but we've only provided for a parent component, not a
"self" component, so geo%h_t doesn't exist.  I can't use

  geo = z%ZOT_to_geo()

for two reasons.  First, geo is polymorphic.  Second, it has a "v"
component, that I'm not yet ready to fill.

Is there something simpler than this:

  block
    type(h_t) :: T
    integer :: I
    do i = 1, n
      t = z(i)%ZOT_to_geo()
      geo(i)%lat = t%lat
      geo(i)%lon = g%lon
    end do
  end block

Ignoring for a while the "v" component of h_v_geod, I tried

  allocate ( geo, source=h_geod(h_t=z%zot_to_geo()) )

but that doesn't work because structure constructors aren't elemental
(how could they be?).  Maybe I could overload h_geod with an elemental
function; I haven't tried that yet.

I tried

  allocate ( h_geod :: geo, source = z%zot_to_geo() )

but that doesn't work because it has both a type spec and a source.

I did finally make this work, but it seems like a needlessly wordy
kludge:

  allocate ( geo, source = [ ( h_v_geod(h_t=z(i)%zot_to_geo(),v=0), i = 1, n ) ] )

Isn't there something simpler?

[BTW, it doesn't work with ifort 15.0.2.164.  It complains about a
missing field [LAT] not being initialized.  Maybe it's been repaired
already.  I have not yet been able to convince our SA to install the
latest Intel release.]





More information about the J3 mailing list