How to transfer the loop from do i=1, lx1; do j=1, ly1; do k=1,lz1 to do l=1,lxyz.

12 views
Skip to first unread message

X. G. Zhou

unread,
Mar 29, 2026, 8:27:10 AM (3 days ago) Mar 29
to Nek5000
Dear community,

I see the derivatives calculated in Nek5000 with subroutines comp_gije and gradm1 use the following data structure:

parameter (lxyz=lx1*ly1*lz1)
common /myTest/ dudx(lxyz,lelv), dudy(lxyz,lelv), dudz(lxyz,lelv)
real dudx, dudy, dudz
call gradm1(dudx,dudy,dudz,u)
do e=1,nelv
    do l=1,lxyz
        dudx(l,e) = .... 
    enddo
enddo

However, i see the y location for velocity mesh can be accessed from ym1(lx1,ly1,lz1,lelv). Hence we usually write:

do e=1,nelv
    do i=1,lx1
    do j=1,ly1
    do k=1,lz1
        .... = ym1(i,j,k,e)
    enddo
    enddo
    enddo
enddo

Now i would like to get the derivatives in loop of i j k. Can i write the code like:
do e=1,nelv
    do i=1,lx1
    do j=1,ly1
    do k=1,lz1
        dudx( i + lx1*(j-1) + lx1*ly1*(k-1), e ) = ....  ! instead of dudx(l,e) in loop lxyz?
    enddo
    enddo
    enddo
enddo

I need to get the derivates and y coordinates in the same loop, any suggestions are helpful. Thanks for advance.

Yours,

Zhou


Fischer, Paul

unread,
Mar 29, 2026, 9:19:12 AM (3 days ago) Mar 29
to X. G. Zhou, Nek5000
Dear Zhou,

Here is a brief description of some options - I hope it will clarify.

Best,
Paul 
      integer e

      real f(lx1,ly1,lz1,lelt)

      ...

      lxyz = lx1*ly1*lz1

c     Option 1
      do e=1,nelv
         do i=1,lxyz
            du = dudx(i,e)
            f(i,1,1,e) = ym1(i,1,1,e)*dudx(i,e)
         enddo
      enddo


c     Option 2
      n = lxyz*nelv
      do i=1,n
         du = dudx(i,1)
         f(i,1,1,1) = ym1(i,1,1,1)*dudx(i,1)
      enddo


c     Your suggested, while technically correct will be about 10x slower
c     because you are not using unit-stride memory access

c     Option 3
      do e=1,nelv
        do i=1,lx1
        do j=1,ly1
        do k=1,lz1
          dudx( i + lx1*(j-1) + lx1*ly1*(k-1), e ) = ....  ! instead of dudx(l,e) in loop lxyz?
        enddo
        enddo
        enddo
      enddo

      If you really want to use nested loops (not recommended because it relies
      on the compiler to vectorize all of the nested loops, which they rarely do),
      you should at least order them correctly

c     Option 4
      do e=1,nelv
        do k=1,lz1
        do j=1,ly1
        do i=1,lx1
          dudx( i + lx1*(j-1) + lx1*ly1*(k-1), e ) = ....  ! instead of dudx(l,e) in loop lxyz?
        enddo
        enddo
        enddo
      enddo

But the fastest is Option 2.



From: nek...@googlegroups.com <nek...@googlegroups.com> on behalf of X. G. Zhou <starlig...@163.com>
Sent: Sunday, March 29, 2026 7:27 AM
To: Nek5000 <nek...@googlegroups.com>
Subject: [nek5000] How to transfer the loop from do i=1, lx1; do j=1, ly1; do k=1,lz1 to do l=1,lxyz.
 
--
You received this message because you are subscribed to the Google Groups "Nek5000" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nek5000+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/nek5000/6f6cf64b-82bb-4183-ba0a-5f90847f65b5n%40googlegroups.com.

X. G. Zhou

unread,
Mar 29, 2026, 8:34:31 PM (3 days ago) Mar 29
to Nek5000
Dear Paul

Thanks for your kind and detailed responses, which are really helpful.

Thank you for your time.

Yours,

Zhou
Reply all
Reply to author
Forward
0 new messages