Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

derived type function assignment

dundar11
Beginner
886 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
886 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
886 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
886 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
886 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