2016-06-21 2 views
0

J'ai un certain code dans fortran. Le code prend 'pq' comme une entrée de l'utilisateur et est un seul point. Au lieu de faire cela, je veux lire un ensemble de points 'pq' à partir d'un fichier points.txt et l'exécuter pour ce nombre de points au lieu d'une seule entrée utilisateur. C'est possible? Le code est le suivant:Appeler un sous-programme pour une liste de points au lieu d'un seul point

program prop 

     use module 

     implicit none 

     character(len=80) :: ErrorMsg 
     character(2)   :: xy 
     real(8)    :: Conc(20) = 0.d0 
     character(len=20)  :: fn, fl 
     real(8)    :: Mmolar, Tcritical, Pcritical, Tmininimum, Tmaximum, x, y 

call Init_module() 

    write(*,*) 'Insert the gas name:' 
    read(*,*) fn 
    write(*,*) 'Insert the gas library:' 
    read(*,*) fl 


    write(*,*) 'Insert the copule pq:' 
    read(*,*) pq 
    write(*,*) 'Insert the value of ', pq(1:1) 
    read(*,*) x 
    write(*,*) 'Insert the value of ', pq(2:2) 
    read(*,*) y 

write(*,*) 'Pres  = ', Pres(pq, x, y, ErrorMsg) 
    write(*,*) 'Temp = ', Temperature(pq, x, y, ErrorMsg) 

call ReleaseObjects() 

end program prop 

Au lieu de pq de lecture comme un seul point x, y de l'utilisateur dans le code ci-dessus, je veux lire un ensemble de points de file.txt, par exemple 50 points et puis exécutez les sous-programmes Pres et Temperature. Chaque ligne du fichier contient un point x, y et x et y dans chaque ligne sont séparés par quelques espaces. Les premières lignes de fichier.txt sont:

Ts 
500 
0.04781564 159.81587875 
0.20396084 165.46398084 
0.08159885 166.81382894 
0.03879184 164.17497877 
0.12585959 165.37000305 
0.09895530 165.95997769 
0.10389518 170.74235496 

Il faut noter que la longueur et le signe des nombres flottants peuvent varier. Le fichier file.txt est écrit à l'origine via python avec la mise en forme pour x, y étant '%-12.8f %-12.8f\n'%. Je le code suivant pour essayer de lire le fichier mais ne suis pas capable de lire à partir de la 3ème ligne partir:

real, allocatable  :: x(:),y(:) 
     integer :: np 

     open(12,file=trim('file.txt'),status='old', & 
      access='sequential', form='formatted', action='read') 

      read(12,*)pq 
      write(*,*)'pq:', pq 

      read(12,*)np 
      write(*,*)'number of points:',np 

      allocate (x(np)) 
      allocate (y(np)) 
      do i=1,np   
      read(12,*)x(i),y(i) 
      write(*,*)x(i),y(i) 
      enddo 
+0

Vous pourriez savoir ce qu'ils appellent des boucles et des tableaux dans les langages de programmation modernes. Ce sont vos amis pour ce genre de choses. Mais entretemps 'module' est un mot-clé dans fortran 90 et plus, donc vous ne voulez pas nommer votre propre modulemodule. – innoSPG

+1

@innoSPG Dûment noté. Cependant, je suis familier avec les tableaux et les boucles, je ne savais pas comment les implémenter pour fortran, je suis nouveau à fortran. Merci pour l'info. – Aspro

Répondre

0

au lieu d'utiliser l'instruction READ avec l'astérisque (*) comme premier argument demandant un utilisateur entrée, utilisez un identifiant de fichier. Vous devez OPEN votre fichier contenant l'ensemble des points, en supposant qu'il est ASCII:

OPEN(UNIT=10,FILE=file.txt,ACTION='read',STATUS='old') 

Je pense que les arguments de cette commande sont assez explicites. Ensuite, en supposant que votre fichier contient plusieurs lignes avec des valeurs x et y, vous pouvez lire chaque ligne de votre fichier en faisant:

READ(10,*) x,y 

Si vous avez plusieurs points de lecture, il suffit d'utiliser un DO si vous connaissez le nombre de points à lire, un DO WHILE sinon. Pour prendre votre exemple avec 50 points, quelque chose comme cela devrait fonctionner:

OPEN(UNIT=10,FILE=file.txt,ACTION='read',STATUS='old') ! Open file 
DO i=1,50 
    READ(10,*) x,y 
    write(*,*) 'Pres  = ', Pres(pq, x, y, ErrorMsg) 
    write(*,*) 'Temp = ', Temperature(pq, x, y, ErrorMsg) 
END DO 
CLOSE(10) ! Close file 

EDIT

Votre suggestion est presque correcte. Vous avez oublié de déclarer pq comme character(len=2). Vous n'auriez pas dû passer la ligne 1 à cause de ça. Comme je l'ai dit, il y a un séparateur d'espace qui est traité naturellement par un astérisque comme format. Quoi qu'il en soit, si vous voulez correspondre exactement au format, utilisez la même chose avec laquelle vous avez écrit vos données. La lecture de votre forme Python, je suppose que vous avez écrit deux flotteurs avec un séparateur d'espace, et même si l'on compte le nombre de caractères de vos chiffres:

0.04781564 159.81587875 
^^^^^^^^^^^^|^^^^^^^^^^^^ 
1   12|1   12 
      | 
      space 

qui donne le format suivant en Fortran:

read(12,'(f12.8,1X,f12.8)') x(i),y(i) 

X signifie un séparateur d'espace dans les formats Fortran.

Ensuite, vous pouvez vous écrire des données à l'écran avec le même format pour vérifier:

write(*,'(f12.8,1X,f12.8)') x(i),y(i) 

Il donne:

pq:Ts 
number of points:   500 
0.04781564 159.81587219 
0.20396084 165.46397400 
0.08159885 166.81382751 
0.03879184 164.17497253 
0.12585959 165.37001038 
0.09895530 165.95997620 
0.10389518 170.74235535 

Vous avez peut-être remarqué que vous avez perdu la précision sur les derniers chiffres. C'est parce que vous avez déclaré un réel simple (4 octets). Mettez vos real à 8 octets avec real(kind=8) ou real*8 selon votre compilateur (attention, pas la bonne façon de le faire, non portable mais suffisante dans votre cas)

Ne pas oublier de fermer votre dossier lorsque vous avez terminé le traitement avec elle:

close(12) 
+0

Utilisez également le spécificateur 'newunit' si vous avez la chance d'avoir accès à un compilateur Fortran (2008+) moderne. – jlokimlin

+0

@Coriolis Les points dans le fichier sont formatés en espace au lieu d'une virgule, que faire dans ce cas? – Aspro

+0

@Aspro Le deuxième astérisque de l'instruction 'read' vous permet de définir un format. Quand un astérisque est utilisé, le programme lit vos données "comme il veut", en fait cela devrait suffire pour traiter un séparateur d'espace. Si vous voulez être sûr de la façon dont vos données sont lues, vous devez définir un format. Je vous suggère de lire un tutoriel à ce sujet, il est trop complexe pour être défini ici. – Coriolis