Apply boundary conditions#
Boundary conditions prescribe loads and constraints on the degrees of
freedom of a _Simu. They are applied to
node sets via add_* methods on the simulation object and are accessible
in the EasyFEA.Simulations namespace. Node sets come from coordinate
conditions or from mesh tags — see Use tags to apply boundary conditions for the
tag-based approach.
Query available unknowns#
Each simulation exposes the DOF names it solves for via
Get_unknowns():
print(simu.Get_unknowns())
# Elastic 2D: ['x', 'y']
# Elastic 3D: ['x', 'y', 'z']
# HyperElastic 2D: ['x', 'y']
# Thermal: ['t']
# Beam (planar): ['x', 'y', 'rz']
# PhaseField: ['x', 'y'] for elastic sub-problem, ['d'] for damage
Pass these strings as the unknowns argument to every add_* method.
You can also pass a subset — for example, fix only ["x"] to constrain
horizontal motion while leaving the vertical DOF free.
Summary of BC methods#
Method |
Physical meaning |
Integration |
|---|---|---|
Prescribed DOF value (displacement, temperature, …) |
— |
|
Concentrated nodal force / flux |
Point |
|
Force per unit length |
Along a line |
|
Force per unit area (pressure in 2D, traction in 3D) |
Over a surface |
|
Body force per unit volume |
Over a volume |
|
Normal pressure (outward positive) |
Over a boundary surface |
Dirichlet conditions (add_dirichlet())#
Prescribes the value of one or more DOFs on a set of nodes.
# fix all displacement DOFs to zero — clamped wall (Elastic simulation)
nodes = mesh.Nodes_Conditions(lambda x, y, z: x == 0)
simu.add_dirichlet(nodes, [0, 0], ["x", "y"])
# impose temperature 100 °C on the top surface (Thermal simulation)
nodes_top = mesh.Nodes_Conditions(lambda x, y, z: y == H)
simu.add_dirichlet(nodes_top, [100.0], ["t"])
# prescribed displacement that varies along x
simu.add_dirichlet(nodes, [lambda x, y, z: 0.01 * x, 0], ["x", "y"])
Concentrated force (add_neumann())#
Applies a concentrated force (or flux) directly on the selected nodes. No integration is performed — the value is added as-is to the right-hand side. Useful for point loads on beams or reactions at a single node.
# point load at the beam tip (Elastic simulation)
nodes_tip = mesh.Nodes_Point((L, h / 2))
simu.add_neumann(nodes_tip, [0, -500], ["x", "y"])
Distributed loads#
Line load (add_lineLoad())#
Force per unit length integrated along the selected boundary edges. Used in 2D for loads applied along a line, or in 3D for edge loads.
# uniform downward load of −1000 N/m along the top edge
nodes_top = mesh.Nodes_Conditions(lambda x, y, z: y == H)
simu.add_lineLoad(nodes_top, [-1000], ["y"])
# spatially varying line load
simu.add_lineLoad(nodes_top, [lambda x, y, z: -500 * (1 + x / L)], ["y"])
Surface load (add_surfLoad())#
Force per unit area integrated over the selected boundary faces. Typical for pressure loads in 3D, or traction/pressure in 2D (force per unit area × thickness).
# uniform pressure of −800 Pa in x on the right face
nodes_right = mesh.Nodes_Conditions(lambda x, y, z: x == L)
simu.add_surfLoad(nodes_right, [-800], ["x"])
# traction vector on a 3D face
simu.add_surfLoad(nodes_right, [-1e6], ["z"])
Volume load (add_volumeLoad())#
Body force per unit volume integrated over the selected elements. Typical use is gravity.
# gravity in −y, ρ = 7800 kg/m³
simu.add_volumeLoad(mesh.nodes, [-7800 * 9.81], ["y"])
Pressure load (add_pressureLoad())#
Applies a normal pressure of given magnitude on a boundary surface. The direction is automatically computed from the outward normal at each boundary face.
# internal pressure of 1 MPa on a cylinder inner surface
simu.add_pressureLoad(inner_surface_nodes, magnitude=1e6)
Spatially varying values#
All values arguments accept:
a float — uniform value applied to all selected nodes,
a NumPy array of length
Nn— one value per node,a lambda function
lambda x, y, z: ...— evaluated at node (or integration-point) coordinates.
# temperature that increases linearly along x
simu.add_dirichlet(nodes, [lambda x, y, z: 20 + 80 * x / L], ["t"])
# load proportional to distance from center
simu.add_surfLoad(nodes, [lambda x, y, z: -100 * (x - L/2)**2], ["x"])
Functions always receive three arguments x, y, z regardless of the problem
dimension.
Visualize applied conditions#
from EasyFEA import Display, PyVista
Display.Plot_BoundaryConditions(simu) # matplotlib
PyVista.Plot_BoundaryConditions(simu) # interactive 3D
Reset boundary conditions#
Call Bc_Init() to clear all previously defined conditions (e.g., between load steps):
simu.Bc_Init()