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

Dirichlet

En bref

Impose la valeur d’une inconnue sur des nœuds : T = 20 sur un bord, u_x = 0 sur un appui. Avec sense, impose une borne : u_x ≥ 0 est une butée.

opérateurpyrucast.model.dirichlet(imposed_mesh, target, variable, sense="=")
tagconstraint et celui de la cible
typecontrainte (label() : "Dirichlet")
supportun maillage POI1 : les nœuds imposés, une relation par maille

target est le modèle contraint, variable l’une de ses inconnues ; une variable que la cible ne déclare pas est refusée à la construction. Une seule variable par contrainte : pour encastrer, on compose dirichlet(noeuds, m, "u_x") | dirichlet(noeuds, m, "u_y").

Théorie

Chaque nœud \(n\) du support porte une relation à un seul terme,

\[ u(n) = u_d \qquad (\text{ou } \ge,\ \le\ u_d), \]

imposée par un multiplicateur \(\lambda\) (voir Contraintes). Elle apporte deux blocs à la raideur, chacun de coefficient 1 :

  • le bloc \(C\) : ligne (multiplicateur, imposed), colonne (n, variable) ;
  • le bloc \(C^{\mathsf T}\) : ligne (n, duale de la variable), colonne (multiplicateur, lambda).

À la solution, \(\lambda\) est l’effort de la pièce sur le blocage : le flux ou la force qui tient la valeur imposée, vu de la pièce. La réaction, ce que le blocage exerce sur la pièce, est \(-\lambda\) : une poutre encastrée qui porte un poids \(P\) vers le bas a des multiplicateurs u_z de somme \(-P\), et une réaction \(P\) vers le haut (voir Contraintes).

Chaque relation a son nœud multiplicateur, créé par la contrainte à la position du nœud imposé, dans le même Coords ; multiplier_mesh() les donne. La valeur imposée \(u_d\) n’est pas stockée dans la contrainte : elle s’écrit dans le chargement, à la composante imposed du nœud multiplicateur, ce que fait constraint_rhs([(noeud_impose, u_d)]). Une relation absente du chargement impose 0.

Variables

primalelambda, le multiplicateur
dualeimposed, la ligne de la relation
ce qu’elle contraintvariable, une inconnue de la cible, dont la duale reçoit la réaction
matériau, comportementaucun

Ce qu’elle produit

raideurles blocs \(C\) et \(C^{\mathsf T}\), une paire par zone du support
masse, géométrique—
tangente= raideur
forces internes\(C^{\mathsf T}\lambda\) sur la duale de la cible, \(C\,u\) sur les lignes imposed
forces externesaucune ; la valeur imposée est un chargement

Exemple

Une barre \([0, 1]\) en conduction, \(T(0) = 0\) et \(T(1) = 1\) : le profil est \(T = x\), et les multiplicateurs sont les flux \(\pm1\) aux deux bouts.

import pyrucast

# 1) Maillage et espace éléments finis
c = pyrucast.Coords(dim=1)
nodes = [c.add_node([i / 4.0]) for i in range(5)]
mesh = pyrucast.Mesh(c, "SEG2")
for i in range(4):
    mesh.unit().add_cell([nodes[i], nodes[i + 1]])
fes = pyrucast.FiniteElementSpace(mesh)

# 2) Les deux appuis ; chacun crée son nœud multiplicateur près du nœud imposé.
imposed_left = pyrucast.mesh.poi1_from_nodes([nodes[0]])
imposed_right = pyrucast.mesh.poi1_from_nodes([nodes[-1]])
conduction = pyrucast.model.heat_conduction(fes)
left = pyrucast.model.dirichlet(imposed_left, conduction, "T")
right = pyrucast.model.dirichlet(imposed_right, conduction, "T")
mult_left = left.multiplier_mesh().node(0, 0, 0)
mult_right = right.multiplier_mesh().node(0, 0, 0)

# 3) Le modèle : la conduction et les deux appuis.
model = conduction | left | right
materials = pyrucast.element_field.material_field(model, [("k", 1.0)])

# 4) Chargement : `constraint_rhs` désigne chaque relation par son nœud imposé
#    et écrit la valeur à la composante `imposed` de son nœud multiplicateur.
#    Les deux se réunissent par `|`.
rhs = left.constraint_rhs([(nodes[0], 0.0)]) | right.constraint_rhs([(nodes[-1], 1.0)])

# 5) Assemblage + résolution.
K = pyrucast.matrix.stiffness(model, materials)
solution = pyrucast.solver.solve(K, rhs)
assert abs(solution.value(nodes[2], "T") - 0.5) < 1e-10  # T au milieu
assert abs(solution.value(mult_left, "lambda") - 1.0) < 1e-10  # le flux à gauche

Côté Rust

Dirichlet (src/models/dirichlet.rs) implémente Constraint : ses relations (relations()) et ses nœuds multiplicateurs. Ses blocs sortent de constraint_block_pair, partagé avec les autres contraintes, qui donne aux deux blocs une même identité de paire (Symmetry::Half) : la matrice n’est symétrique que si elle les tient tous les deux. Ils entrent dans la raideur par contributions, comme blocs écrits.