- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am writing a program that loops through a file with many instances of data taken at different times. I use a derived data type to create the linked list. See the code below.
module types
type
:: wavedatreal, dimension(:, :) :: espt real :: winddir real :: windspeed real :: time
type (wavedat), pointer :: p
end type wavedat
end module
typesSo I then have a module that reads in a data file and gets values for winddir, windspeed, and time. The value for wavedat%espt is given inReadOWI by the transpose of spec2d. Spec2d is a rank-2 array of size (nfreq,nang).How can I initialize wavedat%espt to dimension(nfreq,nang)?
module
ReadOWI containssubroutine
OWI(freqz,owidat)use
types integer :: OPEN_STATUS,yr,mo,da,hr,mm,nfreq,nang,countreal
:: TWD,U10,stime,depreal
, allocatable, dimension(:,:) :: dummy,spec2dreal
, allocatable, dimension(:), intent(out) :: freqzreal
, allocatable, dimension(:) :: thetadtype
(wavedat), pointer :: tailtype
(wavedat), pointer :: headtype
(wave dat), pointer :: ptrtype
(wavedat), allocatable, dimension(:), intent(out) :: owidat !Initialize loop countcount = 0
!Open file for read only open(UNIT=2,FILE=sample.asc,STATUS='OLD',&ACTION='READ',IOSTAT=OPEN_STATUS)
if(OPEN_STATUS>0)STOP "----Error, File not opened properly-----" ! This section reads in the number of frequencies and directions (angles) read(2,'(11X,I,12X,I)'), nfreq,nang !These values define size of owidat%espt read(2,'(A)') !Blank Line !Now allocate dimensions to arrays allocate (freqz(nfreq)) allocate (thetad(nang)) allocate (spec2d(nang,nfreq)) allocate (dummy(nang,nfreq+1)) ! Main loop docount = count+1
if (count == 1) then read(2,'(64X,F9.4)'),dep !Depth else read(2,'(A)') !First Header Line end if read(2,'(A)') !Second Header Line !Now read year, month, day, hour, minute, wind direction, and wind speed read(2,'(1X,I4,I2,1X,3I2,7X,F6.1,F7.3)'),yr,mo,da,hr,mm,TWD,U10 read(2,'(A)') !Fourth Header Line read(2,'(7X)',ADVANCE='NO') !Unwanted Charactersstime = datenum(yr,mo,da,hr,mm)
!Serial date number !Read in the frequencies to vector freq if (count==1) then do p=1,nfreqread(2,'(F7.4)',ADVANCE='NO') , freqz(p) end do end if !Read directions and spec2d data to 'dummy' variable do k=1,nang
read(2,'(A)') do j=1,nfreq+1 if (j==1) then
read(2,'(F7.2)',ADVANCE='NO'),dummy(k,j) else
read(2,'(F7.4)',ADVANCE='NO'),dummy(k,j) end if end do end do !Sort Directions and spectrum
dummy = Sort(dummy,nang,nfreq+1)
!Sorted Directions vectorthetad = dummy(:,1)
!Rotate spectrum angles to direction 'From'spec2d(1:(nang/2),:) = dummy((nang/2)+1:nang,2:nfreq+1)
spec2d((nang/2)+1:nang,:) = dummy(1:nang/2,2:nfreq+1)
read(2,'(A)',IOSTAT=OPEN_STATUS) !Blank Line !Update owidat structure with this observation if (.NOT. ASSOCIATED(head)) then
allocate (head,STAT=istat)
! allocate (head%espt(nfreq,nang))
tail => head
nullify (tail%p)tail%espt =
transpose(spec2d)tail%winddir = TWD
tail%windspeed = U10
tail%time = stime
elseallocate(tail%p,STAT=istat)
tail => tail%p
nullify (tail%p)tail%espt =
transpose(spec2d)tail%winddir = TWD
tail%windspeed = U10
tail%time = stime
end if !End loop at the end of fileend do !Determine if loop terminated because of a READ error or the end of the input file if (OPEN_STATUS>0) then print *,'An Error Occurred While Reading File' else print *,'End of file Reached' end if
allocate
(owidat(count))ptr => head
do
i=1,countowidat(i)%espt = ptr%espt
owidat(i)%winddir = ptr%winddir
owidat(i)%windspeed = ptr%windspeed
owidat(i)%time = ptr%time
ptr => ptr%p
end do
close
(2)end subroutine
OWIend module ReadOWI
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
bobfrat@gmail.com:
module types
type :: wavedat
...real, dimension(:, :) :: espt
This last line is a syntax error, and you need either ALLOCATABLE or POINTER attribute for espt...
bobfrat@gmail.com:
!Update owidat structure with this observationif (.NOT. ASSOCIATED(head)) then
allocate (head,STAT=istat)
! allocate (head%espt(nfreq,nang))
...and if you uncomment the last line, it should work as expected. Or am I missing something?
I didn't look to carefully at the rest of the code; offhand, I'd say that you don't need spec2d array, as you can do all the operations with espt, so you can avoid one transposition/copying.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
module types
type :: wavedat
real, allocatable, dimension(:, :) :: espt
And when I uncomment the line
allocate (head%espt(nfreq,nang))
something doesn't work. I know that it works up until
allocate (owidat(count))
ptr => head
do i=1,count
owidat(i)%espt = ptr%espt
This last line doesn't work, so I tried inserting the following...
allocate (owidat(count))
allocate (owidat%espt(nfreq,nang))
ptr => head
do i=1,count
owidat(i)%espt = ptr%espt
But this produces the following error... "The part-name to the right of a part-ref with nonzero rank has the ALLOCATABLE attribute (6.1.2) [ESPT]- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The cleanest way to solve the problem is to allocate espt at the moment when you create the parent type. In the code above, that would be after you ALLOCATE(tail%p).
Actually, I'd say that your code should crash at this line (because tail%espt is not ALLOCATEd):
tail%espt = transpose(spec2d)
And it likely would if you use /check:pointer.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
if (.NOT. ASSOCIATED(head)) then
allocate (head,STAT=istat)
allocate (head%espt(nfreq,nang))
but not when it is a variable?
allocate (owidat(count))
allocate (owidat%espt(nfreq,nang))
The program will run without error (without the previous allocate statement), just without any data in owi%espt. However, the data in owi%winddir, owi%windspeed, and owi%time comes out just fine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
if (.NOT. ASSOCIATED(head)) then
allocate (head,STAT=istat)
allocate (head%espt(nfreq,nang))
tail => head
nullify (tail%p)
tail%espt = transpose(spec2d)
tail%winddir = TWD
tail%windspeed = U10
tail%time = stime
else
allocate(tail%p,STAT=istat)
tail => tail%p
****allocate (tail%espt(nfreq,nang))
nullify (tail%p)
tail%espt = transpose(spec2d)
tail%winddir = TWD
tail%windspeed = U10
tail%time = stime
end if
And also...
allocate (owidat(count))
ptr => head
do i=1,count
if (.NOT. ASSOCIATED(ptr)) EXIT
**allocate (owidat(i)%espt(nfreq,nang))
owidat(i)%espt = ptr%espt
owidat(i)%winddir = ptr%winddir
owidat(i)%windspeed = ptr%windspeed
owidat(i)%time = ptr%time
ptr => ptr%p
end do
Thanks for the help Jugoslav!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A side note: your original code (without the last changes) would work as desired under the Fortran 2003 standard -- %espt component would get automatically allocated (or re-allocated) to the shape of the right-hand expression (transpose(spec2d) or ptr%espt respectively). However, that semantics is not enabled by default in IVF 10.1 -- you need to use /assume:realloc_lhs switch (check the documentation) -- it's very new though, and it doesn't even exist in the Project Settings dialog; that's why I avoided mentioning it initially.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page