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 :

Subroutines et Functions ?


Sujet :

Fortran

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Août 2011
    Messages : 28
    Points : 19
    Points
    19
    Par défaut Subroutines et Functions ?
    Bonjour à tous,

    Je suis en train d'élaborer un programme et dans celui-ci j'ai beaucoup de répétition qui pourraient être transformées en subroutine et en fonction.

    Je voudrais créer ces subroutines et ces fonctions dans des fichiers extérieurs (un fichier pour chaque fonction et subroutine) puis faire appel à ces subroutines dans le fichier principale. Cependant lorsque j'essaye cela ne marche pas.

    Est ce que quelqu'un pourrait me dire comment dois-je procéder pour effectuer cette manip ?

    J'aimerais également savoir comment je peux faire pour créer des subroutines dont mes variables d'entrée sont des matrices et mes variables de sortie sont également des matrices.

    Exemple :
    J'ai mes variables Pp et Qp qui ont été calculé précédemment dans le programme et avant de passer au pas de temps suivant j'actualise les variables Q et P par rapport au variable Pp et Qp.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    !Actualisation des variables dans la cana 10		
            Do i = 1, NS(10)
             Q(10,i) = Qp(10,i)
             P(10,i) = Pp(10,i)
     
            if (P(10,i) < 0) then
               P(10,i) = 0.1
             else
               P(10,i) = Pp(10,i)
    		end if
            end do

    En vous remerciant par avance pour l'aide que vous m'apporterez,

    Yu Cloud

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 152
    Points : 191
    Points
    191
    Par défaut
    Salut,

    Je voudrais créer ces subroutines et ces fonctions dans des fichiers extérieurs (un fichier pour chaque fonction et subroutine) puis faire appel à ces subroutines dans le fichier principale. Cependant lorsque j'essaye cela ne marche pas.

    Est ce que quelqu'un pourrait me dire comment dois-je procéder pour effectuer cette manip ?
    Pour ce faire, tu as deux possibilités :
    1. Créer des subroutines externes au programme que tu ranges dans des fichiers séparés

    2. Créer des modules contenant les subroutines que tu souhaites utiliser.

    Avantages/inconvénients :
    1. L'avantage est qu'il est extrêmement simple à mettre en oeuvre une telle option. Cependant, elle nécessite une recompilation constante de l'ensemble du code (ce qui dans certains cas peut être affreusement long). Qui plus est, il te faudra interfacer l'ensemble de ces routines à chaque fois qu'elles sont utilisées. En somme, cela ne consiste qu'à séparer dans différents fichiers des subroutines externes au lieu de toutes les mettre dans le même.

    2. Une seule compilation par mise à jour (si le fichier n'est pas modifié, il n'a pas besoin d'être recompilé). Inconvénients : un module doit être déclaré et compilé avec un ordre bien précis (surtout dans le cas de 'modules imbriqués'). Cependant, il suffit d'une syntaxe USE pour l'utiliser (pas besoin d'interfaces).

    J'aimerais également savoir comment je peux faire pour créer des subroutines dont mes variables d'entrée sont des matrices et mes variables de sortie sont également des matrices.
    Il suffit de déclarer une routine du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SUBROUTINE MaJ(MAT_IN,MAT_OUT)
    IMPLICIT NONE
    REAL(KIND=8),DIMENSION(:,:),INTENT(IN) :: MAT_IN
    REAL(KIND=8),DIMENSION(:,:), INTENT(OUT) :: MAT_OUT
    [... autre déclarations : variables internes au module, ...]
     
    [calcul]
     
    END SUBROUTINE MaJ
    En espérant avoir pu t'aider,

    Marlan

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Août 2011
    Messages : 28
    Points : 19
    Points
    19
    Par défaut
    Merci pour ton aide, pour les subroutines dans des fichiers séparé, je vais essayer ta deuxième solution qui a l'air plus simple et moins fastidieuse.

    Cependant j'ai encore quelques difficultés avec la subroutine pour les matrices.

    Si je reprends l'exemple que j'ai donné un peu plus haut, comment est ce que je dois insérer ma variable d'entrée dans le sous programme ? Pp(10,i) ?

    De plus comment est ce que je crée le corps du sous-programme ?

    Exemple :
    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
     
    SUBROUTINE Actualisation(Pp(10,i),Qp(10,i),Ns(10),P(10,i),Q(10,i))
    use MyKinds
     
    implicit none
    real(rkd),dimension(:,:),intent(IN)   :: Pp, Qp
    real(rkd),dimension(:,:), intent(OUT) :: P, Q
    integer(rkd),intent(in)  :: Ns
    integer(rkd)                          :: i
     
     
     Do i = 1, Ns
      Q(:,i) = Qp(:,i)
      P(:,i) = Pp(:,i)
     
      if (P(:,i) < 0) then
       P(:,i) = 0.1
      else
       P(:,i) = Pp(:,i)
      end if
     end do
     
    END SUBROUTINE Actualisation
    En te remerciant par avance,

    Yu Cloud

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 152
    Points : 191
    Points
    191
    Par défaut
    Salut,

    Essayes plutôt comme ceci :

    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
     
    SUBROUTINE Actualisation(Pp,Qp,Ns,P,Q)
    use MyKinds
     
    implicit none
    real(rkd),dimension(:,:),intent(IN)   :: Pp, Qp
    real(rkd),dimension(:,:), intent(OUT) :: P, Q
    integer(rkd),intent(in)  :: Ns
    integer(rkd)                          :: i
     
     
     Do i = 1, Ns
      Q(:,i) = Qp(:,i)
      P(:,i) = Pp(:,i)
     
      if (P(:,i) < 0) then
       P(:,i) = 0.1
      else
       P(:,i) = Pp(:,i)
      end if
     end do
     
    END SUBROUTINE Actualisation
    Explications :
    Les arguments que tu demandes en entrée doivent être du type entrant. C'est à dire que, dans ton cas Pp, Qp, ... sont des tableaux (déclarés comme dimension(:,). Or, quand tu demandais l'entrée dans ta sous routine, tu avais spécifié des choses comme Qp(10,i), ce qui signifie (sauf erreur de ma pars) que tu pointes un espace du tableau bien défini ie : un réel et non plus un tableau.

    De même, lorsque tu feras appel à la sous routine Actualisation, il faudra bien faire attention à ce que les variables d'entrées correspondent bien aux dimensions spécifiées. Exemple :
    Si tu définis une variable DIMENSION(:,:, :: Qp,Pp, ... (tableau à trois dimension)
    Alors lors de l'appel de ta sous routine, puisque Qp et Pp sont des tableaux à deux dimension (DIMENSION(:,), il te faudra employer une syntaxe du type :

    CALL ACTUALISATION(Pp(:,:,I),Qp(:,:,I), ...) afin de respecter les tailles de tableau.

    Maintenant, dans ton cas, j'imagine que tes variables sont déclarées dans le programme appelant comme : DIMENSION(N,M) :: Qp, Pp
    De fait, il te suffira d'appeler CALL Actualisatiàon(Pp,Qp, ...)

    En espérant t'avoir aidé,

    Marlan

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Août 2011
    Messages : 28
    Points : 19
    Points
    19
    Par défaut
    J'ai essayé ta méthode cependant je dois faire une erreur quelque part car cela ne fonctionne pas au niveau du if parce qu'il attend un scalaire dans l'expression.

    error #6512: A scalar-valued expression is required in this context.
    if (P(:,i) < 0) then
    --------^
    Comment est-ce que je peux faire pour résoudre ce léger petit détail ?

    De plus lorsque je retire le if pour voir ce que cela donne il m'informe :
    Attempt to call a routine with an incorrect or mising INTERFACE related to argumet number one, which needs to be declared as assumed-shape in both the caller and callee.
    J'ai donc essayer d'appeler le programme par diverses façons (call actualisation(Pp(:,,Qp(:,,N(:,,P(:,,Q(:,), actualisation(Pp(2,15),Qp(2,15),N(2),P(2,15),Q(2,15)), actualisation(Pp(:,i),Qp(:,i),N(:,i),P(:,i),Q(:,i))) mais cela n'a pas fonctionné et m'indique la même erreur.

    Comment est ce que je peux résoudre ce problème ?

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 488
    Points : 593
    Points
    593
    Par défaut
    Bonjour,

    Ainsi que le précise le message d'erreur:
    error #6512: A scalar-valued expression is required in this context.
    if (P(:,i) < 0) then
    --------^
    Une conditionnelle ne peut s'appliquer qu'à un scalaire, pas à un tableau.
    Il faut simplement faire une boucle pour gérer un élément à la fois, ou sinon utiliser l'instruction Fortran90 "where" faite pour manipuler les tableaux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    where ( P < 0. )
      P = 0.1
    elsewhere
      P = Pp
    end where
    Bonne continuation.

Discussions similaires

  1. implicit declaration of function
    Par guillaume_pfr dans le forum C
    Réponses: 7
    Dernier message: 12/06/2003, 10h59
  2. [POSTGRESQL] exec function
    Par peuh dans le forum Requêtes
    Réponses: 5
    Dernier message: 23/05/2003, 15h15
  3. A propos des 'File management Functions' de Windows
    Par znaidi dans le forum Windows
    Réponses: 3
    Dernier message: 01/04/2003, 16h01
  4. [postgreSQL] équivalent de la function 'instr'
    Par Dra_Gun dans le forum Requêtes
    Réponses: 2
    Dernier message: 17/01/2003, 16h09
  5. [Dev c++ 4] implicite declaration of function "int kbhi
    Par Torpedox dans le forum Dev-C++
    Réponses: 5
    Dernier message: 01/01/2003, 13h37

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