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

type variable + allocatable

diedro
Beginner
2,768 Views

Dear all,

I have a question. I have a type variable and I would like if it is possible to allocate it.

I mean, this is the variable:

type LPARTint
      integer                       :: value
      real,allocatable,dimension(:) :: QQ
      real,allocatable,dimension(:) :: RP
      type(LPARTint), pointer :: next => null()
      type(LPARTint), pointer :: prev => null()
end type LPARTint

I would like to know if this variable is correct.

The second things, How I can allocate QQ and RR?

I sort of allocate(LPARTint%QQ(nVar)), because nVar is constant in all the program.

Thanks again

Thanks  a lot

0 Kudos
19 Replies
mecej4
Honored Contributor III
2,768 Views

There is nothing special that you need to do beyond what you described. Secondly, nVar does not have to be a constant. In fact, the extent of the arrays allocated can be any integer expressions. Perhaps the following code, which gets compiled successfully, will clarify.

subroutine lp
type LPARTint
      integer                       :: value
      real,allocatable,dimension(:) :: QQ
      real,allocatable,dimension(:) :: RP
      type(LPARTint), pointer :: next => null()
      type(LPARTint), pointer :: prev => null()
end type LPARTint

type(LPARTint), target :: lprt(2)
integer :: i1=2,i2=3

allocate(lprt(1)%QQ(i1),lprt(1)%RP(i1), &
         lprt(2)%QQ(i2),lprt(2)%RP(i2))
lprt(1)%value=15
lprt(2)%value=20
lprt(1)%next => lprt(2)
lprt(2)%prev => lprt(1)
end subroutine lp

 

0 Kudos
diedro
Beginner
2,768 Views

Dear mecej4, Dear all,

Actually nVar is costant. I would like to avoid to allocate type every time.

I mean, I would like a sort of:

type LPARTint
      integer                       :: value
      real,                           :: QQ(4)
      real                            :: RP(2)
      type(LPARTint), pointer :: next => null()
      type(LPARTint), pointer :: prev => null()
end type LPARTint

What do you think?

Thanks again

0 Kudos
mecej4
Honored Contributor III
2,768 Views

Your narration is confusing. If, as you said in #3, you "would like to avoid to allocate type every time", why did you declare QQ and RP to be allocatable in #1? As to "What do you think?", I don't think that you can expect an answer, because you have not given us any information about how you propose to use this user-defined-type, and why you have misgivings about it. The declaration is certainly valid Fortran, but whether the structure of this type is a good fit with the intended application depends on what kinds of processing is to be performed in the application, the nature of the algorithms used, etc.

0 Kudos
diedro
Beginner
2,768 Views

Dear mecej4 , Dear all,

I am sorry, I will try to explain better.

My program run some simulations. These could be two dimensional or three dimensional -> di=2 or di=3.

These simulations could have 2,3,4,5 variables: nVar=2,nVar=3,nVar=4,nVar=5.

The program reads these in a input file. After reading di and nVar I would like to do:

type LPARTint
      integer                       :: value
      !
      real,                           :: QQ(nVar)
      real                            :: RP(di)
      !
      type(LPARTint), pointer :: next => null()
      type(LPARTint), pointer :: prev => null()
      !
end type LPARTint

What do you think?

Is it possible?

Thank again and sorry again. 

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,768 Views

>> These could be two dimensional or three dimensional -> di=2 or di=3.
>>>...
>>real :: RP(di)

In the above, RP is a one dimensional array with either 2 or 3 elements.

Perhaps this is a case of "lost in translation".

Is the type LPARTint, representing a particle that, depending on simulation, could represent a particle in 2 dimensional space or 3 dimensional space?

If so, then RP is properly described as an array of coordinates, or colloquially, an array of dimensions. For the physics of your simulation the array QQ are also dimensions of the particle: position, velocity, acceleration, mass, charge, temperature, whatnot, ... (position is presumably in RP).

Jim Dempsey


 

 

 

0 Kudos
mecej4
Honored Contributor III
2,768 Views

In lines 4 and 5, the upper bounds should be given as "initialization expressions". So, no, you cannot use variables in those contexts. You can make QQ and RP allocatable arrays as in #1, or you can create different types for each combination of di and nVar. For example, you can declare type LPARTint23 as in #5 for di=2, nVar=3, and so on.

0 Kudos
diedro
Beginner
2,768 Views

Dear all,

what's a shame :)

Thanks a lot, I will try to think to another strategy.

Again, Thanks a lot

 

0 Kudos
IanH
Honored Contributor III
2,768 Views

mecej4 wrote:

In lines 4 and 5, the upper bounds should be given as "initialization expressions". So, no, you cannot use variables in those contexts. You can make QQ and RP allocatable arrays as in #1, or you can create different types for each combination of di and nVar. For example, you can declare type LPARTint23 as in #5 for di=2, nVar=3, and so on.

The bounds of a component have to be specification expressions.  In terms of the example, that may permit use of length type parameters if all the elements in a particular array have the same bounds for a particular component.

TYPE :: LPARTint(nvar, di)
  INTEEGR, LEN :: nvar, di
  REAL, DIMENSION(nvar) :: QQ
  REAL, DIMENSION(di) :: RP
  TYPE(LPARTint(:,:)), POINTER :: next => NULL()
  TYPE(LPARTint(:,:)), POINTER :: prev => NULL()
END TYPE


TYPE(LPARTint(:,:)), ALLOCATABLE :: some_array(:)
READ (some_unit, "(I10,I10)") nvar, di
ALLOCATE(LPARTint(nvar, di) :: some_array(xxx))

! Now all elements of some_array have a component QQ 
! that has an upper bound of the value of nvar, and 
! all elements have a component RP that has an upper 
! bound of di.

Whether this is appropriate or not might depend on details not specified.

(The next and prev pointer components can point to objects that have different length parameters.)

0 Kudos
mecej4
Honored Contributor III
2,768 Views

The feature used in IanH's suggestion, "parameterized derived types", was added recently to Intel Fortran (IanH often rides the wave of the present :-) ). See the feature matrix presented at http://fortranwiki.org/fortran/show/Fortran+2003+status regarding support for this feature in other compilers.

0 Kudos
IanH
Honored Contributor III
2,768 Views

mecej4 wrote:

(IanH often rides the wave of the present :-) )

Waves have a habit of reaching shallow water and dumping their riders in the surf.  But that's part of the fun.

As with many new features, it may be a major release or two before their implementation in compilers is robust, but beyond that point I think the antipathy towards length parameterized derived types is a little harsh - they are quite neat for this sort of use case (if my understanding of the use case is correct).

(I think additional language evolution will be required before kind parameterized derived types will be particularly useful, but hopefully we'll get there one day.)

0 Kudos
diedro
Beginner
2,768 Views

Dear all,

I did this simple program:

PROGRAM TEST
IMPLICIT NONE
INTEGER :: di,nVar

TYPE :: LPARTint(nVar, di)
  INTEGER, LEN :: nVar, di
  REAL, DIMENSION(nVar) :: QQ
  REAL, DIMENSION(di) :: RP
  TYPE(LPARTint(:,:)), POINTER :: next => NULL()
  TYPE(LPARTint(:,:)), POINTER :: prev => NULL()
END TYPE

TYPE(LPARTint(:,:)), ALLOCATABLE :: some_array

ENDPROGRAM

And I got some errors when I compile it.

Does this mean that I am using a too old version of INTEL FORTRAN COMPILER?

Thanks again

0 Kudos
Lorri_M_Intel
Employee
2,768 Views
Parameterized derived types were added in 15.0. What version are you running? --Lorri
0 Kudos
diedro
Beginner
2,768 Views

Dear all,

I belive composer_xe_2013.5.192, is it too old?

0 Kudos
mecej4
Honored Contributor III
2,768 Views

Yes, that version is too old. Compiler version 15.0.1.148 compiles your program with no messages.

0 Kudos
diedro
Beginner
2,768 Views

Dear all,

there is no more intel linux free for non commercial purpouse:

https://software.intel.com/en-us/non-commercial-software-development   :(

Am I right?

0 Kudos
Steven_L_Intel1
Employee
2,768 Views

That is correct.

0 Kudos
diedro
Beginner
2,768 Views

Dear all,

noooooo   :(

what's a shame :)

0 Kudos
mecej4
Honored Contributor III
2,768 Views

Diedro, please see https://software.intel.com/en-us/intel-education-offerings#pid-2460-93 if you are a student and having the C++ compiler +MKL and other libraries will meet your needs.

If you must use Fortran and/or not a student, and if you qualify for "academic" status, there are some reasonably priced packages offered there.

The recently changed policy is probably undergoing evaluation and may change again.

0 Kudos
diedro
Beginner
2,768 Views

Dear all,

I have just finished my PhD, so I not a student anymore. Now, I am looking to some positions in academic and I would like to write some research project. If I will get some money I'll let you know......fingers crossed.

About Intel policy: Most of my friends use intel fortran in Windows. Having a free intel fortran comiler in LINUX means that people will buy an intel proecessor and it is a good debugging for windows fortran.

Thanks again

 

 

0 Kudos
Reply