Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Opérateurs de comportement

Le module ops::element_field::behavior intègre la loi de comportement d’un Model — le COMP de cast3m (« intégrer le comportement ») ; l’opérateur ops::node_field::internal_forces en calcule les forces internes — le BSIG de cast3m (∫ Bᵀ σ).

integrate_behavior(model, deformation, materials, prev=None, dt=None) → ElementField

Là où stiffness produit la linéarisation du modèle (une matrice), integrate_behavior produit la réponse ponctuelle exacte comme champ aux points de Gauss.

C’est un montage incrémental A → B : la loi intègre le comportement entre l’état convergé du début de pas A et la déformation de fin de pas B.

  1. l’entrée de déformation ε(B) est construite séparément et géométriquement par gradient (∇T…), deformation (ε), beam_deformation (κ, γ) ou shell_deformation (ε, κ, γ) — ces opérateurs ne dépendent que de l’espace EF, pas du modèle ; le choix de quelle déformation nourrir reste donc à l’appelant ;
  2. prev est l’état convergé de A — la sortie du pas précédent : la contrainte σ(A), les variables internes VAR(A) et la déformation ε(A). Il vaut None au premier pas, où A est la configuration de référence (σ(A)=0, ε(A)=0) ;
  3. dt est l’incrément de temps, None pour une loi indépendante du temps (une loi visqueuse future erreurera s’il vaut None) ;
  4. integrate_behavior prend ces entrées plus le matériau par zone et applique la loi de chaque physique point par point ;
  5. il renvoie l’état matériau de B : le flux / la contrainte dual(e) plus les variables internes mises à jour VAR1 — le champ à réinjecter comme prev au pas suivant.

Les sous-modèles de contrainte (Dirichlet…) sont ignorés : un sous-modèle participe ssi il déclare un espace EF de comportement. Les zones de déformation, de matériau et d’état précédent sont appariées par sous-espace EF.

Pourquoi le montage incrémental ? Fournir l’état de A séparément de la déformation de B (plutôt que fusionnés dans un même champ) rend le fil d’état robuste — un ElementField = une zone par support, sans ambiguïté — et ouvre les grandes déformations et les lois visqueuses : elles exigent l’accès à σ(A) et à un incrément daté, que cette interface porte déjà. En petites déformations le prédicteur incrémental σ_trial = σ(A) + C:Δε est rigoureusement identique à la forme en déformation totale.

Pour une loi linéaire, le résultat est cohérent avec stiffness (∫ Bᵀ·flux = K·u) ; une loi non linéaire s’écarte de cette tangente — c’est tout l’intérêt d’intégrer le comportement exactement.

Boucle multi-pas (fil d’état)

state = None  # VAR0 = prev; None at the first step
for step in range(1, nsteps + 1):
    ...  # the step's load → Newton loop on u
    eps = pyrucast.element_field.deformation(u, fes)  # ε(B)
    out = pyrucast.element_field.integrate_behavior(model, eps, materials, prev=state)
    ...  # F_int (BSIG), résidu, correction de u
    state = out  # commit: prev ← VAR1 for the next step

Exemple : efforts de section d’une poutre

# Solution (w, theta) already obtained from the solver.
eps = pyrucast.element_field.beam_deformation(solution, fes, materials)  # (κ, γ)
forces = pyrucast.element_field.integrate_behavior(model, eps, materials)
# forces porte le moment M = E·I·κ et l'effort tranchant V = G·A_s·γ.

Exemple : résultantes d’une coque

Le même montage, avec la formulation en argument : ce sont ses lignes de flexion qui distinguent thick de kirchhoff.

# Solution (six DOFs per node) already obtained from the solver.
eps = pyrucast.element_field.shell_deformation(solution, fes, "thick")
forces = pyrucast.element_field.integrate_behavior(model, eps, materials)
# forces carries the membrane resultants N, the bending ones M, the
# vrillage M_drill, et — en `thick` — l'effort tranchant Q.

Les pages Barre, Élasticité et Timoshenko détaillent l’intégrande de comportement (COMP) de chaque physique. Pour les lois non linéaires avec variables internes (VAR0 → VAR1), voir Plasticité parfaite (retour radial von Mises) et Endommagement de Mazars.

internal_forces(model, state) → NodeField

Les forces internes f = ∫ Bᵀ σ dΩ (le BSIG de cast3m) sont la transposée de l’opérateur de déformation B : là où deformation applique B au déplacement (ε = B·u), internal_forces applique Bᵀ à la contrainte et rassemble le résultat aux nœuds. C’est la généralisation mécanique de divergence (qui est exactement Bᵀ q pour un transport scalaire) : une composante de sortie par DDL dual.

state est le champ d’état matériau renvoyé par integrate_behavior. Chaque sous-modèle porteur d’un comportement applique son propre Bᵀ — c’est pourquoi l’opérateur prend un modèle et pas un simple espace EF : un même SEG2 peut être une barre (Bᵀ axial, DDL déplacement) ou une poutre (Bᵀ à deux quadratures flexion + cisaillement, DDL w, θ), et seul le modèle tranche. Solides continus, barres et poutres sont donc tous couverts.

Pour une loi linéaire, le résultat égale la rigidité appliquée à la solution (K·u) ; pour une loi non linéaire, il donne les forces internes exactes.

C’est le côté intérieur du bilan Σ f_int = Σ f_ext, dont l’écart est le résidu d’équilibre. Le miroir nodal de stiffness : là où l’assemblage demande à chaque sous-modèle ses blocs de ∂r/∂u, celui-ci lui demande son terme de r. Un sous-modèle qui n’a pas de terme de ce côté n’en déclare aucun et n’apparaît pas dans le résultat.

# Solution already obtained from the solver.
eps = pyrucast.element_field.deformation(solution, fes)  # ε = B·u
sig = pyrucast.element_field.integrate_behavior(model, eps, materials)  # COMP : σ
f_int = pyrucast.node_field.internal_forces(model, sig, solution, materials)
# L'autre côté du bilan. L'élasticité seule n'a aucun terme donné : le champ
# comes back empty, and everything external comes from the hand-built loading.
f_ext_modele = pyrucast.node_field.external_forces(model, materials)
residu = f_ext - f_int  # Σ f_ext − Σ f_int

external_forces(model) → NodeField

L’autre côté du bilan : la donnée de chaque terme, à droite du signe égal. Une physique dont le terme n’est qu’une réponse à u — élasticité, conduction, barre — n’en a aucun, si bien qu’un modèle qui n’en contient que de celles-là rend un champ vide, ce qui est la réponse juste et non un échec.

Séparer les deux côtés est ce qui garde les signes hors des fichiers de physique
l’auteur écrit ses deux moitiés positivement, comme la forme faible se lit, et l’unique soustraction vit chez l’appelant. De quel côté un terme se range est une question de physique — le côté du signe égal où il se trouve — et non de comptabilité.

Sans modèle, ce sont des divergences

Il n’y a pas de variante sans modèle des forces internes, et c’est voulu : privée de son modèle, l’opération ne connaît plus aucune mécanique. Il lui reste la géométrie et des noms, et sous ce jour ∫ Bᵀ σ est exactement la divergence du tenseur des contraintes — une divergence faible par ligne de σ. C’est donc divergence(field, "sigma") qui la rend, avec des composantes div_sigma_x, div_sigma_y… que l’appelant renomme en lignes duales s’il veut en faire des forces.

Ce renommage n’est pas une formalité administrative : c’est l’endroit, et le seul, où ces nombres deviennent de la mécanique.

Barres et poutres ne sont pas couvertes par cette voie — leur B n’est pas le gradient symétrique et leurs DDL ne sont pas un déplacement : pour elles, internal_forces(model, …), qui répartit par physique.