IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Fortran Discussion :

Appel de data communes à plusieurs procédures


Sujet :

Fortran

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 5
    Points
    5
    Par défaut Appel de data communes à plusieurs procédures
    Bonjour à vous,

    Je débute en Fortran et j'ai un problème qui peut se résumer ainsi. Je dispose de deux programmes utilisant exactement les mêmes datas et qui doivent être inclus dans une procédure récursive. J'aimerais pouvoir charger une fois pour toute ces datas, au lieu de les recharger à chaque fois que je re rentre dans la boucle.

    Dans un premier programme, j'ai les déclarations suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    program main
      implicit none
      
      integer, parameter :: nbniv=220
      integer, parameter :: nfreq=3000
      real, dimension(nbniv) :: ener,g
      integer, dimension(nbniv) :: n,charge,nlast,llast,nel_eq
      integer, dimension(3) :: i0_ion
      integer, dimension(10) :: aa, bb
      real, dimension(10) :: corr_ener
      real, dimension(nbniv,nbniv) :: a,c,s,rrad,t
      real, dimension(nbniv-1,nbniv-1) :: q
      real, dimension(nbniv-1) :: y
      real, dimension(nbniv) :: pop,boltz
    
    ...
    ...
    
    open(10,file='donnes_LIBS_clair',form='formatted',status='unknown')
      read(10,'(a14,a15,a14)') tex6,tex7,tex8
      do Z=1,val
         read(10,'(e16.7,e16.7,e16.7)',iostat=ios) tps,densi,temp
         if (Z==1) then
            call modstat(temp,densi,choix,pop,poptot0,ener,g,nlast,llast,nel_eq,charge,a)
            !pause
         else
            call modnonstat(temp,densi,choix,pop,poptot0,ener,g,nlast,llast,nel_eq,charge,a)
            !pause
         endif
      enddo
      close(10)
    Les six derniers arguments sont en fait les data communes aux programmes. La taille de ces data est annoncée en gras plus haut.

    Donc dans les procédures modstat et modnonstat, j'utilise la syntaxe suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SUBROUTINE modnonstat(telec,dens,choix,pop,poptot0,ener,g,nlast,llast,nel_eq,charge,a)
          implicit none
          
          integer, parameter :: nbniv=220 
          integer, parameter :: nfreq=3000 
          integer, dimension(nbniv) :: n
          integer, dimension(3) :: i0_ion
          integer, dimension(10) :: aa, bb
          real, dimension(10) :: corr_ener
          real, dimension(nbniv,nbniv) :: c,s,rrad,t,q
          real, dimension(nbniv) :: y
          real, dimension(nbniv) :: boltz
          real, dimension(*) :: pop,ener,g
          real, dimension(*,*) :: a
          integer, dimension (*) :: charge,nlast,llast,nel_eq
    Cette déclaration (dimension (*)) marche bien pour les vecteurs, mais pas pour la matrice a(nbniv, nbniv). En effet, quand on compile avec g95 le code :
    In file modnonstat.f90:14

    real, dimension(*,*) :: a
    1
    Error: Bad specification for assumed size array at (1)
    Auriez vous des conseils à me donner concernant cette erreur ? La syntaxe de déclaration en dimension(*) est elle correcte, ou y'a t'il une méthode alternative ?

    Merci d'avance pour vos réponses !

  2. #2
    Rédacteur

    Homme Profil pro
    Comme retraité, des masses
    Inscrit en
    Avril 2007
    Messages
    2 978
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : Suisse

    Informations professionnelles :
    Activité : Comme retraité, des masses
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 2 978
    Points : 5 179
    Points
    5 179
    Par défaut
    Salut!
    Pourquoi ne pas utiliser l'instruction common?
    Jean-Marc Blanc

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    Citation Envoyé par Benjamin Straw Voir le message
    Je dispose de deux programmes utilisant exactement les mêmes datas et qui doivent être inclus dans une procédure récursive. J'aimerais pouvoir charger une fois pour toute ces datas, au lieu de les recharger à chaque fois que je re rentre dans la boucle.
    Si tu ne veux pas passer les variables en paramètres, je vois 3 solutions :
    • Tu place tes routines dans une section « contains » de ton programme. Les routines contenues voient les variables du programme contenant.
    • Tu déplace les variables à partager dans un module que tu « use » où tu en as besoin.
    • Tu utilise un common (comme suggéré par Jean-Marc)

    La première solution est très utile pour des petits programmes, mais je ne crois pas que ce soit ton cas.

    La solution « module » est la solution moderne et la plus simple, mais exige que ton programme soit en Fortran 90 au moins (ce qui est ton cas).

    La solution common est la solution Fortran 77. Si tu utilise un compilateur Fortran 90+, elle devrait être évité (à mon avis) car elle n'apporte rien par rapport au module et est plus longue et difficile d'entretien.

    Ébauche de la solution module :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    module ModulePartage
      implicit none
      integer, parameter :: nbniv=220
      integer, parameter :: nfreq=3000
      real, dimension(nbniv) :: ener,g
      integer, dimension(nbniv) :: n,charge,nlast,llast,nel_eq
      real, dimension(nbniv,nbniv) :: a,c,s,rrad,t
      real, dimension(nbniv-1,nbniv-1) :: q
      real, dimension(nbniv-1) :: y
      real, dimension(nbniv) :: pop,boltz
    end module
     
    program main
      implicit none
      use ModulePartage
      integer, dimension(3) :: i0_ion
      integer, dimension(10) :: aa, bb
      real, dimension(10) :: corr_ener
      ...
      ...
     
    open(10,file='donnes_LIBS_clair',form='formatted',status='unknown')
    read(10,'(a14,a15,a14)') tex6,tex7,tex8
    do Z=1,val
    read(10,'(e16.7,e16.7,e16.7)',iostat=ios) tps,densi,temp
    if (Z==1) then
    call modstat()
    !pause
    else
    call modnonstat()
    !pause
    endif
    enddo
    close(10)
    ...
    subroutine modstat
      implicit none
      use ModulePartage ! Donne accès à tout ce qui est dans ModulePartage...
      ...
    Citation Envoyé par Benjamin Straw Voir le message
    Cette déclaration (dimension (*)) marche bien pour les vecteurs, mais pas pour la matrice a(nbniv, nbniv). Auriez vous des conseils à me donner concernant cette erreur ? La syntaxe de déclaration en dimension(*) est elle correcte
    La dimension étoile (*) indique au compilateur qu'il n'y a pas d'information sur le nombre d'éléments. C'est la responsabilité du programmeur de référencer le vecteur correctement (à l'intérieur des dimensions réelles de la variable). Comme les éléments sont consécutifs en mémoire, le fait que les dimensions ne soient pas accessibles ne cause pas vraiment de problème. Le vecteur commence à (1), suivi de l'élément (2), et ainsi de suite.

    Pour un tableau, le problème est le suivant :
    • Les éléments sont aussi placés à la suite les une des autres (1,1), (2,1), ..., (n,1), (1,2), (2,2), ..., (n,2), (3,1), ..., (n,m)
    • Si la routine n'a pas accès au dimensions réelles, elle n'a pas accès à « n ».
    • Les références (i,j) pour j > 1 ne peuvent pas être résolue sans la valeur de « n ».

    Pour cette raison, tu peux utiliser l'étoile uniquement pas la dernière dimension. a(nbniv, *) serait donc permis, à condition évidemment que nbniv soit connu dans la routine.
    Citation Envoyé par Benjamin Straw Voir le message
    y'a t'il une méthode alternative ?
    En Fortran 90 (et +), tu peux utiliser la syntaxe a(:,: ). Avec cette syntaxe, le compilateur a accès aux dimensions effectives du tableau. Pour que ça fonctionne, il faut cependant que l'appelant ait accès à l'interface explicite de l'appelé. Pour ce faire, l'appelé doit être dans la section contains de l'appelant ou dans un module (il est aussi possible d'écrire « à bras » l'interface, mais il faut éviter à moins de besoin très spécifique).

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Merci infiniment pour vos réponses !

    Vos solutions malheureusement ne fonctionnent pas encore. La solution common (blanc pour ma part) entre en conflit avec l'intitulé dummy lors que je la place dans mon programme principal après avoir déclaré la taille des variables. Cela me semble normal étant donné ce qui est spécifié sur le cours de l'IDRIS au sujet des common blanc (impossibilité d'initialiser les variables à la déclaration).

    J'ai donc opté pour le moment pour la solution module (merci au passage pour l'explication pour le problème de déclaration du tableau a). Maintenant mon programme principal main.f90 a l'entête suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    module Partage
      implicit none
      integer, parameter :: nbniv=220  !nb total de niveaux dans le modele CR
      integer, parameter :: nfreq=3000
      real, dimension(nbniv) :: ener,g
      integer, dimension(nbniv) :: n,charge,nlast,llast,nel_eq
      real, dimension(nbniv,nbniv) :: a,c,s,rrad,t
      real, dimension(nbniv-1,nbniv-1) :: q
      real, dimension(nbniv-1) :: y
      real, dimension(nbniv) :: pop,boltz
    end module Partage
     
    program main
      implicit none
     
      use Partage
      integer, dimension(3) :: i0_ion
      integer, dimension(10) :: aa, bb
      real, dimension(10) :: corr_ener
      real :: eji,eij,fij,gaunt,te,Ne,x,exi1,vac,d,tps
      real :: s0,s1,zmoy,rap,tex,aux,poptot0,popi0,potion,lambda,zrad,deg
      real ::  hnumin,hnumax,pas,hplanck,clum,celec, aij, eV,corr,grnd,temp,densi
      integer :: k,i,j,i0,N_noy,kion,nb_niv,ii,jj,i_CR,iraie,ios,val,choix,choix2,Z
      real, dimension(:,:), allocatable :: mat
      real, parameter :: ryd=13.605804
      integer, dimension(nbniv-1) :: indx
      real (kind (0D0)) :: tt,xx
      character tex1*2,tex2*5,tex3*8,tex4*7,tex5*12,tex6*16,tex7*16,tex8*6
      real, dimension(nfreq) :: hnu,em,londe,intens
     
    ...
    ...
    ...
     
    open(10,file='donnes_LIBS_clair',form='formatted',status='unknown')
      read(10,'(a14,a15,a14)') tex6,tex7,tex8
      do Z=1,val
         read(10,'(e16.7,e16.7,e16.7)',iostat=ios) tps,densi,temp
         if (Z==1) then
            call modstat(temp,densi,choix,pop,poptot0)
            !pause
         else
            call modnonstat(temp,densi,choix,pop,poptot0)
            !pause
         endif
      enddo
      close(10)
     
    ...

    Vous remarquerez que j'ai fait disparaitre les 6 variables qui me posaient problème, des arguments dummy.

    Et donc dans les fichiers modstat.f90 et modnonstat.f90, j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
          SUBROUTINE modnonstat(telec,dens,choix,pop,poptot0)
          implicit none
     
          use Partage
          integer, dimension(3) :: i0_ion
          integer, dimension(10) :: aa, bb
          real, dimension(10) :: corr_ener
          real :: eji,eij,fij,gaunt,te,Ne,x,exi1,vac,d,&
          s0,s1,rap,tex,aux,poptot,poptot0,popi0,potion,lambda,zrad,deg,&
          hnumin,hnumax,pas,hplanck,clum,celec, aij, eV,corr,grnd, &
          telec,dens,deltaT,corr_pop,sompop,zmoy
          integer :: k,i,j,i0,N_noy,kion,nb_niv,ii,jj,i_CR,iraie,ios,val
          integer :: choix,Z,U,nul
          real, parameter :: ryd=13.605804
          integer, dimension(nbniv) :: indx
          real (kind (0D0)) :: tt,xx
          character tex1*2,tex2*5,tex3*8,tex4*7,tex5*12,tex6*12,tex7*5
          character tex8*12,fichier*20,step*4
          real, dimension(nfreq) :: hnu,em,londe,intens
    Seulement a la compilation, c'est le drame :

    In file main.f90:16

    use Partage
    1
    In file main.f90:14

    implicit none
    2
    Error: USE statement at (1) cannot follow IMPLICIT NONE statement at (2)
    Je vous passe les autres erreurs des autres programmes qui sont du même acabit (notamment celles ou le compilo déclare ne pas connaître les variables que je lui rentre ... évidemment !)

    Je vais continuer à chercher de mon côté mais si jamais vous êtes plus rapides que moi, je vous en prie.


    EDIT :
    Bon ... le fichier main.f90 se compile en inversant le use avec le implicit none. Par contre pour un fichier du genre de modstat.f90 :

    g95 -c -O3 modstat.f90
    In file modstat.f90:5

    integer, parameter :: nbniv=220 !nb total de niveaux dans le modele CR
    1
    Error: Symbol 'nbniv' at (1) already has basic type of INTEGER
    In file modstat.f90:6

    integer, parameter :: nfreq=3000
    1
    Error: Symbol 'nfreq' at (1) already has basic type of INTEGER
    In file modstat.f90:8

    integer, dimension(nbniv) :: n,nlast,llast,nel_eq,charge
    1
    Error: Symbol 'n' at (1) already has basic type of INTEGER
    In file modstat.f90:12

    real, dimension(nbniv,nbniv) :: a,c,s,rrad,t
    1
    Error: Symbol 'a' at (1) already has basic type of REAL
    In file modstat.f90:13

    real, dimension(nbniv-1,nbniv-1) :: q
    1
    Error: Symbol 'q' at (1) already has basic type of REAL
    Là ca devient vraiment tricky ! Des remarques ? ^^

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    C'est un peu difficile de résoudre toutes les erreurs à partir d'extraits de source. L'erreur grossière est cependant la mienne : il faut toujours mettre les use avant les implicit none, même dans les routines.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Je pense que j'ai trouvé ! Je vous recontacte plus tard !

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    En fait c'est encore pire qu'avant. Je vous donne donc tout le code source, c'est a dire les trois fichiers .f90.

    1) Le fichier principal qui appelle les deux autres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    module Partage
      implicit none
      integer, parameter :: nbniv=220  !nb total de niveaux dans le modele CR
      integer, parameter :: nfreq=3000
      real, dimension(nbniv) :: ener,g
      integer, dimension(nbniv) :: n,charge,nlast,llast,nel_eq
      real, dimension(nbniv,nbniv) :: a
    end module Partage
    
    
    program main
      use Partage
      implicit none
      
      real, dimension(nbniv,nbniv) :: a,c,s,rrad,t
      real, dimension(nbniv-1,nbniv-1) :: q
      real, dimension(nbniv-1) :: y
      real, dimension(nbniv) :: pop,boltz
      integer, dimension(3) :: i0_ion
      integer, dimension(10) :: aa, bb
      real, dimension(10) :: corr_ener
      real :: eji,eij,fij,gaunt,te,Ne,x,exi1,vac,d,tps
      real :: s0,s1,zmoy,rap,tex,aux,poptot0,popi0,potion,lambda,zrad,deg
      real ::  hnumin,hnumax,pas,hplanck,clum,celec, aij, eV,corr,grnd,temp,densi
      integer :: k,i,j,i0,N_noy,kion,nb_niv,ii,jj,i_CR,iraie,ios,val,choix,choix2,Z
      real, dimension(:,:), allocatable :: mat
      real, parameter :: ryd=13.605804
      integer, dimension(nbniv-1) :: indx
      real (kind (0D0)) :: tt,xx
      character tex1*2,tex2*5,tex3*8,tex4*7,tex5*12,tex6*16,tex7*16,tex8*6
      real, dimension(nfreq) :: hnu,em,londe,intens
      
      ! ==========================================================
      ! Donnees:
      celec=1.6022e-19
      hplanck=6.6261e-34
      clum=3.e8
      grnd=6593.03515625
      ! ==========================================================
    
      print*, 'Choisissez votre configuration : Modèle CR (1) / Forcer l''''ETL (2)' 
      read(*,*) choix
      
    !============================================================================================================
      ! SECTION DES LECTURE DES DATAS AIJ ET ENERJ DES NIVEAUX
      !============================================================================================================
      
      ! Lecture des donnees des energies:
      open(14,file='Al1_ener_D',form='formatted',position='rewind',status='unknown')
      read(14,'(a2,i3,a5,i3,a8,f12.5,a7)')tex1,N_noy,tex2,kion,tex3,potion,tex4
      read(14,'(i4)')nb_niv
      do i=1,nb_niv
         i_CR=i_CR+1
         read(14,'(2i4,f15.8,f16.1,3i4)') ii,jj,ener(i_CR),g(i_CR),nlast(i_CR),llast(i_CR),nel_eq(i_CR)
         !print*, ener(i_CR)
         !print*,corr_ener(i_CR),ener(i_CR)
         !pause
         charge(i_CR)=0
      enddo
    
      !
      ! Lecture des taux de transitions radiatives:
    3 open(114,file='Al1_trad_D',form='formatted',position='rewind',status='unknown')
      read(114,'(a2,i3,a5,i3)')tex1,N_noy,tex2,kion
    1 read(114,'(2i4,2e14.5)',end=2)ii,jj,zrad,lambda
      !  zrad taux entre ii et jj en s-1, lambda, l.o. en angstrom
      if (choix==1 .or. choix==3) then
         a(ii,jj)=zrad
      else 
         a(ii,jj)=0.
      endif
      goto 1
    2 continue
      close(114)
    
      if (choix==3) then
         goto 56
      endif
      
    
      !
      ! ion suivant:
      i0_ion(2)=nb_niv+1
      
      !
      ! Lecture des donnees des energies:
      open(15,file='Al2_ener_D',form='formatted',position='rewind',status='unknown')
      read(15,'(a2,i3,a5,i3,a8,f12.5,a7)')tex1,N_noy,tex2,kion,tex3,potion,tex4
      read(15,'(i4)')nb_niv
      do i=1,nb_niv
         i_CR=i_CR+1
         read(15,'(2i4,f15.8,f16.1,3i4)') ii,jj,ener(i_CR),g(i_CR),nlast(i_CR),llast(i_CR),nel_eq(i_CR)
         charge(i_CR)=1
      enddo
      close(15)
      
      !
      ! Lecture des taux de transitions radiatives:
    90 open(115,file='Al2_trad_D',form='formatted',position='rewind',status='unknown')
      read(115,'(a2,i3,a5,i3)')tex1,N_noy,tex2,kion
    88 read(115,'(2i4,2e14.5)',end=89)ii,jj,zrad,lambda
      !  zrad taux entre ii et jj en s-1, lambda, l.o. en angstrom
      !    print *,ii,jj,zrad,lambda
      if (choix==1 .or. choix==3) then
         a(ii+i0_ion(2)-1,jj+i0_ion(2)-1)=zrad
      else 
         a(ii+i0_ion(2)-1,jj+i0_ion(2)-1)=0.
      endif
      goto 88
    89 continue 
      close(115)
      
      if (choix==3) then
         goto 57
      endif
      
      !
      ! ion suivant:
      i0_ion(3)=i0_ion(2)+nb_niv
      !
      open(16,file='Al3_ener_D',form='formatted',position='rewind',status='unknown')
      read(16,'(a2,i3,a5,i3,a8,f12.5,a7)')tex1,N_noy,tex2,kion,tex3,potion,tex4
      read(16,'(i4)')nb_niv
      do i=1,nb_niv
         i_CR=i_CR+1
         read(16,'(2i4,f15.8,f16.1,3i4)') ii,jj,ener(i_CR),g(i_CR),nlast(i_CR),llast(i_CR),nel_eq(i_CR)
         charge(i_CR)=2
      enddo
    
    
    if (choix2==1) then
       open (68,file='boltzmann_plot_general_alu',status='old')
       do i=1,nbniv
          boltz(i)=log(pop(i)/g(i))
          write (68,'(F30.5,F10.5)') ener(i), boltz(i)
       enddo
    endif
    close(68)
    
    !===============================================================================================================
    !
    !===============================================================================================================
    
      ios=0.
      val=0.
    
      open(10,file='donnes_LIBS_clair',form='formatted',status='unknown')
      read(10,'(a14,a15,a14)') tex6,tex7,tex8
      do while (ios==0)
         read(10,'(e16.7,e16.7,e16.7)',iostat=ios)tps,temp,densi
         val=val+1
      enddo
      close(10)
      
      open(10,file='donnes_LIBS_clair',form='formatted',status='unknown')
      read(10,'(a14,a15,a14)') tex6,tex7,tex8
      do Z=1,val
         read(10,'(e16.7,e16.7,e16.7)',iostat=ios) tps,densi,temp
         if (Z==1) then
            call modstat(temp,densi,choix,pop,poptot0)
            !pause
         else
            call modnonstat(temp,densi,choix,pop,poptot0)
            !pause
         endif
      enddo
      close(10)
    
      print *, 'Extraire un Boltzmann plot general ? (1) Oui / (2) Non'
      read(*,*) choix2
    
      if (choix2==2) stop
    
      i_CR=0
      i0_ion(1)=1 !indice du premier niveau dans un ion
      a=0.0 ; c=0.0 ; s=0.0 ; rrad=0.0 ; t=0.0
      
    
    !============================================================
    ! CALCUL DES EMISSIVITES DES RAIES (SPECTRE)
    !============================================================
    
    hnumin=1.8  ; hnumax=6.2 !eV  borne min=700 nm//borne max=200nm
    pas=(hnumax-hnumin)/float(nfreq-1)  
    em=0.0
    intens=0.0
    
    if(choix == 2) then
       choix=3
       goto 3      
    56 goto 90
    57 continue
    endif
    
    !
    ! contribution de toutes les transitions radiatives:
    
    open(09,file='Al_ener_D_corr',form='formatted',status='unknown')
    read(09,'(a11)') tex5
    aa=0.
    bb=0.
    corr_ener=0.
    do i=1,10
       read(09,'(i4,i2,f11.8)') ii, jj, corr
       aa(i)=ii
       bb(i)=jj
       corr_ener(i)=corr 
    enddo
    close (09)
    
    open(30,file='spectre_alu_pour_boltzplotLIBS',status='old')
    
    do i=1,nbniv
       do j=1,i-1
          val=0.
          do k=1,10
             if (i .ne. aa(k)) then 
                cycle
             else 
                if (j .ne. bb(k)) then 
                   cycle
                else   
                   eij=ener(i)-ener(j)+corr_ener(k)
                   !  print*, aa(k), bb(k), corr_ener(k), eij
                   !  pause
                endif 
             endif
             val=val+1.
          enddo
    
          if (val==0) then 
             eij=ener(i)-ener(j)  !! pas forcement superieur à 0 !
          endif
          
          iraie=int(((eij-hnumin)/pas))+1
    
          if(iraie<0.or.iraie>nfreq) cycle
          !      if (eij<0) pause
          em(iraie)=em(iraie)+pop(i)*a(i,j)*eij
          intens(iraie)=intens(iraie)+pop(i)*a(i,j)
          write(30,'(F15.10,F40.4)') ener(i)+grnd,intens(iraie)
          write(26,'(F8.5,F40.4)') ((iraie-1)*pas)+hnumin, a(i,j)
       enddo
    enddo
    
    close(26)
    close(30)
    
    do i=1,nfreq
       hnu(i)=hnumin+(i-1)*pas
       londe(i)=((hplanck*clum)/(hnu(i)*celec))*1e9
    enddo
    
    
    !=============================================================
    !                   ECRITURE DU SPECTRE
    !=============================================================
    
    open(25,file='spectre_alu',status='old')
    do i=1,nfreq
       write(25,'(F15.10,F40.4)') londe(i),em(i)
    enddo
    close(25)
    
    !=============================================================
    ! CLASSEMENT DE LA MATRICE DE FORT.26 
    !=============================================================
    
    open(26,file='fort.26',form='formatted',status='old')
    
    ios=0.
    val=0.
    
    do while (ios==0)
       read(26,'(F15.5,F40.4)',iostat=ios) eV, aij
       val=val+1   
    enddo
    
    allocate (mat(val,2))
    close(26)
    
    
    open(26,file='fort.26',form='formatted',status='old')
    
    do i=1,val
       read(26,'(F15.5,F40.4)',iostat=ios) mat(i,1), mat(i,2)
    enddo
    close (26)
    
    call tri_mat(mat,val,2)
    
    do i=1,val
       write(26,'(F8.5,F40.4)') mat(i,1), mat(i,2)
    enddo
    
    !
    !============================================================
    !    FIN DU PROGRAMME PRINCIPAL 
    !============================================================
    
    CONTAINS
      
      subroutine tri_mat(mat,n,m)
        
        implicit none
        
        integer              :: n,m
        real, dimension(n,m) :: mat
        integer              :: ligne
        
        !=========================================
        
        call tri_vecteur(mat,n)
        
      end subroutine tri_mat
      
      
      subroutine tri_vecteur(v,n)
        
        implicit none
        
        integer              :: n,i
        real, dimension(n,2) :: v
        logical              :: tri_termine
        
        
        do
           tri_termine=.true.
           
           do i=2,n
              if (v(i,1) < v(i-1,1)) then
                 tri_termine = .false.
                 v(i-1:i,1)=v(i:i-1:-1,1)
                 v(i-1:i,2)=v(i:i-1:-1,2)
              endif
           enddo
           if (tri_termine) exit
        enddo
        
      end subroutine tri_vecteur
      
    end program main
    Ce qui est en gras et en rouge, ce sont les valeurs que les deux autres programmes vont utiliser ! C'est ca que je veux calculer une fois pour toutes, et ne pas avoir à rappeler à modstat et modnonstat ! Notez aussi que la valeur de la matrice a(nbniv,nbniv) dépends si on réponds 1 ou 2 à la question du programme

    Ensuite, que ce soit le programme modstat.f90 ou modnonstat.f90, la structure change peu; aussi je n'en mettrais qu'un seul :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    SUBROUTINE modstat(telec,dens,choix,pop,poptot0)
      use Partage
     
          implicit none
          real, dimension(nbniv,nbniv) :: c,s,rrad,t
          real, dimension(nbniv-1,nbniv-1) :: q
          real, dimension(nbniv-1) :: y
          real, dimension(nbniv) :: pop,boltz
          integer, dimension(3) :: i0_ion
          integer, dimension(10) :: aa, bb
          real, dimension(10) :: corr_ener
          real, intent(out) :: poptot0
          real :: eji,eij,fij,gaunt,te,Ne,x,exi1,vac,d
          real :: s0,s1,rap,tex,aux,popi0,potion,lambda,zrad,deg,poptot
          real :: hnumin,hnumax,pas,hplanck,clum,celec, aij, eV,corr,grnd
          real :: telec,dens,sompop,zmoy
          integer :: k,i,j,i0,N_noy,kion,nb_niv,ii,jj,i_CR,iraie,ios,val
          integer :: choix,choix2,Z
          real, dimension(:,:), allocatable :: mat
          real, parameter :: ryd=13.605804
          integer, dimension(nbniv-1) :: indx
          real (kind (0D0)) :: tt,xx
          character tex1*2,tex2*5,tex3*8,tex4*7,tex5*12
          real, dimension(nfreq) :: hnu,em,londe,intens
     
    !     ==========================================================
    !     Donnees:
          te=telec 
          Ne=dens
          celec=1.6022e-19
          hplanck=6.6261e-34
          clum=3.e8
          grnd=6593.03515625
    !     ==========================================================
     
     
          i_CR=0
          i0_ion(1)=1               !indice du premier niveau dans un ion
          c=0.0 ; s=0.0 ; rrad=0.0 ; t=0.0
     
     
    !================================================================
    !     CONSTRUCTION DES TAUX COLLISIONNELS ET RADIATIFS (SAUF AIJ)
    !================================================================
     
    !
    !     =========================================
    !     Taux d'excitation/desexcitation collisionnelle
    !     formulation semi-empirique de Van-Regemorter: 
     
          do k=1,2
             do i=i0_ion(k),i0_ion(k+1)-1
                do j=i+1,i0_ion(k+1)-1
                   eji=(ener(j)-ener(i))
                   if(eji==0.0) cycle
                   fij=a(j,i)*(g(j)/g(i))/(4.339e7*eji*eji)
                   x=eji/te
                   tex=exp(-x)
                   xx=x ; tt=exp(xx)
                   gaunt=0.15+0.28*tt*exi1(x)
                   aux=1.16e-6*Ne*gaunt*ryd/(eji*sqrt(te))
                   c(i,j)=aux*tex
                   c(j,i)=aux*(g(i)/g(j))
                enddo
             enddo
          enddo
     
    !     ===============================================
    !     Taux d'ionisation/recombinaison collisionnelle:
    !     formulation de Lotz:
     
          do k=1,2
             do i=i0_ion(k),i0_ion(k+1)-1
                j=i0_ion(k+1)
                eji=(ener(j)-ener(i))
                if(eji<=0.0) cycle
                x=eji/te
                s(i,j)=Ne*3.0e-6*nel_eq(i)*(exi1(x)/x)*te**1.5
                xx=x
                tt=exp(xx)
                s(j,i)=(Ne*1.66e-22)*(g(i)/g(j))*tt*s(i,j)/(te**1.5)
             enddo
          enddo
     
    !     =============================================== 
    !     Taux de recombinaison radiative:
    !     formulation de Seaton: 
     
          do k=1,2
             do i=i0_ion(k),i0_ion(k+1)-1
                j=i0_ion(k+1)
                eji=(ener(j)-ener(i))
                if(eji<=0.0) cycle
                x=eji/te
                deg=2*(2*llast(i)+1)
                vac=1.0-float(nel_eq(i)-1)/deg !vacance 
    !     dans la couche d'acceuil avant processus
                xx=x
                tt=exp(xx)
                if (choix==2) then
                   rrad(j,i)=0.
                else
                   rrad(j,i)=Ne*5.2e-14*(x**1.5)*tt*exi1(x)*k*vac
                endif
             enddo
          enddo
     
    !     ===============================================
    !     Remplissage du systeme des equations de bilan
    !     Si un niveau i peuple un niveau j par un certain processus,
    !     alors ce processus doit etre pris en compte de la facon suivante
    !     dans la matrice CR:
    !     T(i,i)=T(i,i)-taux du processus
    !     T(j,i)=T(j,i)+taux du processus
    !     sachant que T(j,i)*Ni correspond a ce que recoit le niveau j,
    !     venant du niveau i.
    !     
     
          do i=1,nbniv
             do j=1,nbniv
    !     On examine le processus i -> j:
                t(i,i)=t(i,i)-(a(i,j)+c(i,j)+s(i,j)+rrad(i,j))
                t(j,i)=t(j,i)+(a(i,j)+c(i,j)+s(i,j)+rrad(i,j))
             enddo
          enddo
    !     
     
    !     Indice du fondamental de l'un des ions les plus
    !     probable:
          ion : do k=1,3
          do i=i0_ion(k),i0_ion(k+1)-1
             j=i0_ion(k+1) 
             eji=(ener(j)-ener(i))  !pot. d'ionisation 
             rap=eji/te
             if(rap>1.0) exit ion
          enddo
          enddo ion
          i0=j
     
    !     On supprime l'equation associee a la population i0
    !     et on rearrange le systeme relativement a cette
    !     population
    !     definition de la nouvelle matrice (q)
    !     
     
          do 11 i=1,i0-1
             y(i)=-t(i,i0)
             do 21 j=1,i0-1
     21         q(i,j)=t(i,j)
                do 31 j=i0+1,nbniv
     31            q(i,j-1)=t(i,j)
     11         continue
                do 111 i=i0+1,nbniv
                   y(i-1)=-t(i,i0)
                   do 222 j=1,i0-1
     222              q(i-1,j)=t(i,j)
                      do 333 j=i0+1,nbniv
     333                 q(i-1,j-1)=t(i,j)
     111              continue
     
     
    !     
    !     resolution du systeme
             call ludcmp(q,nbniv-1,nbniv-1,indx,d)
             call lubksb(q,nbniv-1,nbniv-1,indx,y)
    !     
             s0=1.0 ; s1=charge(i0)
             do i=1,i0-1
                pop(i)=y(i)
                !print*, pop(i)
    !     pause
                s0=s0+y(i)
                s1=s1+charge(i)*y(i)
             enddo
             pop(i0)=1.0
             do i=i0,nbniv-1
                pop(i+1)=y(i)
                s0=s0+y(i)
                s1=s1+charge(i+1)*y(i)
             enddo
    !     
     
     
             zmoy=s1/s0
             print *,"zmoy=",zmoy
             poptot=Ne/zmoy ; popi0=poptot/s0
             poptot0=poptot
             do i=1,nbniv
                pop(i)=pop(i)*popi0
                print *,i,pop(i)
             enddo
     
             sompop=0.
             do i=1,nbniv
                sompop=sompop+pop(i)
             enddo
     
     
             print*,'Ne',Ne,'Te',Te,'zmoy',zmoy
             !print*,'pop totale',poptot
     
             open(UNIT=38,file='evol_para_plasma_ini',form='formatted',status='old')
             write(38,'(a13,i4)') "Temps (en ns)", Z*50
             write(38,'(a5,F10.8)') "Zmoy=",zmoy
             write(38,'(a12)') "POPULATIONS"
     
             !print*, Ne, te
             do i=1,nbniv
                write(38,'(F30.5)') pop(i)
                print*,pop(i)
                !pause
             enddo
             write(38,*)
             close(38)
     
            open(35,file='evol_ioni',form='formatted',status='replace')
            write(35,'(e10.5)') zmoy
            close(35)
    !     
    !============================================================
    !     FIN DU PROGRAMME PRINCIPAL 
    !============================================================
     
             end subroutine modstat
    J'essaie de remédier également à ce problème de mon côté ...

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    J'ai compilé le tout de mon côté. Le nombre d'erreur est assez faible. Ne te décourage pas !

    J'aimerais cependant attirer ton attention sur les points suivants :
    • Tu fais des boucles avec des goto pour lire les données. Il serait beaucoup plus élégant (et facile d'entretien) d'utiliser des boucles do. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    do
       read(..., ioStat=k) ...
       if (k < 0) exit ! Fin de fichier atteinte
       ...
    enddo
    • Dans la fonction modstat, le paramètre poptot0 est déclaré intent(out). En faisant cela, tu dois obligatoirement fournir une interface explicite dans l'appelant. Si tu n'as pas d'erreur à la compilation, c'est que le compilateur ne voit pas modstat lors de la compilation de main, et il ne voit pas main à la compilation de modstat.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Merci sylvain pour ton aide, je pense que je supprimerais les boucles en goto après avoir optimisé le programme.

    Par contre je ne comprends pas ta phrase sur intent(out), peux tu préciser s'il te plait ?

    Sinon effectivement, tout se compile bien. Le problème est que quand je fais ceci :

    greg@gregs:~/Bureau/modeleCR_NStat_alu.d$ g95 -c -O3 *.f90
    In file main.f90:190

    56 goto 90
    1
    In file main.f90:77

    goto 56
    2
    Warning (104): Label at (1) is not in the same block as the GOTO statement at (2)
    In file main.f90:191

    57 continue
    1
    In file main.f90:114

    goto 57
    2
    Warning (104): Label at (1) is not in the same block as the GOTO statement at (2)

    greg@gregs:~/Bureau/modeleCR_NStat_alu.d$
    greg@gregs:~/Bureau/modeleCR_NStat_alu.d$ g95 -c *.f
    greg@gregs:~/Bureau/modeleCR_NStat_alu.d$ g95 -o go2 *.o
    Tout se passe bien, l'exécutable a été créé. Maintenant lançons le !

    greg@gregs:~/Bureau/modeleCR_NStat_alu.d$ ./go2
    Choisissez votre configuration : Modèle CR (1) / Forcer l''ETL (2)
    1
    Erreur de segmentation
    Non pitié, pas une erreur de segmentation ! Bref, à force de mettre des lignes pause dans main.f90, j'ai réussi à trouver le problème. Et, oh surprise, la ligne incriminée est celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    module Partage
      implicit none
      integer, parameter :: nbniv=220  !nb total de niveaux dans le modele CR
      integer, parameter :: nfreq=3000
      real, dimension(nbniv) :: ener,g
      integer, dimension(nbniv) :: n,charge,nlast,llast,nel_eq
      real, dimension(nbniv,nbniv) :: a
    end module Partage
    
    
    program main
      use Partage
      implicit none
      
      real, dimension(nbniv,nbniv) :: c,s,rrad,t
      real, dimension(nbniv-1,nbniv-1) :: q
      real, dimension(nbniv-1) :: y
      real, dimension(nbniv) :: pop,boltz
      integer, dimension(3) :: i0_ion
      integer, dimension(10) :: aa, bb
      real, dimension(10) :: corr_ener
      real :: eji,eij,fij,gaunt,te,Ne,x,exi1,vac,d,tps
      real :: s0,s1,zmoy,rap,tex,aux,poptot0,popi0,potion,lambda,zrad,deg
      real ::  hnumin,hnumax,pas,hplanck,clum,celec, aij, eV,corr,grnd,temp,densi
      integer :: k,i,j,i0,N_noy,kion,nb_niv,ii,jj,i_CR,iraie,ios,val,choix,choix2,Z
      real, dimension(:,:), allocatable :: mat
      real, parameter :: ryd=13.605804
      integer, dimension(nbniv-1) :: indx
      real (kind (0D0)) :: tt,xx
      character tex1*2,tex2*5,tex3*8,tex4*7,tex5*12,tex6*16,tex7*16,tex8*6
      real, dimension(nfreq) :: hnu,em,londe,intens
      
      ! ==========================================================
      ! Donnees:
      celec=1.6022e-19
      hplanck=6.6261e-34
      clum=3.e8
      grnd=6593.03515625
      ! ==========================================================
    
      print*, 'Choisissez votre configuration : Modèle CR (1) / Forcer l''''ETL (2)' 
      read(*,*) choix
      
    !============================================================================================================
      ! SECTION DES LECTURE DES DATAS AIJ ET ENERJ DES NIVEAUX
      !============================================================================================================
      
      ! Lecture des donnees des energies:
      open(14,file='Al1_ener_D',form='formatted',position='rewind',status='unknown')
      read(14,'(a2,i3,a5,i3,a8,f12.5,a7)')tex1,N_noy,tex2,kion,tex3,potion,tex4
      read(14,'(i4)')nb_niv
      do i=1,nb_niv
         i_CR=i_CR+1
         read(14,'(2i4,f15.8,f16.1,3i4)') ii,jj,ener(i_CR),g(i_CR),nlast(i_CR),llast(i_CR),nel_eq(i_CR)
         !print*, ener(i_CR)
         !print*,corr_ener(i_CR),ener(i_CR)
         !pause
         charge(i_CR)=0
      enddo
    
      !
      ! Lecture des taux de transitions radiatives:
    3 open(114,file='Al1_trad_D',form='formatted',position='rewind',status='unknown')
      read(114,'(a2,i3,a5,i3)')tex1,N_noy,tex2,kion
    1 read(114,'(2i4,2e14.5)',end=2)ii,jj,zrad,lambda
      !  zrad taux entre ii et jj en s-1, lambda, l.o. en angstrom
      if (choix==1 .or. choix==3) then
         a(ii,jj)=zrad
      else 
         a(ii,jj)=0.
      endif
      goto 1
    2 continue
      close(114)
    
      if (choix==3) then
         goto 56
      endif
      
    
      !
      ! ion suivant:
      i0_ion(2)=nb_niv+1
      
      !
      ! Lecture des donnees des energies:
      open(15,file='Al2_ener_D',form='formatted',position='rewind',status='unknown')
      read(15,'(a2,i3,a5,i3,a8,f12.5,a7)')tex1,N_noy,tex2,kion,tex3,potion,tex4
      read(15,'(i4)')nb_niv
      do i=1,nb_niv
         i_CR=i_CR+1
         read(15,'(2i4,f15.8,f16.1,3i4)') ii,jj,ener(i_CR),g(i_CR),nlast(i_CR),llast(i_CR),nel_eq(i_CR)
         charge(i_CR)=1
      enddo
      close(15)
      
      !
      ! Lecture des taux de transitions radiatives:
    90 open(115,file='Al2_trad_D',form='formatted',position='rewind',status='unknown')
      read(115,'(a2,i3,a5,i3)')tex1,N_noy,tex2,kion
    88 read(115,'(2i4,2e14.5)',end=89)ii,jj,zrad,lambda
      !  zrad taux entre ii et jj en s-1, lambda, l.o. en angstrom
      !    print *,ii,jj,zrad,lambda
      if (choix==1 .or. choix==3) then
         a(ii+i0_ion(2)-1,jj+i0_ion(2)-1)=zrad
      else 
         a(ii+i0_ion(2)-1,jj+i0_ion(2)-1)=0.
      endif
      goto 88
    89 continue 
      close(115)
      
      if (choix==3) then
         goto 57
      endif
      
      !
      ! ion suivant:
      i0_ion(3)=i0_ion(2)+nb_niv
      !
      open(16,file='Al3_ener_D',form='formatted',position='rewind',status='unknown')
      read(16,'(a2,i3,a5,i3,a8,f12.5,a7)')tex1,N_noy,tex2,kion,tex3,potion,tex4
      read(16,'(i4)')nb_niv
      do i=1,nb_niv
         i_CR=i_CR+1
         read(16,'(2i4,f15.8,f16.1,3i4)') ii,jj,ener(i_CR),g(i_CR),nlast(i_CR),llast(i_CR),nel_eq(i_CR)
         charge(i_CR)=2
      enddo
    
    if (choix2==1) then
       open (68,file='boltzmann_plot_general_alu',status='old')
       do i=1,nbniv
          boltz(i)=log(pop(i)/g(i))
          write (68,'(F30.5,F10.5)') ener(i), boltz(i)
       enddo
    endif
    close(68)
    
    !===============================================================================================================
    !
    !===============================================================================================================
    
      ios=0.
      val=0.
    
      open(10,file='donnes_LIBS_clair',form='formatted',status='unknown')
      read(10,'(a14,a15,a14)') tex6,tex7,tex8
      do while (ios==0)
         read(10,'(e16.7,e16.7,e16.7)',iostat=ios)tps,temp,densi
         val=val+1
      enddo
      close(10)
      
      open(10,file='donnes_LIBS_clair',form='formatted',status='unknown')
      read(10,'(a14,a15,a14)') tex6,tex7,tex8
      do Z=1,val
         read(10,'(e16.7,e16.7,e16.7)',iostat=ios) tps,densi,temp
         if (Z==1) then
            call modstat(temp,densi,choix,pop,poptot0)
            !pause
         else
            call modnonstat(temp,densi,choix,pop,poptot0)
            !pause
         endif
      enddo
      close(10)
    
      print *, 'Extraire un Boltzmann plot general ? (1) Oui / (2) Non'
      read(*,*) choix2
    
      if (choix2==2) stop
    
      i_CR=0
      i0_ion(1)=1 !indice du premier niveau dans un ion
      a=0.0 ; c=0.0 ; s=0.0 ; rrad=0.0 ; t=0.0
      
    
    !============================================================
    ! CALCUL DES EMISSIVITES DES RAIES (SPECTRE)
    !============================================================
    
    hnumin=1.8  ; hnumax=6.2 !eV  borne min=700 nm//borne max=200nm
    pas=(hnumax-hnumin)/float(nfreq-1)  
    em=0.0
    intens=0.0
    
    if(choix == 2) then
       choix=3
       goto 3      
    56 goto 90
    57 continue
    endif
    
    !
    ! contribution de toutes les transitions radiatives:
    
    open(09,file='Al_ener_D_corr',form='formatted',status='unknown')
    read(09,'(a11)') tex5
    aa=0.
    bb=0.
    corr_ener=0.
    do i=1,10
       read(09,'(i4,i2,f11.8)') ii, jj, corr
       aa(i)=ii
       bb(i)=jj
       corr_ener(i)=corr 
    enddo
    close (09)
    
    open(30,file='spectre_alu_pour_boltzplotLIBS',status='old')
    
    do i=1,nbniv
       do j=1,i-1
          val=0.
          do k=1,10
             if (i .ne. aa(k)) then 
                cycle
             else 
                if (j .ne. bb(k)) then 
                   cycle
                else   
                   eij=ener(i)-ener(j)+corr_ener(k)
                   !  print*, aa(k), bb(k), corr_ener(k), eij
                   !  pause
                endif 
             endif
             val=val+1.
          enddo
    
          if (val==0) then 
             eij=ener(i)-ener(j)  !! pas forcement superieur à 0 !
          endif
          
          iraie=int(((eij-hnumin)/pas))+1
    
          if(iraie<0.or.iraie>nfreq) cycle
          !      if (eij<0) pause
          em(iraie)=em(iraie)+pop(i)*a(i,j)*eij
          intens(iraie)=intens(iraie)+pop(i)*a(i,j)
          write(30,'(F15.10,F40.4)') ener(i)+grnd,intens(iraie)
          write(26,'(F8.5,F40.4)') ((iraie-1)*pas)+hnumin, a(i,j)
       enddo
    enddo
    
    close(26)
    close(30)
    
    do i=1,nfreq
       hnu(i)=hnumin+(i-1)*pas
       londe(i)=((hplanck*clum)/(hnu(i)*celec))*1e9
    enddo
    
    
    !=============================================================
    !                   ECRITURE DU SPECTRE
    !=============================================================
    
    open(25,file='spectre_alu',status='old')
    do i=1,nfreq
       write(25,'(F15.10,F40.4)') londe(i),em(i)
    enddo
    close(25)
    
    !=============================================================
    ! CLASSEMENT DE LA MATRICE DE FORT.26 
    !=============================================================
    
    open(26,file='fort.26',form='formatted',status='old')
    
    ios=0.
    val=0.
    
    do while (ios==0)
       read(26,'(F15.5,F40.4)',iostat=ios) eV, aij
       val=val+1   
    enddo
    
    allocate (mat(val,2))
    close(26)
    
    
    open(26,file='fort.26',form='formatted',status='old')
    
    do i=1,val
       read(26,'(F15.5,F40.4)',iostat=ios) mat(i,1), mat(i,2)
    enddo
    close (26)
    
    call tri_mat(mat,val,2)
    
    do i=1,val
       write(26,'(F8.5,F40.4)') mat(i,1), mat(i,2)
    enddo
    
    !
    !============================================================
    !    FIN DU PROGRAMME PRINCIPAL 
    !============================================================
    
    CONTAINS
      
      subroutine tri_mat(mat,n,m)
        
        implicit none
        
        integer              :: n,m
        real, dimension(n,m) :: mat
        integer              :: ligne
        
        !=========================================
        
        call tri_vecteur(mat,n)
        
      end subroutine tri_mat
      
      
      subroutine tri_vecteur(v,n)
        
        implicit none
        
        integer              :: n,i
        real, dimension(n,2) :: v
        logical              :: tri_termine
        
        
        do
           tri_termine=.true.
           
           do i=2,n
              if (v(i,1) < v(i-1,1)) then
                 tri_termine = .false.
                 v(i-1:i,1)=v(i:i-1:-1,1)
                 v(i-1:i,2)=v(i:i-1:-1,2)
              endif
           enddo
           if (tri_termine) exit
        enddo
        
      end subroutine tri_vecteur
      
    end program main
    Visiblement, le fait d'avoir déclaré les données en module, m'empêche de leur affecter une valeur !

  10. #10
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    Citation Envoyé par Benjamin Straw Voir le message
    je ne comprends pas ta phrase sur intent(out), peux tu préciser s'il te plait ?
    ...
    Tout se passe bien, l'exécutable a été créé. Maintenant lançons le !

    Non pitié, pas une erreur de segmentation ! Bref, à force de mettre des lignes pause dans main.f90, j'ai réussi à trouver le problème. Et, oh surprise, la ligne incriminée est celle-ci
    Résumons donc les interfaces en Fortran. Il y a 2 types d'interface à des fonctions / routines :
    • les interfaces implicites
    • les interfaces explicites

    L'interface implicite est l'interface de Fortran 77 (que tu peux encore utiliser en 90 et +). Avec cette interface, tu n'as généralement pas le droit de déclarer des paramètres formels de sous-programme avec les attributs F90+ (intent, optional, pointer, allocatable, dimension (: ), ...). On dit que l'interface est implicite parce que le compilateur ne la voit pas au moment de compiler l'appelant et qu'il fait des suppositions à partir de l'appel.

    L'interface explicite est par contre accessible au compilateur lorsqu'il compile l'appelant. Pour le générer, il y a 3 méthodes :
    • Tu place le sous-programme dans la section contains de l'appelant. Le compilateur va alors générer une interface tout seul et la rendre accessible lors de la compilation de l'appelant.
    • Tu place le sous-programme dans la section contains d'un module. Le compilateur va alors générer une interface tout seul et la placer dans le fichier .mod du module. Via le use du module, le compilateur aura alors accès à l'interface lors de la compilation de l'appelant.
    • Tu insères « à bras » l'interface dans l'appelant. ex: interface subroutine modstat... end interface


    Dans ton cas, tu utilises une interface implicite, mais tu utilises également un attribut de F90 (intent (out)). Le segmentation fault peut très bien venir de là. Le fait qu'il y ait erreur dans un read n'a pas nécessairement rapport...

    Compte tenu du lien entre le module Partage et les routines modstat, il serait logique de placer les routines dans une section contains dans le module Partage. Tu n'as qu'à insérer une ligne « contains » avant la ligne « end module », et tu insères ensuite tes 2 routines entre la ligne « contains » et la ligne « end module ». Dans chaque routine, tu dois ensuite enlever les use, puisque les routines sont déjà dans le module...

    Alternativement, tu pourrais essayer de simplement enlever les attributs « intent » de tes routines. Ça peut être plus rapide à court terme, mais c'est une solution très limitée. Les interfaces explicites sont vraiment une grande invention du F90.

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Merci d'avoir explicité.

    Pour ma part, j'essaie d'être assez pragmatique. Le regroupement des deux subroutines dans l'appelant va entrainer la création d'un seul fichier .f90, et ça je ne le souhaite pas, en raison de l'utilisation ultérieure de ce code. Je ne peux donc tout copier dans main.f90.


    Je vais préciser ce que je veux pour être tout a fait clair à la lumière de ce que tu m'as dit :


    - le paramètre poptot0 est un paramètre calculé dans la procédure MODSTAT, il doit absolument être un argument de sortie de la procédure, de façon à pouvoir être réutilisé lors de chaque utilisation de MODNONSTAT.

    - le vecteur pop est une première fois évalué dans MODSTAT, et doit être également ressorti de cette subroutine pour être utilisé dans MODNONSTAT. Passé la première utilisation de modnonstat, on va générer un nouveau vecteur pop, qui devra ressortir de façon à être réévalué à la prochaine utilisation (nous sommes dans une boucle) de MODNONSTAT.

    Donc si je comprends bien :


    1) Dans l'appel de modstat, je dois modifier le programme de façon à ne pas mentionner poptot0 et pop :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    call modstat(temp,densi,choix)
    Idem dans l'entête de MODSTAT ou je vire la mention poptot0 et pop. Et je rajoute :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    real, dimension(nbniv), intent(out) :: pop
    2) Dans l'appel de MODNONSTAT, je ne modifie rien, par contre, le principe du vecteur pop à la fois data d'entrée en début de subroutine, et data de sortie en fin de subroutine, me pose problème.

    Cela règlera t'il mon problème d'après toi ?

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Sylvain,

    Ne tiens pas compte de mon précédent message, sauf le passage concernant mes desideratas

    J'ai essayé de faire un truc un peu plus propre :


    - J'ai créé une interface explicite dans main.f90 par le biais d'un bloc interface copié à partir des déclarations en en-tête de modstat.f90 et modnonstat.f90 (où j'ai détaillé à mort la destinations des variables avec des intents massifs !). :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    program main
      use Partage
      implicit none
    ...
     
    !=============BLOC INTERFACE===============================================
      interface
         SUBROUTINE modstat(telec,dens,choix,pop,poptot0)
           use Partage
     
           implicit none
           integer :: k,i,j,i0,N_noy,kion,nb_niv,ii,jj,i_CR,iraie,ios,val
           integer :: choix,choix2,Z
           integer, dimension(3) :: i0_ion
           integer, dimension(10) :: aa, bb
           integer, dimension(nbniv-1) :: indx
           real :: eji,eij,fij,gaunt,te,Ne,x,exi1,vac,d
           real :: s0,s1,rap,tex,aux,popi0,potion,lambda,zrad,deg,poptot
           real :: hnumin,hnumax,pas,hplanck,clum,celec, aij, eV,corr,grnd
           real :: telec,dens,sompop,zmoy
           real, dimension(10) :: corr_ener
           real, dimension(nbniv,nbniv) :: c,s,rrad,t
           real, dimension(nbniv-1,nbniv-1) :: q
           real, dimension(nbniv-1) :: y
           real, dimension(nbniv) :: boltz
           real, intent(out) :: poptot0
           real, dimension(nbniv),intent(out) :: pop
           real, dimension(:,:), allocatable :: mat
           real, parameter :: ryd=13.605804
           real (kind (0D0)) :: tt,xx
           real, dimension(nfreq) :: hnu,em,londe,intens
           character tex1*2,tex2*5,tex3*8,tex4*7,tex5*12
         end subroutine modstat
      end interface
     
      interface
         SUBROUTINE modnonstat(telec,dens,choix,pop,poptot0)
           use Partage
           implicit none
           real :: eji,eij,fij,gaunt,te,Ne,x,exi1,vac,d,&
                s0,s1,rap,tex,aux,poptot,popi0,potion,lambda,zrad,deg,&
                hnumin,hnumax,pas,hplanck,clum,celec, aij, eV,corr,grnd, &
                telec,dens,deltaT,corr_pop,sompop,zmoy
           real, intent(in) :: poptot0
           real, parameter :: ryd=13.605804
           real (kind (0D0)) :: tt,xx
           real, dimension(10) :: corr_ener
           real, dimension(nbniv,nbniv) :: c,s,rrad,t
           real, dimension(nbniv-1,nbniv-1) :: q
           real, dimension(nbniv-1) :: y
           real, dimension(nbniv) :: boltz
           real, dimension(nbniv),intent(inout) :: pop
           real, dimension(nfreq) :: hnu,em,londe,intens
           integer, dimension(3) :: i0_ion
           integer, dimension(10) :: aa, bb
           integer :: k,i,j,i0,N_noy,kion,nb_niv,ii,jj,i_CR,iraie,ios,val
           integer :: choix,Z,U,nul
           integer, dimension(nbniv) :: indx
           character tex1*2,tex2*5,tex3*8,tex4*7,tex5*12,tex6*12,tex7*5
           character tex8*12,fichier*20,step*4
         end subroutine modnonstat
      end interface
     
      !===== FIN DU BLOC INTERFACE ================================================
     
    ...
    ...
    ...
     
    do Z=1,val
         read(10,'(e16.7,e16.7,e16.7)',iostat=ios) tps,densi,temp
         if (Z==1) then
            call modstat(temp,densi,choix,pop,poptot0)
            !pause
         else
            call modnonstat(temp,densi,choix,pop,poptot0)
            !pause
         endif
      enddo
    Normalement là tout est carré, à moins que le fait (pour pop et poptot0) d'appeler un argument d'appel de la même façon qu'un argument dummy soit rédhibitoire. A toi de me dire suivant ton expérience

    J'ai donc tout compilé et je n'ai eu aucune erreur. Par contre l'erreur de segmentation est toujours là, malgré mon interface explicite. La localisation de l'erreur n'a toujours pas changé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    read(14,'(2i4,f15.8,f16.1,3i4)') ii,jj,ener(i_CR),g(i_CR),nlast(i_CR),llast(i_CR),nel_eq(i_CR)

    Étant donné que plus haut dans le fichier, il y a toujours (avant même la ligne program main):


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    module Partage
      implicit none
      integer, parameter :: nbniv=220  !nb total de niveaux dans le modele CR
      integer, parameter :: nfreq=3000
      real, dimension(nbniv) :: ener,g
      integer, dimension(nbniv) :: n,charge,nlast,llast,nel_eq
      real, dimension(nbniv,nbniv) :: a
    end module Partage
    J'en conclus qu'il y a une incompatibilité entre le fait de mettre des données dans mon module commun, et le fait de vouloir leur attribuer une valeur. Je vais essayer de mettre dans le module toute la procédure permettant de lire et de stocker les valeurs de a, ener, g, nlast, llast, nel_eq et charge.

    Je te recontacte, mais a priori l'erreur de segmentation vient bien d'un conflit entre le module et cette partie de lecture qui n'est pas dans le module (pour le moment).



    EDIT :

    Copier toutes les lignes de lecture des data dans le module n'a aucun effet. Le compilo a alors un problème dès l'ouverture du fichier. Il semblerait qu'il faille faire une procédure ouvrant et lisant toutes les datas, avant de les stocker dans le module. Est-ce correct, et si oui comment faire ?

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Sujet (enfin) résolu, merci pour votre aide !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 08/11/2014, 17h50
  2. Plusieurs procédures appelant une procédure
    Par kakolac dans le forum Oracle
    Réponses: 6
    Dernier message: 13/07/2012, 17h29
  3. [AC-2003] Variables commune à plusieurs procédure
    Par DonKnacki dans le forum IHM
    Réponses: 2
    Dernier message: 04/05/2011, 11h30
  4. Réponses: 5
    Dernier message: 20/09/2005, 22h48
  5. ProgressBar avec plusieurs procédures
    Par elifqaoui dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 08/09/2002, 18h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo