[Nek5000-users] size of arrays and declaration of variables

nek5000-users at lists.mcs.anl.gov nek5000-users at lists.mcs.anl.gov
Tue Jun 3 03:51:11 CDT 2014



Hi Emmanuel,

f77 passes arrays by address -- i.e., it passes a pointer to the element
of the array listed, or to the first one if no array index is indicated
in the call.  There is no concept of passing a whole array or just part of one
--- you simply pass the pointer to the first element of the array, e.g., as in
"call blah(ta)"  or to some other element of the array "call blah(ta(1,1,1,e))"
which, in this case, would pass the pointer to the e-th element of ta.

Moreover, in f77, the declaration

    real x(3,4)

implies that x(2,k) comes immediately after x(1,k) in memory (whereas
x(k,3) is _not_ next to x(k,2).)

Common usage in Nek is therefore to view the block

    x(1,1,1,e),x(2,1,1,e),...,x(lx1,ly1,lz1,e)

as an "element"   All of these variables are adjacent in
memory, assuming that the array index sizes are (lx1,ly1,lz1)
for the first three indices.  Given that they are adjacent,
we can pass one element at a time to a routine (but really,
we're just passing a pointer to the "e"th block) via

     integer e

     do e=1,nelv
        call blah(x(1,1,1,e))
     enddo

In a case where we operate on an entire field, i.e., all
elements, it suffices to just pass the pointer to the whole
array, as in:

      n=nx1*ny1*nz1*nelv
      call rzero(x,n)

Note that it's critical that each element be completely
full - i.e., that we use all the memory locations in the
x(i,j,k) locacations.   That way, we are always accessing
adjacent memory locations and have unit-stride addressing
(see, e.g., Deville,Fischer,Mund chapter 8 or google the
topic).   However, we _don't_ have to fill up all the elements.
If we want to declare 10 elements and use only the first 5,
that's ok (though it takes more memory, which may or may not
be an issue).   With this approach we have the flexibility
of running the same executable with different processor
counts.    Consider the following scenario:

We have nelg=80 elements in a mesh and we declare lelt=10.

We can run on:

    8 processors, lelt=10, nelt=10
   16 processors, lelt=10, nelt= 5
   32 processors, lelt=10, nelt= 2 or 3

etc.  Note that, in the 32 processor case, not all processors
have the same value of nelt.  However, they must have the
same value of lelt because they are running the same
executable and nek uses static (i.e., declared at compile-time)
memory allocation.


Paul

________________________________
From: nek5000-users-bounces at lists.mcs.anl.gov [nek5000-users-bounces at lists.mcs.anl.gov] on behalf of nek5000-users at lists.mcs.anl.gov [nek5000-users at lists.mcs.anl.gov]
Sent: Tuesday, June 03, 2014 2:52 AM
To: nek5000-users at lists.mcs.anl.gov
Subject: [Nek5000-users] size of arrays and declaration of variables

Hi Nek team,

I have a question concerning the size of arrays. I took the routine convab for example.

TA, such as T, BQ or VTRANS, have a size of lt=lx1*ly1*lz1*lelt.
So why in the call of col2 or subcol3 the parameter n, which should be the size of the arrays cited above, is actually ntot=nx1*ny1*nz1*nelfld(ifield) ?


1) I guess that there is a reason for that, but I don’t understand this mismatch of size of arrays. Moreover, ntot refers to the number of nodes on a CPU and LT refers to the total number of node in the full domain, right?

2) I’m not expert in F77 but could you confirm me that there is no difference between the declaration: TA (LX1,LY1,LZ1,LELT) and TA(LT) with LT=LX1*LY1*LZ1*LELT ? I mean, an argument such as TA(1,1,1,1) will pass the whole array of TA ?

Thank you !


      subroutine convab
C---------------------------------------------------------------
C
C     Eulerian scheme, add convection term to forcing function
C     at current time step.
C
C---------------------------------------------------------------
      include 'SIZE'
      include 'SOLN'
      include 'MASS'
      include ‘TSTEP'

      COMMON /SCRUZ/ TA (LX1,LY1,LZ1,LELT)
C
      NEL = NELFLD(IFIELD)
      NTOT1 = NX1*NY1*NZ1*NEL
      CALL CONVOP  (TA,T(1,1,1,1,IFIELD-1))
      CALL COL2    (TA,VTRANS(1,1,1,1,IFIELD),NTOT1)
      CALL SUBCOL3 (BQ(1,1,1,1,IFIELD-1),BM1,TA,NTOT1)



Best regards,
Emmanuel



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/nek5000-users/attachments/20140603/5f04c82c/attachment-0001.html>


More information about the Nek5000-users mailing list