Simulation is more than Software

Version d’essai
0
Liste de souhaits
0 0
Panier

Contact direct
FR

Tech Article | 23/07

Scripting Python dans Ansys Discovery - Seulement pour les programmeurs?

Vous êtes-vous déjà retrouvé dans cette situation ? La modélisation géométrique dans Ansys Discovery est en cours, et la même séquence d'opérations doit être répétée à maintes reprises. Cela peut être agaçant, n'est-ce pas ? Imaginez un instant si ces tâches répétitives pouvaient être prises en charge par une automatisation. Et si je vous disais qu'un guide en un clic peut vous être proposé pour vous initier au scripting dans Ansys Discovery ? Attention, à la fin de ce guide, vous verrez que ce type d’automatisation est tout à fait accessible et que vous ne pourrez plus vous en passer.

De l'idée au premier script Python

Lorsque nous pensons à la programmation, des images de lignes de code s'affichant à l'écran nous viennent à l'esprit. Surtout si l'on n'a pas eu beaucoup de contacts avec Python ou tout autre langage de programmation, les obstacles peuvent être grands pour commencer à écrire la première ligne de code. Avec cet article, j'aimerais vous guider à travers le processus de création d'un script Python pour la création de géométrie et je serais heureux si, en lisant l'article, vous l'essayiez directement dans Ansys Discovery.

Imaginons que nous devions remplir un cylindre hydraulique avec des rondelles-ressorts. L'espace de construction est donné et la meilleure configuration en termes de nombre, de disposition et d'épaisseur des ressorts doit être déterminée par simulation. Comme il faut calculer un grand nombre de conceptions différentes, il est beaucoup trop compliqué de recréer manuellement chaque paquet de ressorts. La première étape de la création automatisée de la géométrie est toujours de réfléchir à la manière dont nous procéderions manuellement dans le logiciel. Nous dessinerions une rondelle-ressort, puis une deuxième avec un nouveau centre, nous la retournerions éventuellement et, en répétant plusieurs fois, nous composerions ainsi le paquet de ressorts. Nous allons maintenant mettre en œuvre ces étapes de manière programmatique.

De quelles connaissances de Python ai-je besoin pour le scripting dans Discovery ? Pour commencer, les bases absolues suffisent :

  • Boucles For
  • instructions If
  • les listes

Celui qui sait encore ce qu'est une fonction peut mieux structurer son code. Le fait qu'il s'agisse d'IronPython 2.7 ne vaut tout d'abord qu'une remarque marginale, car les différentes variantes de Python ne se distinguent guère au niveau des bases.

disc spring construction discovery

L'éditeur de scripts dans Discovery

Pour le scripting dans Discovery, nous avons besoin de l'éditeur de scripts, qui est installé par défaut. Pour ce faire, allez dans le menu principal de Discovery et ouvrez l'éditeur de scripts. L'éditeur de scripts est divisé en deux parties. Dans la zone supérieure, le script est écrit, dans la zone inférieure se trouve la console. La console nous donne un feedback sur notre script. Il peut s'agir de valeurs de sortie, mais aussi de messages d'erreur.

Pour un premier exercice, nous allons entrer une commande print dans la zone de script :

print("Hello World!")

Si nous exécutons le script en cliquant sur le triangle vert dans le coin supérieur droit, notre texte apparaît en sortie dans la console.

Le bouton d'enregistrement de l'éditeur de scripts - ton ami et assistant

Nous voulons maintenant faire construire notre première rondelle-ressort par le script. Résumons brièvement comment nous procéderions manuellement. Nous ferions

  1. passer en mode Esquisse
  2. dessiner un parallélogramme
  3. passer en mode solide
  4. utiliser l'outil Pull pour faire pivoter la surface obtenue de 360°.

Lorsque l'éditeur de script s'ouvre, le bouton d'enregistrement est déjà activé. Nous commençons maintenant à esquisser le ressort et observons ce que l'éditeur de scripts enregistre. Le passage du mode solide au mode esquisse est encore bien lisible :

sectionPlane = Plane.PlaneXY
result = ViewHelper.SetSketchPlane(sectionPlane, None)

Nous prenons le plan XY et y plaçons notre plan d'esquisse. Lorsque nous commençons à dessiner le parallélogramme, le script a l'air assez sauvage au premier abord, car toutes les contraintes générées automatiquement sont également enregistrées. Nous pouvons toutefois désactiver les contraintes et obtenir un script bien lisible. Deux points sont créés et reliés en une ligne. Le tout se répète quatre fois.

start = Point2D.Create(MM(10), MM(10))
end = Point2D.Create(MM(10), MM(6))
result = SketchLine.Create(start, end)

L'éditeur de script travaille en unités SI. Pour nous épargner des conversions, nous pouvons indiquer la bonne unité directement dans le script. Dans l'étape suivante, nous repassons en mode solide.

mode = InteractionMode.Solid
result = ViewHelper.SetViewMode(mode, None)

Ensuite, la rondelle-ressort reçoit son design définitif via la fonction pull. Nous reviendrons plus en détail sur les trois premières lignes de l'extrait de code dans la section suivante.

selection = Face1
axisSelection = Axis1
axis = RevolveFaces.GetAxisFromSelection(selection, axisSelection)
options = RevolveFaceOptions()
options.ExtrudeType = ExtrudeType.Cut
result = RevolveFaces.Execute(selection, axis, DEG(360), options)

La seule chose qui manque encore est de placer au tout début du script une commande pour nettoyer le graphique. Le script démarre alors toujours avec un vide.

ClearAll()

La bonne nouvelle, c'est que nous n'avons pas besoin d'apprendre par cœur ou de chercher la plupart de ces commandes, mais que l'éditeur de scripts nous fournit presque toutes les commandes via la fonction d'enregistrement et que nous pouvons développer nos scripts à partir de là. Mais il est toujours recommandé de regarder de plus près ce qui a été enregistré et de faire le ménage.

Révision et nettoyage du scripte

Dans le développement de logiciels, le nettoyage et la réorganisationdu code source permettent d'améliorer la lisibilité et la maintenabilité du code. Permettez-moi de vous montrer la procédure à l'aide de notre exemple. En mode Esquisse, des points sont créés pour dessiner des lignes. Il est ici judicieux de regrouper les définitions Point2D et de les rendre plus flexibles grâce à des variables pour les dimensions. Ainsi, le script pour la partie esquisse a déjà l'air plus clair :

D = MM(10)
D1 = MM(20)
H = MM(1)
H1 = MM(2)

ClearAll()
sectionPlane = Plane.PlaneXY
result = ViewHelper.SetSketchPlane(sectionPlane, None)

point1 = Point2D.Create(D/2, H1)
point2 = Point2D.Create(D1/2, H1-H)
point3 = Point2D.Create(D1/2, 0)
point4 = Point2D.Create(D/2, H)

result = SketchLine.Create(point1, point2)
result = SketchLine.Create(point2, point3)
result = SketchLine.Create(point3, point4)
result = SketchLine.Create(point4, point1)

La deuxième partie du script traite de l'opération pull. Pour cela, nous avons besoin de la surface qui se forme à partir des quatre lignes lors du passage en mode solide. D'une part, nous pouvons accéder à la surface via les variables intelligentes (ce sont les variables magenta dans le script). D'autre part, nous pourrions définir la sélection par la position dans l'arborescence, en parcourant la liste des corps et, à partir de là, la liste des faces. Comme Python commence toujours à compter à partir de zéro, le premier corps dans l'arborescence est à l'emplacement 0 de la liste. GetRootPart() est toujours le niveau supérieur de l'arborescence :

face_selection = FaceSelection.Create(GetRootPart().Bodies[0].Faces[0]

Contrairement aux variables intelligentes, la sélection basée sur l'index montre certes de manière transparente dans le script où l'on se trouve dans l'arborescence, mais elle est instable par rapport aux modifications de l'arborescence lorsque des corps sont ajoutés ou supprimés n fois. Il se peut alors que l'index change. Il existe une troisième variante pour accéder aux objets, qui est à mon avis la plus stable. Dans les scripts enregistrés, les commandes sont très souvent précédées de "result = " et ces variables result ne sont pas des variables mortes, mais contiennent souvent des informations utiles que nous pouvons réutiliser. Dans notre cas, le passage en mode solide nous permet d'emporter d'accéder directement à la surface obtenue.

mode = InteractionMode.Solid
result= ViewHelper.SetViewMode(mode, None)
body =result.CreatedBodies[0]

L'opération pull nécessite encore l'axe de rotation. Dans le script enregistré, l'axe est d'abord sélectionné, puis l'axe géométrique est déduit de cette sélection. Nous y parvenons aussi de manière plus directe. Si nous passons la souris sur « l'Eexecute » de RevolveFaces.Execute, nous voyons que l'axe attendu est une "ligne". Très souvent, on peut taper au hasard "Line.Create(" dans l'éditeur de scripts et on est alors guidé par les textes d'indication de l'autocomplétion.

selection = FaceSelection.Create(body.Faces[0])
axis = Line.Create(Point.Origin, Direction.DirY)
options = RevolveFaceOptions()
options.ExtrudeType = ExtrudeType.Cut
result = RevolveFaces.Execute(selection, axis, DEG(360), options)

Toujours plus haut avec les boucles « for »

Nous avions prévu d'utiliser le script pour empiler plusieurs rondelles-ressorts les unes sur les autres. Tout le monde peut en empiler une seule, nous n'avons pas besoin de script pour cela. 😉 Les rondelles ressorts doivent être placées sur le même axe, seule la hauteur doit varier. Si nous empilons n ressorts les uns sur les autres, le n-ième ressort aura une hauteur de x +i*H1.

Le mieux est d'écrire la création du ressort dans une fonction. Les fonctions en Python se caractérisent par le fait qu'elles commencent par def, suivi d'un nom de fonction et éventuellement de variables entre parenthèses. À la fin de la ligne, il y a deux points. Contrairement à C++ ou à d'autres langages de programmation, Python renonce aux accolades ou autres pour marquer le début et la fin d'une fonction. Au lieu de cela, tout ce qui appartient à la fonction est mis en retrait par une tabulation (équivalent à quatre espaces).

Nous pouvons maintenant tricoter une boucle for autour de notre fonction. Notre boucle for commence par "for i in range(n) :". range(n) est une fonction Python standard pour créer des listes. Ces listes vont de 0 à n-1, a donc n éléments. Même principe que pour la fonction : tout ce qui appartient à la boucle for est indenté d'un arrêt de tabulation. Selon la taille que nous choisissons pour n, notre empilement de ressorts sera plus ou moins haut. N'hésitez pas à essayer le script suivant directement dans Discovery :

ClearAll()

def create_disc_spring(i):
    D = MM(10)
    D1 = MM(20)
    H = MM(1)
    H1 = MM(2)

    sectionPlane = Plane.PlaneXY
    result = ViewHelper.SetSketchPlane(sectionPlane, None)

    point1 = Point2D.Create(D/2, H1+i*H1)
    point2 = Point2D.Create(D1/2, H1-H+i*H1)
    point3 = Point2D.Create(D1/2, 0+i*H1)
    point4 = Point2D.Create(D/2, H+i*H1)

    result = SketchLine.Create(point1, point2)
    result = SketchLine.Create(point2, point3)
    result = SketchLine.Create(point3, point4)
    result = SketchLine.Create(point4, point1)

    mode = InteractionMode.Solid
    result = ViewHelper.SetViewMode(mode, None)
    body = result.CreatedBodies[0]

    selection = FaceSelection.Create(body.Faces[0])
    axis = Line.Create(Point.Origin, Direction.DirY)
    options = RevolveFaceOptions()
    options.ExtrudeType = ExtrudeType.Cut
    result = RevolveFaces.Execute(selection, axis, DEG(360), options)

n = 10
for i in range(n):
    create_disc_spring(i)

Optimiser l’empilement de ressorts avec des instructions if

Pour empiler des ressorts opposés en alternance, nous devons dessiner un ressort sur deux en sens inverse. Nous devons donc voir si i est pair ou impair dans l'exécution actuelle de la fonction. Mathématiquement, cela peut être fait assez facilement avec Modulo et en Python, il existe également le caractère spécial %. Si notre nombre est pair, alors 4%2 = 0, s'il est impair, alors 5%2 = 1.

Il en va de l'instruction if comme de la boucle for. Tout le code qui suit en retrait appartient à l'instruction if/else.

ClearAll()

def create_disc_spring(i):
     D = MM(10)'
     D1 = MM(20)
     H = MM(1)
     H1 = MM(2)

    sectionPlane = Plane.PlaneXY
    result = ViewHelper.SetSketchPlane(sectionPlane, None)

    if i%2 == 0: # i is even
        point1 = Point2D.Create(D/2, H1+i*H1)
        point2 = Point2D.Create(D1/2, H1-H+i*H1)
        point3 = Point2D.Create(D1/2, 0+i*H1)
        point4 = Point2D.Create(D/2, H+i*H1)

    else:        # i is odd
       point1 = Point2D.Create(D/2, H1-H+i*H1)
       point2 = Point2D.Create(D1/2, H1+i*H1)
       point3 = Point2D.Create(D1/2, H+i*H1)
       point4 = Point2D.Create(D/2, 0+i*H1)

    result = SketchLine.Create(point1, point2)
    result = SketchLine.Create(point2, point3)
    result = SketchLine.Create(point3, point4)
    result = SketchLine.Create(point4, point1)

    mode = InteractionMode.Solid
    result = ViewHelper.SetViewMode(mode, None)
    body = result.CreatedBodies[0]

    selection = FaceSelection.Create(body.Faces[0])
    axis = Line.Create(Point.Origin, Direction.DirY)
    options = RevolveFaceOptions()
    options.ExtrudeType = ExtrudeType.Cut
    result = RevolveFaces.Execute(selection, axis, DEG(360), options)

n = 10
for i in range(n):
    create_disc_spring(i)

Aperçu des paramètres et des boutons customisés dans Ansys Discovery

Quelle est maintenant la suite du script ? L’empilement de ressorts doit encore être installé dans lea cylindrée. Nous pouvons également mesurer la hauteur du cylindre à l'aide d'une commande. Si, par exemple, huit ressorts Belleville doivent être montés, il faut encore faire un peu de mathématiques pour calculer la hauteur H1 appropriée. Cela devient encore plus intéressant lorsque nous commençons à paramétrer le tout. Il est possible de définir des paramètres de script, que nous pouvons également contrôler via le gestionnaire de paramètres sur la page de projet Workbench. La paramétrisation permet également de créer un lien avec optiSLang.

Une autre possibilité consiste à enregistrer le script en tant que « user bouton » dans la barre d'outils Discovery. Vous l'aurez ainsi toujours à portée de main lorsque vous en aurez besoin. En outre, vous pouvez également écrire des informations pour les boutons customizés à l'aide de l'InputHelper. L'utilisateur peut alors, après avoir cliqué sur le bouton, indiquer par exemple le nombre de ressorts via l'interface graphique. Les boutons customisés peuvent également être transmis à des collègues. Cela présente l'avantage que toute personne souhaitant utiliser de tels assistants ne doit pas nécessairement maîtriser le scripting dans Discovery.

Alors, vous avez trouvé ça compliqué ? Si vous dites que ça s'est plutôt bien passé, n'hésitez pas à laisser tourner l'éditeur de scripts lorsque vous utilisez Discovery. Observez quelles commandes sont enregistrées et si vous pouvez en tirer profit. N'hésitez pas non plus à jeter un coup d'œil aux formations indiquées ci-dessous, qui vous offrent la possibilité d'apprendre Python avec d'autres participants. Et si vous appréciez les avantages de l'automatisation, mais que vous vous sentez un peu trop incertain pour vous lancer dans la programmation, n'hésitez pas à nous contacter. Nous trouverons ensemble une solution.

Autheur

Application Engineer

Publié: October 2023

 

Editorial
Dr.-Ing. Marold Moosrainer
Head of Professional Development

Images de couverture:
Droite: © CADFEM Germany GmbH
Liens: © Adobe Stock

PLUS D'INFORMATIONS