Reputation: 5847
I want to write my data for a periodic boundary, implying the zero-th index needs to written at the end for both i
and j
direction. Also, rho(m+1,n+1)=rho(0,0)
needs to be written. The current code for writing data is:
do j=0,n
write(2,"(F16.8)")(rho(i,j),i=0,m)
end do
How can the data be written in such a way I mentioned above? Something like the following
j ...
i 1 2 3
. 4 5 6
. 7 8 9
1 2 3 1
4 5 6 4
7 8 9 7
1 2 3 1
Upvotes: 2
Views: 691
Reputation: 8140
An implied do loop has to be in parentheses inside an array declaration:
! These are the same
[ (i, i=1, 3) ]
(/ (i, i=1, 3) /)
If you have a many-dimensional one, you have to wrap them
[ ( [ (i*j, i=1, 3) ], j = 1, 3 ) ]
! ^^^^^^^^^^^^^^^^^
For your periodicity, I simply use mod(idx, len)
to get back to 0 for the last one. Here's my idea on how to do it with implicit do loops.
program periodic_boundary
implicit none
integer :: d(0:2, 0:2), i, j
d = reshape( [(i, i=1, 9)], [3, 3] )
print '(4I4)', &
[ ( &
[ (d(mod(i, 3), mod(j, 3)), i=0, 3) ] &
, j=0, 3) ]
end program periodic_boundary
For readability, I use continuation lines to separate the inner from the outer loop.
Upvotes: 1
Reputation: 7395
If the computational speed does not matter, wrapping the indices with periodic boundary condition might be another option. (As for modulo()
, please see this page, which gives [0,P-1]
for negative as well as positive arguments. By changing the return value 0 to P, it always maps the result to [1,P]
.)
program main
implicit none
integer, parameter :: m = 3, n = 3
integer rho( m, n ), i, j
rho(1,:) = [1,2,3]
rho(2,:) = [4,5,6]
rho(3,:) = [7,8,9]
do i = -2,m+3
print "(*(i2))", ( rho( pbc(i,m), pbc(j,n) ), j = -2,n+3 )
enddo
contains
integer function pbc( k, P )
integer :: k, P
pbc = modulo( k, P )
if ( pbc == 0 ) pbc = P
endfunction
end
$ gfortran -fcheck=all test.f90
1 2 3 1 2 3 1 2 3
4 5 6 4 5 6 4 5 6
7 8 9 7 8 9 7 8 9
1 2 3 1 2 3 1 2 3
4 5 6 4 5 6 4 5 6
7 8 9 7 8 9 7 8 9
1 2 3 1 2 3 1 2 3
4 5 6 4 5 6 4 5 6
7 8 9 7 8 9 7 8 9
Upvotes: 0
Reputation: 78374
Maybe something like this (untested)
integer, dimension(4,4) :: arr1
...
arr1(1:3,1:3) = transpose(reshape([(i,i=1,9)],[3,3]))
arr1(:,4) = arr1(:,1)
arr1(4,:) = arr1(1,:)
but drop the madness of thinking about 0-th indices in Fortran.
Upvotes: 0