I have a question regarding data type.
I have some big vector: PP,TT,PET. I would like to put them in a data type variable
TYPE::tMACROCELLNODE INTEGER :: nElem REAL(KIND=8),ALLOCATABLE,DIMENSION(:) :: PP REAL(KIND=8),ALLOCATABLE,DIMENSION(:) :: TT REAL(KIND=8),ALLOCATABLE,DIMENSION(:) :: PET
In this way, my code should be easy to develop, to read and to parallelize.
I ask to my self if this type variable, with very big data, could create some problem.
I do not know, stability, speed ecc ecc.
Thanks to all of you
TYPE tMACROCELLNODE INTEGER :: nElem REAL(KIND=8),ALLOCATABLE,DIMENSION(:) :: PP REAL(KIND=8),ALLOCATABLE,DIMENSION(:) :: TT REAL(KIND=8),ALLOCATABLE,DIMENSION(:) :: PET END TYPE tMACROCELLNODE TYPE tYourEnclosingType ... ! other sturr TYPE(tMACROCELLNODE) :: MacroCellNode ... ! other stuff END TYPE tYourEnclosingType ... TYPE(tYourEnclosingType) :: diedro ! an instance ! CODE ... diedro%MacroCellNode%nElem = WhatYouWant ALLOCATE(diedro%MacroCellNode%PP(WhatYouWant)) diedro%MacroCellNode%PP = 0.0_8 ...
You should look at Type-Bound Procedures
It is probably best to look for some examples as the IVF compiler documentation is rather skimpy on this.
Dear Jim , Dear all,
I am quite new with data tytpe.
I do not understand the difference between my "type" and your "type".
Could you explain me? What do you mean for "IVF compiler"?
Thanks a lot
The :: format is generally used with type declarations containing an attribute list.
The :: is optional when the type declaration does not contain an attribute list.
Your code sample did not include the END TYPE tMACROCELLNODE
So it was unclear as to if that were the problem or not.
Additionally, an omission in my code was explicit enough information as to where the TYPE declarations were made (I make assumptions too).
Do the PP, TT and PET components all get allocated to the same size? Is nElem that size?
If so, then storing nElem may be superfluous, you can just get the size of the component arrays using the size intrinsic.
If so alternatively, you could use parameterized derived types, perhaps making nElem a length type parameter.
(In the following, for the sake of example, I have also pulled out the real kind parameter of the components to a type parameter - perhaps that's not necessary - in which case rk could instead just be an ordinary named constant.)
TYPE::tMACROCELLNODE(rk,nElem) INTEGER, KIND :: rk INTEGER, LEN :: nElem REAL(KIND=rk),DIMENSION(nElem) :: PP REAL(KIND=rk),DIMENSION(nElem) :: TT REAL(KIND=rk),DIMENSION(nElem) :: PET ... END TYPE tMACROCELLNODE TYPE(tMACROCELLNODE(8,100)) :: my_node DO i = 1, my_node%nELem my_node%PP(i) = ...
In general, if the components PP, TT and PET are closely related to each other and are commonly manipulated together, then bundling them together in a derived type usually is a sensible thing to do. A writer/reader of the source code only has to worry about passing one thing around that describes the properties of a node (or whatever), not three or more.
You may also want to think about how these arrays are accessed and consider whether you want SOA (Strucure of Arrays, as you have), or AOS (Array of Structures). If you'll always be accessing the same indexed element of each array for each "step" of your algorithm, AOS is more efficient since the memory accesses are closer together. There's also less indirection through the allocatable array descriptors.
That is neat and useful for smallish nElem values. Very large array sizes should be allocated from the heap (via type contained procedure).
BTW, is END TYPE implicit???
There you go - all fixed now.
If having a large object stored on the stack is of concern (which is reasonable), you can make the object itself allocatable. This is something that you might do anyway, if the number of elements for the arrays is not known at compile time.
TYPE(tMACROCELLNODE(8,:)), ALLOCATABLE :: my_node INTEGER :: my_length ! read my_length from a file or whatever. ALLOCATE(tMACROCELLNODE(8,my_length) :: my_node) ...
First of all, really really thank. I am learing a lot.
In both cases (SOA and AOS), there is no stability problem, am I right?
SOA is slower to access, am I right?
This is my example:
TYPE::tMACROCELLNODE INTEGER :: nElem INTEGER :: AA INTEGER :: IDnode INTEGER :: IDmCell REAL(KIND=8),ALLOCATABLE,DIMENSION(:) :: WFX REAL(KIND=8),ALLOCATABLE,DIMENSION(:) :: WFY ! REAL(KIND=8),ALLOCATABLE,DIMENSION(:) :: WFtime REAL(KIND=8),ALLOCATABLE,DIMENSION(:) :: WFpdf ! REAL :: qs ENDTYPE TYPE(tMACROCELLNODE) ,ALLOCATABLE,DIMENSION(:) :: MACROCELLNODE
This what I do:
and in a cycle
OPEN(1,file=read_file_name,STATUS='old', ACTION='read',IOSTAT=IERR) DO i=1,npairs READ(1,*) MACROCELLNODE(i)%IDnode,MACROCELLNODE(i)%IDmCell .... .... .... READ(1,*) n, nmacronode n=n+1 MACROCELLNODE(i)%nElem = n AA = nmacronode*ADEM MACROCELLNODE(i)%AA = AA ! ALLOCATE(MACROCELLNODE(i)%WFX(n)) ALLOCATE(MACROCELLNODE(i)%WFY(n))
This because "n" changes.
Is this correct?
Because I do not think that I can do
PP, TT and PET have the same number of element, consequently I will use AOS.
What do you think? Have I done some errors?
Do you have some suggestions?
Really really thanks again