8. Utilitaires de levée d’exception#

En cours d’écriture

Les utilitaires UTEXCP et UTEXCM permettent de lever une exception python depuis le fortran et de la transmettre au jeu de commande. Cette exception peut être récupérée dans le fichier de commande (ou une macro-commande) par un bloc try/except.

Les exceptions étant des cas particuliers d’erreur <F>, si elles ne sont pas récupérées, le superviseur termine le calcul comme après une erreur <F> ordinaire (fermeture et recopie de la base). Seule l’exception FatalError échappe à la règle puisqu’elle équivaut à une erreur <F> (et encore on verra un peu plus loin que ce comportement est modifiable).

Le mécanisme d’exception permet d’essayer une commande puis de reprendre la main si celle-ci échoue en levant une exception particulière.

Ce fonctionnement est particulièrement utilisé dans les macro-commandes, soit pour se comporter différemment selon le contexte, soit pour émettre un message plus parlant à l’utilisateur que celui qui aurait été émis par une commande fille.

Remarque:

L’utilisation des exceptions et surtout des blocs try / except n’a de sens qu’en mode PAR_LOT=’NON’

8.1. Mise en œuvre dans le source#

On présente ici la mise en œuvre du mécanisme des exceptions dans le source fortran et python du point de vue du développeur. On abordera un peu plus bas les exceptions avec la vision “utilisateur” (§ 8.4 ).

Pour la description de ce qu’est une exception, les mécanismes de levée (raise) et d’interception (except), on se reportera à la Description des exceptions du Tutorial Python.

“Lever une exception” signifie émettre un signal avec (souvent) des éléments de contexte pour permettre au programme appelant de réagir ainsi :

  • je comprends le signal et je prends telle décision en conséquence

  • je ne comprends pas le signal et je m’arrête (en émettant un autre signal au programme appelant du niveau supérieur)

  • j’ignore le signal et je laisse le programme appelant du niveau supérieur traiter le signal

Et ainsi de suite, sachant qu’au plus haut, c’est l’interpréteur Python lui-même qui prendra la décision d’interrompre l’exécution.

Syntaxiquement et schématiquement, le fonctionnement est le suivant :

try:


...

Instructions à exécuter qui peuvent par exemple lever 3 exceptions

différentes : UneExceptionParticulière, UneAutreException, EncoreUneAutre

...


except UneExceptionParticulière, arguments:


...

On exécutera ces instructions si l'exception "UneExceptionParticulière" est levée. On peut utiliser les "arguments" utilisés lors de la levée de l'exception.

Dans le cas le plus simple (et fréquent), "arguments" est un message qui peut être imprimé avec "print" ou utilisé comme chaîne de caractères avec "str(arguments)".

...


except UneAutreException, arguments2:


...

Instructions à exécuter si l'exception UneAutreException est levée.

...

Supposons que le bloc d’instructions sous le try lève l’exception EncoreUneAutre (qui n’est pas interceptée par un bloc except), l’exécution s’arrête avec un message du type :

Traceback (most recent call last):

File ".......", line 3, in <.......> <<<     permet de dire où s'est                                                             produite l'exception

EncoreUneAutre: ...... <<<     éléments de contexte                                                                 (arguments) fournissant

des détails sur les raisons de la levée d’exception

Pour les autres mécanismes, try/finally ou try/except/else, on se reportera à la documentation Python.


8.1.1. Levée d’exception dans Code_Aster#

Le plus simple : en Python, c’est-à-dire dans le fichier de commandes ou dans une macro-commande, il suffit de faire :

if nbre_iterations > nbre_maxi_autorise:

raise aster.NonConvergenceError, "Absence de convergence avec le nombre d'itérations autorisé"

Dans le source fortran (exemple dans nmerro.f qui traite les erreurs dans STAT_NON_LINE) :

...

ELSE IF (ITEMAX) THEN

CALL UTEXCP(22,'MECANONLINE_83')

...

où

  • 22 est le numéro de l’exception

  • ‘MECANONLINE_83’ est l’identifiant du message à imprimer

En effet, les exceptions propres à Code_Aster sont numérotées pour être accessibles facilement depuis le fortran :


numéro de l’exception

Description

Nom de l’exception dans le module aster

Type erreur

20

Erreur fatale

FatalError

F

21

Erreur non fatale

error

F

22

Non convergence

NonConvergenceError

F

23

Echec intégration du comportement

EchecComportementError

F

24

Bande de fréquence vide

BandeFrequenceVideError

F

25

Matrice singulière

MatriceSinguliereError

F

26

Echec de traitement du contact

TraitementContactError

F

27

Matrice de contact non inversible

MatriceContactSinguliereError

F

28

Manque de temps CPU

ArretCPUError

F

29

Echec du pilotage

PilotageError

F


Remarques

Les exceptions sont définies dans le module aster (astermodule.c). Ainsi, on y accède par aster.error.

A part FatalError, toutes les exceptions dérivent de errorqui représente donc l’enveloppe des erreurs <F>.

Le comportement en cas d’erreur fatale (FatalError ) est modifiable par l’utilisateur [U1.03.01], ce choix est déterminé dans les commande DEBUT/POURSUITE [U4.11.01],[U4.11.03] mot-clé facteur ERREUR_F. Dans les macro-commandes, on utilisera la fonction aster.onFatalError(arg)pour modifier ce comportement.

8.2. Levée d’une exception avec impression d’un message#

CALL UTEXCP( CODE, IDMESS )

CODE

IN

Numéro de l’exception

IDMESS

IN

Identificateur du message

Exemple :

CALL UTEXCP(23,”CHATON_7”)

8.3. Levée d’exception avec impression de messages et de valeurs de type caractères, entières et réelles#

CALL UTEXCM( CODE, IDMESS, NK, VALK, NI, VALI, NR, VALR)

CODE

IN

numéro de l’exception

IDMESS

IN

Identificateur du message

NK

IN

Nombre de paramètres de type caractère

VALK

IN

Valeurs des paramètres de type caractère

NI

IN

Nombre de paramètres de type entier

VALI

IN

Valeurs des paramètres de type entier

NR

IN

Nombre de paramètres de type réel

VALR

IN

Valeurs des paramètres de type réel

Exemple :

VALI (1) = NDIM1

VALI (2) = NDIM2

VALR = 5.D0

CALL UTEXCM(24,'CHATON_12', 0,' ',2, VALI,1,VALR)

8.4. Exemple d’utilisation#

Dans cet exemple, on souhaite :

  • en cas de non-convergence de STAT_NON_LINE, relancer les calculs en augmentant le nombre d’itérations,

  • arrêter les calculs si une autre erreur se produit.

Cette utilisation est illustrée dans le cas-test ssnp125a.


Programmation

On lève l’exception NonConvergenceError qui porte le numéro 22 :

...

ELSE IF ((.NOT.CONVER) .AND. ITEMAX .AND. (.NOT.ARRET)) THEN

ITAB(1) = NUMORD

ITAB(2) = ITERAT

CALL UTEXCM(22,'MECANONLINE_85', 0, K8B, 2, ITAB, 0, RTAB)

END IF

Fichier de commande

try :

STATNL=STAT_NON_LINE(...)


except aster.NonConvergenceError, message:

# non convergence

print "on continue en augmentant le nombre d'itérations"

STATNL=STAT_NON_LINE(reuse=STATNL,

...

CONVERGENCE=_F(ITER_GLOB_MAXI=400,)

…)

Fichier message : mecanonline.py

85 : _(u"""

Arret : absence de convergence au numéro d'instant : %(i1)d

lors de l'itération : %(i2)d

"""),

Message imprimé

!-----------------------------------------------------------------------!

! <EXCEPTION> <MECANONLINE_85> !

! !

! !

! Arret : absence de convergence au numéro d'instant : 123 !

! lors de l'itération : 51 !

! !

! !

!-----------------------------------------------------------------------!