2017-09-15 1 views
1

Je souhaite écrire mes données pour une limite périodique, ce qui implique que l'index zéro doit être écrit à la fin pour les directions i et j. En outre, rho(m+1,n+1)=rho(0,0) doit être écrit. Le code actuel pour l'écriture des données est:Fortran implicite do loop: append array

do j=0,n 
write(2,"(F16.8)")(rho(i,j),i=0,m) 
end do 

Comment les données soient écrites de telle manière je l'ai mentionné ci-dessus? Quelque chose comme ce qui suit

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 
+0

'(n-i, m-j)'? Je ne sais pas si j'ai bien compris votre question. –

+0

@VladimirF Ajout de quelques détails. Peut-être que je pourrais négliger les choses. Vous pouvez me demander, si quelque chose n'est pas clair. –

Répondre

1

Une implique faire boucle doit être entre parenthèses dans une déclaration de tableau:

! These are the same 
[ (i, i=1, 3) ] 
(/ (i, i=1, 3) /) 

Si vous avez un en plusieurs dimensions, vous devez les envelopper

[ ([ (i*j, i=1, 3) ], j = 1, 3) ] 
! ^^^^^^^^^^^^^^^^^ 

Pour votre périodicité, j'utilise simplement mod(idx, len) pour revenir à 0 pour le dernier. Voici mon idée sur la façon de le faire avec des boucles implicites.

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 

Pour la lisibilité, j'utilise des lignes de continuation pour séparer la boucle interne de la boucle externe.

0

Peut-être quelque chose comme ça (non testé)

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,:) 

mais laisser tomber la folie de penser à des indices 0-ième Fortran.

0

Si la vitesse de calcul n'a pas d'importance, l'enroulement des index avec des conditions aux limites périodiques peut être une autre option. (En ce qui concerne modulo(), s'il vous plaît voir ce page, qui donne [0,P-1] pour le négatif ainsi que des arguments positifs. En changeant la valeur de retour de 0 à P, il mappe toujours le résultat à [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