<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<div id="divtagdefaultwrapper" dir="ltr" style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, Helvetica, EmojiFont, 'Apple Color Emoji', 'Segoe UI Emoji', NotoColorEmoji, 'Segoe UI Symbol', 'Android Emoji', EmojiSymbols;">
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0">f77 array declarations do either one or two things, depending on </p>
<p style="margin-top:0; margin-bottom:0">whether the array is passed as an argument or is declared within</p>
<p style="margin-top:0; margin-bottom:0">the scope of the routine or function in question. </p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0">If the array is in <span style="font-size:12pt">a common block or is declared for the first time</span></p>
<p style="margin-top:0; margin-bottom:0">within a subroutine/function, then the statement sets aside memory.</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0">For example:</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"> subroutine blah(z)</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"> include 'SIZE'</p>
<p style="margin-top:0; margin-bottom:0"> real x(lx1,ly1,lz1,lelt)</p>
<p style="margin-top:0; margin-bottom:0"> common /c1/ y(lx1,ly1,lz1,lelt)</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"> real z(lx1,ly1,lz1,lelt)</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"> integer e</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0">results in two arrays, x and y, be declared to hold n words of memory,</p>
<p style="margin-top:0; margin-bottom:0">where n = lx1*ly1*lz1*lelt</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0">The line "real z(...)" does not declare any memory. </p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0">All three statements indicate how to reference an entry in any</p>
<p style="margin-top:0; margin-bottom:0">of the arrays by the formula:</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"> [ z(i,j,k,e) ] = [z(1,1,1,1)] + </p>
<p style="margin-top:0; margin-bottom:0"> (i+(j-1)*lx1+(k-1)*lx1*ly1+(e-1)*lx1*ly1*lz1)*wdsize</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0">where [.] implies the address of the argument. This formula applies</p>
<p style="margin-top:0; margin-bottom:0">equally to x,y, and z in the above example. f77 does not care about</p>
<p style="margin-top:0; margin-bottom:0">i,j,k, or e (save that they must be integer). It assumes you know what</p>
<p style="margin-top:0; margin-bottom:0">you are doing when you compute an address. Thus the following are</p>
<p style="margin-top:0; margin-bottom:0">almost equivalent:</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"> do e=1,nelt</p>
<p style="margin-top:0; margin-bottom:0"> do k=1,lz1</p>
<p style="margin-top:0; margin-bottom:0"> do j=1,ly1</p>
<p style="margin-top:0; margin-bottom:0"> do i=1,lx1</p>
<p style="margin-top:0; margin-bottom:0"> x(i,j,k,e)=z(i,j,k,e)</p>
<p style="margin-top:0; margin-bottom:0"> enddo</p>
<p style="margin-top:0; margin-bottom:0"> enddo</p>
<p style="margin-top:0; margin-bottom:0"> enddo</p>
<p style="margin-top:0; margin-bottom:0"> enddo</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"> n = lx1*ly1*lz1*nelt (Note: nelt, not lelt)</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"> do i=1,n</p>
<p style="margin-top:0; margin-bottom:0"> x(i,1,1,1) = z(i,1,1,1)</p>
<p style="margin-top:0; margin-bottom:0"> enddo</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0">The latter, however, is _much_ better than the former. Why?</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0">Most compilers will not vectorize more than one loop deep (the "i" loop</p>
<p style="margin-top:0; margin-bottom:0">in the first of the two preceding examples). You thus have a relatively short loop for vectorization; whereas the second, single-loop, form will vectorize. Moreover, the second form makes the code much easier to use.
The essential point is that x and z are contiguous arrays --- which is the case throughout nek.</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0">NOTE: many users are hesitant about using the 2nd form, despite the fact that it is vastly superior to the first. There is no need to be uneasy about this form, however. It has been used in Nek for over 30 years on
hundreds of the world's fastest computers. It is a well-know fortran trick for high performance. Please look through the Nek5000 source for more examples of this type.</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
<p style="margin-top:0; margin-bottom:0"><br>
</p>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> Nek5000-users <nek5000-users-bounces@lists.mcs.anl.gov> on behalf of nek5000-users@lists.mcs.anl.gov <nek5000-users@lists.mcs.anl.gov><br>
<b>Sent:</b> Wednesday, August 15, 2018 4:16:15 AM<br>
<b>To:</b> nek5000-users@lists.mcs.anl.gov<br>
<b>Subject:</b> [Nek5000-users] reshape array</font>
<div> </div>
</div>
<meta content="text/html; charset=Windows-1252">
<meta name="x_Generator" content="Microsoft Word 15 (filtered medium)">
<div lang="EN-GB">
<div class="x_WordSection1">
<p class="x_MsoNormal">Hi all,</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal" style="text-autospace:none">All average streamwise velocity are stored in this array</p>
<p class="x_MsoNormal" style="text-autospace:none"> </p>
<p class="x_MsoNormal" style="text-autospace:none">“<span style="font-size:10.0pt; font-family:"Lucida Console"">common /avg/ uavg(lx1,ly1,lz1,lelv)”
</span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console""> </span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console"">but I want this array to be reshaped into
</span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console""> </span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console"">“common /abcd/ abcd(lx1*ly1*lz1,lelv)”
</span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console""> </span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console"">The following didn’t work:</span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console""> </span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console""> </span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console"">common /avg/ uavg(lx1,ly1,lz1,lelv)</span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console"">common /abcd/ abcd(lx1*ly1*lz1,lelv)</span></p>
<p class="x_MsoNormal" style="text-autospace:none"><span style="font-size:10.0pt; font-family:"Lucida Console""> </span></p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal"><span style="font-size:10.0pt; font-family:"Lucida Console"">abcd=reshape(uavg,(/ lx1*ly1*lz1,lelv /))</span></p>
<p class="x_MsoNormal"><span style="font-size:10.0pt; font-family:"Lucida Console""> </span></p>
<p class="x_MsoNormal"><span style="font-size:10.0pt; font-family:"Lucida Console""> </span></p>
<p class="x_MsoNormal"><span style="font-size:10.0pt; font-family:"Lucida Console"">This is how array reshaping works in fortran. Unfortunately, didn’t work in nek. Anyone knows why?</span></p>
<p class="x_MsoNormal"><span style="font-size:10.0pt; font-family:"Lucida Console""> </span></p>
<p class="x_MsoNormal"><span style="font-size:10.0pt; font-family:"Lucida Console"">Many thanks in advance for your replies.</span></p>
</div>
</div>
</div>
</body>
</html>