Summary
A B31 cantilever clamped with 1, 1, 6, a linear *STATIC step with a tip force, then a second *STATIC step with *STEP, NLGEOM: the second step stops at once with
*ERROR in meanrotmpc: MPC has wrong number of terms
and exit 201. The same deck with NLGEOM on both steps runs (tip u_y = 1.421378E-01 in both steps). An S4 strip whose clamped edge is held in DOF 1-5 does the same. A B32R cantilever stops the same way when a PERTURBATION *BUCKLE step sits between a linear and an NLGEOM step.
The 2.23 manual allows NLGEOM to be switched on in a later step: section 7.125 (*STEP), “Once the NLGEOM parameter has been selected, it remains active in all subsequent static calculations.” The message is internal; it names neither the node nor the cause, and the user’s input is valid.
Version
ccx 2.23 (macOS arm64) and current master (537aa81, built on macOS arm64): the same message and numbers.
Already reported or fixed?
Not fixed on master (537aa81). I found no GitHub issue or pull request, and no forum topic title, about this message.
Related:
- *FREQUENCY / *BUCKLE after a nonlinear step: an *EQUATION that a *RIGID BODY or knot MPC depends on is not decascaded again, wrong eigenvalues (exit 0) · Issue #226 · Dhondtguido/CalculiX · GitHub and its pull request CalculiX.c: decascade again after a step that left the MPCs undecascaded by sandervdbroek · Pull Request #252 · Dhondtguido/CalculiX · GitHub (both open): the opposite order. After a nonlinear step the MPCs stay undecascaded, so a following linear step (
*FREQUENCY,*BUCKLE) gives wrong eigenvalues. The pull request decascades again in that linear step and restores the undecascaded copy afterwards for a later nonlinear step. It does not cover a linear first step: a build of master 9ba5d76 with pull request 252 stops onlinear_then_nlgeom.inpwith the same message. (It does cure the NLGEOM / PERTURBATION*BUCKLE/ NLGEOM sequence, which stops on master with “too many cutbacks”.)
Minimal input
linear_then_nlgeom.inp:
** B31 cantilever, clamped at node 1. Step 1: linear static, tip force.
** Step 2: the same load, now with NLGEOM.
*NODE, NSET=NALL
1, 0., 0., 0.
2, 10., 0., 0.
3, 20., 0., 0.
*ELEMENT, TYPE=B31, ELSET=EB
1, 1, 2
2, 2, 3
*MATERIAL, NAME=STEEL
*ELASTIC
210000., 0.3
*BEAM SECTION, ELSET=EB, MATERIAL=STEEL, SECTION=RECT
1., 1.
0., 0., 1.
*BOUNDARY
1, 1, 6
*STEP
*STATIC
*CLOAD
3, 2, 1.
*NODE PRINT, NSET=NALL
U
*END STEP
*STEP, NLGEOM
*STATIC
*NODE PRINT, NSET=NALL
U
*END STEP
nlgeom_both.inp: the same with *STEP, NLGEOM on the first step too.
linear_then_nlgeom_s4.inp: two S4 elements (nodes 1-6 at x = 0, 10, 20 and y = 0, 10), thickness 1, *BOUNDARY 1, 1, 5 and 4, 1, 5, step 1 linear with *CLOAD 3, 3, 1. and 6, 3, 1., step 2 *STEP, NLGEOM with no new load.
How to run
ccx linear_then_nlgeom
ccx nlgeom_both
ccx linear_then_nlgeom_s4
Expected
The second step runs and gives the NLGEOM response to the load, as nlgeom_both.inp does.
Actual
| deck | step 1, node 3 | step 2 | exit |
|---|---|---|---|
| linear_then_nlgeom | 1.418136E-16, 1.421627E-01, 5.046600E-12 | *ERROR in meanrotmpc: MPC has wrong number of terms |
201 |
| nlgeom_both | -6.203952E-04, 1.421378E-01, about 1E-16 | -6.203952E-04, 1.421378E-01, about 1E-16 | 0 |
| linear_then_nlgeom_s4 | u_z 2.640273E-02 | the same *ERROR | 201 |
Where it goes wrong
Line numbers are master 537aa81 (2.23 in brackets).
- The rotational SPCs of a beam or shell node without a knot become mean-rotation MPCs with label MEANROTBS (2.23 manual section 10.3.5;
gen3dboun.f), and the translational SPCs become linear MPCs on the same expanded nodes. - In a step without NLGEOM
cascade.c:109[109] treats every MPC as linear ((*iperturb<2)) jmpc[i]=0;), andCalculiX.c:1178[1163] decascades in the first step. So the linear MPCs are substituted into the MEANROTBS MPC in place, which changes its number of terms, while its label stays. (Read from the source, not checked in a debugger.) - In the NLGEOM step
nonlinmpc.f:847-849passes the MEANROTBS MPC toumpc_mean_rot.f, which expects 3 terms per node plus the rotation term and stops at lines 58-64 [same] (nkn=(n-1)/3,if(3*nkn.ne.n-1)).
When the first step is nonlinear, cascade.c treats MEANROTBS as a nonlinear MPC and, called from the main program, does not substitute into it (lines 162-176 [same]: “no expansion if there is a dependence of a nonlinear MPC on another linear or nonlinear MPC and the call is from main”), which is why nlgeom_both.inp runs.
Fix
Not built or tested here. CalculiX.c already stores the undecascaded MPCs in the first step (lines 1160-1172 [1145-1157], nodempcref, coefmpcref: “storing the undecascaded MPC’s if needed … 1) in the first step always”); *EQUATION, REMOVE in a later step already restores it (equations.f lines 110-127). Restoring it (and decascading anew) at the start of the first NLGEOM step that follows a linear step would cover this case, as pull request 252 does after a linear step that follows a nonlinear one.
Workaround: put NLGEOM on the first step as well.