Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs have moved to the Altera Community. Existing Intel Community members can sign in with their current credentials.

derived type function assignment

dundar11
Beginner
754 Views
Hi,
I am trying to employ data hiding technique for my code. To modify the data of derived type I write a function as a derived type procedure. For example I want to store coordinates of atoms in a one dimensional array:
type my_type
integer :: natoms
real :: positions(3*natoms)
...
contains
procedure :: coordinates
....
end type
function coordinates(iatom) result( coords)
class(my_type) :: this
real :: coords(3)
coords=this%positions( (iatom-1)*3+1 : iatom*3)
end function
this works fine and when I want to retrieve positions I just use structure%coordinates(iatom) and have positions of iatom.
My question is how can I do same logic for setting positions. I would like to write something like
structure%coordinates(iatom,:)= (/3.2,2.3,3.1/)
the idea here rest of the code will work like there is an array coordinates(natoms,3) and stored all positions there. But infact it would be just a one dimensional array to save time and RAM space.
Thanks in advance.
0 Kudos
4 Replies
oleglebedev
New Contributor I
754 Views
Hi,
You should add a set-method. I mean
[fortran]type my_type
  integer :: natoms
  real :: positions(3*natoms)
!...
 contains
 procedure :: get => coordinates_fn
 procedure :: set => setCoordinates_sub
!...
end type
!...
!...
 function coordinates_fn(iatom) result( coords)
 class(my_type) :: this
 real :: coords(3)
  coords=this%positions( (iatom-1)*3+1 : iatom*3)
 end function coordinates_fn
! subroutine setCoordinates_sub(this, iatom, coord) implicit none class(my_type) :: this real, dimension(3), intent(IN) :: coord this%positions(iatom) = coord return end subroutine setCoordinates_sub !...[/fortran]
Oleg.
0 Kudos
dundar11
Beginner
754 Views
Thats also works but I am looking for something different. Oleg's implementation will work
call my_type%set(iatom,vec)
but I want to assign vec to position of iatom by doing:
my_type%set(iatom)=vec
is that possible?
It will be easier to read from file if I could do this i.e.:
read(12,*) iatom, my_type%set(iatom)
dundar.
0 Kudos
Steven_L_Intel1
Employee
754 Views
You'll never be able to do it in the READ as you suggest - the semantics aren't there. The closest you can come in the language to the assignment is if function set returns a pointer - Fortran 2008 allows a pointer-valued function on the left side of an assignment. This is not yet supported by Intel Fortran.
0 Kudos
oleglebedev
New Contributor I
754 Views
Dundar,
I misprinted in my method. I mean
[fortran]! corrected
subroutine setCoordinates_sub(this, iatom, coord)  
 implicit none
 class(my_type) :: this
 integer, intent(IN) :: iatom
 real, dimension(3), intent(IN) :: coord
! coords=this%positions( (iatom-1)*3+1 : iatom*3)  ! it`s your get-method
! and it is the set-method which sets the vector coord to this-type
 this%positions( (iatom-1)*3+1 : iatom*3 ) = coord(1:3) ! look here
 return
 end subroutine setCoordinates_sub[/fortran]
You should include thedescription of 'my_type' and set//get-methods into module (for example, call it my_module)
You can use it typing
[fortran]program main
!...
use my_module
type(my_type) :: t
real, dimension(3) :: coord
integer :: iatom
! ...
! you can write 'set' using set => setCoordinates_sub  
call t%set(iatom, coord)
!
end program[/fortran]
PS
You`d better make
[fortran]module my_module

public :: set, get
PRIVATE
!...

type, public :: my_type
  PRIVATE
  integer :: natoms  
  real :: positions(3*natoms)  
!...  
 contains  
 procedure :: get => coordinates_fn  
 procedure :: set => setCoordinates_sub  
!...  
end type
!
contains
!...
subroutine setCoordinates_sub(this, iatom, coord)
!...
function coordinates_fn(iatom) result( coords)
!...

end module my_module[/fortran]
Good luck.
Oleg
0 Kudos
Reply