femlabpy.boundary#

Boundary-condition application and constrained linear-system solvers.

Workflow role#

This module sits between assembly and solution. setbc applies prescribed displacements by direct elimination, while solve_lag_general and solve_lag build augmented systems for exact linear constraints using Lagrange multipliers.

What to read first#

  • setbc for the standard fixed-support workflow.

  • solve_lag_general for constraint equations such as periodicity or multi- point conditions.

  • solve_lag for the legacy wrapper that keeps the original FemLab calling convention.

Functions#

rnorm(f, C, dof)

Return the residual norm restricted to unconstrained degrees of freedom.

setbc(K, p, C[, dof])

Apply boundary conditions using direct elimination.

solve_lag(K, p[, C, dof, return_lagrange])

Solve a linear system with nodal Dirichlet constraints via Lagrange multipliers.

solve_lag_general(K, p, G[, Q, scale, ...])

Solve a linear system with general linear constraints G u = Q.

Function Reference#

femlabpy.boundary.rnorm(f, C, dof: int)[source]#

Return the residual norm restricted to unconstrained degrees of freedom.

Parameters:
f:

Residual or force vector.

C:

Legacy constraint table [node, local_dof, value].

dof:

Degrees of freedom per node.

Returns:
float

Euclidean norm of the unconstrained residual entries.

femlabpy.boundary.setbc(K, p, C, dof: int = 1)[source]#

Apply boundary conditions using direct elimination.

For each constrained DOF j with prescribed value d:

  1. Transfer the coupling forces to the RHS: p -= K[:, j] * d

  2. Zero out the row and column: K[j, :] = 0, K[:, j] = 0

  3. Place a spring stiffness on the diagonal: K[j, j] = ks

  4. Set the load entry: p[j] = ks * d

This is the standard textbook direct-elimination approach matching the Scilab FemLab setbc.sci convention (row/column zeroing with ks = 0.1 * max(diag(K))), with the additional correction that coupling forces are transferred to the RHS before zeroing, so non-zero prescribed displacements are handled correctly.

Parameters:
Kndarray or sparse matrix, shape (ndof, ndof)

Global stiffness matrix (modified in place).

pndarray, shape (ndof, 1)

Load vector (modified in place).

Carray_like, shape (nbc, 2) or (nbc, 3)

Boundary condition array: - For dof=1: each row is [node, value] - For dof>1: each row is [node, local_dof, value] Node indices are 1-based.

dofint, default=1

Number of DOFs per node. Use dof=2 for 2D problems, dof=3 for 3D problems.

Returns:
Kndarray or sparse matrix

Modified stiffness matrix.

pndarray

Modified load vector.

ksfloat

Spring stiffness used for the constrained DOFs.

Examples

>>> from femlabpy import init, setbc
>>> K, p, q = init(nn=10, dof=2)
>>> # Fix node 1 (both DOFs) and node 2 (x-direction only)
>>> C = np.array([
...     [1, 1, 0.0],  # node 1, ux = 0
...     [1, 2, 0.0],  # node 1, uy = 0
...     [2, 1, 0.0],  # node 2, ux = 0
... ])
>>> K, p, _ = setbc(K, p, C, dof=2)
femlabpy.boundary.solve_lag(K, p, C=None, dof: int = 1, *, return_lagrange: bool = False)[source]#

Solve a linear system with nodal Dirichlet constraints via Lagrange multipliers.

Parameters:
K, p:

Linear system K u = p before applying displacement constraints.

C:

Legacy constraint table. For scalar problems, each row is [node, value]. For vector problems, each row is [node, local_dof, value].

dof:

Degrees of freedom per node.

return_lagrange:

When True, also return the recovered Lagrange multipliers.

Returns:
ndarray or tuple[ndarray, ndarray]

Constrained solution vector, optionally paired with the multiplier vector.

femlabpy.boundary.solve_lag_general(K, p, G, Q=None, *, scale: float | None = None, return_lagrange: bool = False)[source]#

Solve a linear system with general linear constraints G u = Q.

The augmented system is scaled to keep the constraint rows numerically compatible with the stiffness matrix, matching the legacy toolbox pattern.