Skip to content

Fix plani4e and soli8e for NumPy 2 and ndarray inputs - #96

Merged
jonaslindemann merged 1 commit into
CALFEM:developfrom
carldlund:fix-plani4e-soli8e-numpy2
Oct 1, 2026
Merged

jonaslindemann merged 1 commit into
CALFEM:developfrom
carldlund:fix-plani4e-soli8e-numpy2

Conversation

@carldlund

@carldlund carldlund commented Sep 26, 2026 •

Copy link
Copy Markdown

plani4e and soli8e assume np.matrix semantics that don't hold when inputs are plain ndarrays, which breaks them under NumPy 2. Same area as #89, different call sites.

plani4e: coerce D to np.matrix so B.T * Dm * B stays a matrix product, build wp/xsi/eta as columns so the following np.append(..., axis=1) has a 2-D operand, use @ for JTinv * dNr, and take detJ/wp[i]/t as floats with q reshaped to a column when accumulating Ke1/fe1.

soli8e: reshape eqp to (3, 1), and test eqp is not None rather than eqp != None.

That last one is a plain bug. On master, with a unit cube and D = np.eye(6):

  • eqp as an ndarray: eqp != None compares elementwise, so truth-testing the result raises ValueError: The truth value of an array with more than one element is ambiguous.
  • eqp as a list: no error, but fe comes back (24, 24) instead of (24, 1).

So soli8e with a body force is wrong either loudly or quietly. Both cases give fe (24, 1) after the change.

Tested on NumPy 2.4.6 and 2.5.2. No intended change where things already worked.

Found while using calfem-python as a reference implementation for a Julia port.

Both functions assume np.matrix semantics that no longer hold when
callers pass plain ndarrays, which breaks them under NumPy 2.

plani4e:

- coerce D to np.matrix so B.T * Dm * B keeps matrix multiplication
- build wp, xsi and eta as explicit column vectors, so the subsequent
  np.append(..., axis=1) has a 2-D operand to append along
- use @ for JTinv * dNr, which is a matrix product rather than an
  elementwise one
- extract detJ, wp[i] and t as Python floats and reshape q to a column
  before accumulating into Ke1 and fe1, instead of relying on 1x1 matrix
  coercion

soli8e:

- reshape eqp to (3, 1) so fe accumulates against a column
- test `eqp is not None` rather than `eqp != None`. The latter is an
  elementwise comparison when eqp is an ndarray, producing an array whose
  truth value is ambiguous, so the function raises instead of returning
  fe

Verified against NumPy 2.4.6 and 2.5.2. No intended change in results for
inputs that already worked.
@jonaslindemann
jonaslindemann changed the base branch from master to develop October 1, 2026 21:17
@jonaslindemann
jonaslindemann merged commit 0457d40 into CALFEM:develop Oct 1, 2026
@carldlund
carldlund deleted the fix-plani4e-soli8e-numpy2 branch October 2, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants