- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would like to solve following task: I have got a grid (nCellsY, nCellsZ). Each grid cell can contain no fiber, one fiber ore more fibers. I know in which cell the fibers are. I need to know the indices of the fibers which are in one cell. For example a short list of fibers: fiberInCellY = (/1,5,3,5,4,3,1/) fiberInCellZ = (/1,4,6,1,2,5,1/) I would like to get following: Cell Index of fiber Index of fiber
GridFibers(1,1) 1 7 GridFibers(5,1) 4 GridFibers(4,2) 5 GridFibers(5,4) 2
...and so on...
but with my following code it shows me no index:
PROGRAM run IMPLICIT NONE INTEGER, DIMENSION(7) :: fiberInCellY, fiberInCellZ INTEGER i, j, k, nCellsY, nCellsZ type :: indFibInCell integer, allocatable, dimension(:) :: ind end type indFibInCell type (indFibInCell), allocatable, dimension(:,:) :: Gridfibers fiberInCellY = (/1,5,3,5,4,3,1/) fiberInCellZ = (/1,4,6,1,2,5,1/) nCellsY = 6 nCellsZ = 6 allocate(GridFibers(nCellsY,nCellsZ)) do j=1, nCellsZ do i=1, nCellsY do k=1, 7 if (i == fiberInCellY(k) .and. j == fiberInCellZ(k)) then Gridfibers(i,j)%ind = k print *, "Gridfibers(",i, "," ,j, ")", Gridfibers(i,j)%ind end if end do end do end do END PROGRAM run
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your indFibInCell has ind as allocatable
1) You did not allocate it (them in Gridfibers)
2) Your code does not indicate that it expects it to be allocated
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[fortran]
PROGRAM run
IMPLICIT NONE
INTEGER, DIMENSION(7) :: fiberInCellY, fiberInCellZ
INTEGER i, j, k, l, nCellsY, nCellsZ, guess
type :: indFibInCell
integer, allocatable, dimension(:) :: ind
end type indFibInCell
type (indFibInCell), allocatable, dimension(:,:) :: Gridfibers
fiberInCellY = (/1,5,3,5,4,3,1/)
fiberInCellZ = (/1,4,6,1,2,5,1/)
nCellsY = 6
nCellsZ = 6
allocate(GridFibers(nCellsY,nCellsZ))
guess=10
do j=1, nCellsZ
do i=1, nCellsY
allocate(Gridfibers(i,j)%ind(guess))
l = 0
do k=1, 7
if (i == fiberInCellY(k) .and. j == fiberInCellZ(k)) then
l = l + 1
Gridfibers(i,j)%ind(l) = k
end if
end do
if (l.gt.0) print *, "Gridfibers(",i, "," ,j, ")", Gridfibers(i,j)%ind(1:l)
end do
end do
END PROGRAM run
[/fortran]
output
Gridfibers( 1 , 1 ) 1 7
Gridfibers( 5 , 1 ) 4
Gridfibers( 4 , 2 ) 5
Gridfibers( 5 , 4 ) 2
Gridfibers( 3 , 5 ) 6
Gridfibers( 3 , 6 ) 3
Try this modification. As Jim says, you have not allocated %ind. With F2003 semantics on %ind can be reallocated if it necessary.
By the way. Couldn't this kind of coding 'error' (not allocated element of a type) seen by the compiler at compile time? Missed I something?
Regards,
Johannes
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Jim for you reply,
that is exactly the problem I have. I would like to get a "dynamik ind array". If 3 fibers are in a cell, "ind" should have a length of 3. If a cell contains no fiber, "ind" should have a length of 1 (filled with 0).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Carsten,
that is excatly what you get if you set guess=1 and use F2003 sementics on. You should initialize Gridfibers(i,j)%ind(1)=0
after allocation.Gridfibers(i,j)%ind
will have diffent length in the end.
Regards,
Johannes
ps: OFFTOPIC How can I avoid these ugly blank lines with firefox?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Johannes,
thx for your input! The Code you are posted works well. I added the line "Gridfibers(i,j)%ind=0" after allocation.
Does IND always needs a memory of 10 entries by using guess=10?
I do not understand what you mean with F2003 sementics on!? If I change "guess=1" and "Gridfibers(i,j)%ind(1)=0" I get following error of course: IND has value 2 which is greater than the upper bound of 1.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Carsten,
F2003 semantics are a compiler flag, which turns along other things the automatic right hand side (re)allocation on. This could cause curious errors, if you are not code correctly. I assume that many programmers don't want to turn it on by default.
However, in VS goto properties -> Fortran -> languange -> Enable F2003 sematics and set it to Yes /standard-semantics. Or set in the command line /standard-semantics.
Only then you can set guess=1. If your code requires 2 elements in ind, the array is dynamically extended through 'automatic right hand sinde allocation' (e.g. like in Matlab). If you don't use this, your code will fail with array bound exceeds (if check is turned on).
Best regards,
Johannes
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think you mean reallocate left hand side.
Gridfibers(i,j)%ind(l) = k
The above is a scalar assignment, the F2003 spec says reallocation to shape on right. This would require using
Gridfibers(i,j)%ind(l) = /Gridfibers(i,j)%ind(1:l-1), k/
or something like that to append to the array (if necessary) to apply k into the l'th and last element.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you both for your effort to help me!
With Johannes second code it works!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Carsten,
nice to hear that it works for you. That the other versions did not work encouraged me to find a solution. Here it is:
[fortran]
PROGRAM run
IMPLICIT NONE
INTEGER, DIMENSION(7) :: fiberInCellY, fiberInCellZ
INTEGER :: i, j, k, l, nCellsY, nCellsZ, guess
type :: indFibInCell
integer, allocatable, dimension(:) :: ind
end type indFibInCell
type (indFibInCell), allocatable, dimension(:,:) :: Gridfibers
integer, allocatable :: idummy(:)
fiberInCellY = (/1,5,3,5,4,3,1/)
fiberInCellZ = (/1,4,6,1,2,5,1/)
nCellsY = 6
nCellsZ = 6
allocate(GridFibers(nCellsY,nCellsZ))
guess=1
do j=1, nCellsZ
do i=1, nCellsY
allocate(Gridfibers(i,j)%ind(guess))
l = 0
do k=1, 7
if (i == fiberInCellY(k) .and. j == fiberInCellZ(k)) then
l = l + 1
! --- begin working version 1
! this is working without /assume realloc_lhs
!allocate(idummy(l))
!idummy(1:l-1)=Gridfibers(i,j)%ind(1:l-1)
!idummy(l)=k
!call move_alloc(idummy,Gridfibers(i,j)%ind)
! --- end working verion 1
!
!!Gridfibers(i,j)%ind(1:l) = [Gridfibers(i,j)%ind(1:l-1),k] ! not working
!!Gridfibers(i,j)%ind(l) = k ! also not working
! --- now with /assume realloc_lhs
Gridfibers(i,j)%ind = [Gridfibers(i,j)%ind(1:l-1),k] ! This should work and does
end if
end do
if (l.gt.0) print *, "Gridfibers(",i, "," ,j, ")", Gridfibers(i,j)%ind(1:l)
end do
end do
END PROGRAM run
[/fortran]
The trick is not to use array sections like (:) or (1:l) but to use the whole sub-array as an object. This says the standard F2003. Nevertheless, I prefer the manual way, because it would be easier to track down mysterious errors.
Best regards,
Johannes

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page