# Point mass (MASS element) on a node with no other element gets no DOFs: stays at 0 in \*DYNAMIC (exit 0); tied by \*EQUATION it stops \*FREQUENCY or loses mass terms

**URL:** <https://calculix.discourse.group/t/point-mass-mass-element-on-a-node-with-no-other-element-gets-no-dofs-stays-at-0-in-dynamic-exit-0-tied-by-equation-it-stops-frequency-or-loses-mass-terms/4229>\
**Category:** Analysis issues\
**Created:** [October 22, 2026, 6:50pm UTC](https://calculix.discourse.group/t/point-mass-mass-element-on-a-node-with-no-other-element-gets-no-dofs-stays-at-0-in-dynamic-exit-0-tied-by-equation-it-stops-frequency-or-loses-mass-terms/4229 "2026-10-22T18:50:23Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sandervdb](https://avatars.discourse-cdn.com/v4/letter/s/49beb7/32.png) [@Sandervdb](https://calculix.discourse.group/u/Sandervdb)\
**Post date:** [October 22, 2026, 6:50pm UTC](https://calculix.discourse.group/t/point-mass-mass-element-on-a-node-with-no-other-element-gets-no-dofs-stays-at-0-in-dynamic-exit-0-tied-by-equation-it-stops-frequency-or-loses-mass-terms/4229/1 "2026-10-22T18:50:23Z")

</div>

## Summary

Section 6.2.44 (One-node mass element (MASS)) of the 2.23 manual: “This element is used to define nodal masses.” Section 7.82 (\*MASS) assigns the mass value to each element of the set.

ccx assembles the mass of a MASS element (`mafillsm.f` treats it as a one-node element with three DOFs), but `mastruct.c` skips MASS elements both when it decides which DOFs are active and when it sets up the structure of the matrix. As long as the node also belongs to another element, nothing shows. When the MASS element is the only element at its node:

1. **Free point mass, `*DYNAMIC`:** the node gets no degrees of freedom. A point mass of 2 pulled by a force (1, 0.5, 0) for one time unit stays at 0, with exit 0 and no message; F = m a is not satisfied. The same mass with a spring of stiffness 0 to a held node moves (0.25, 0.125, 0), exactly as it should. Implicit, NLGEOM and explicit `*DYNAMIC` give the same 0. (Only when the point mass is the whole model does ccx warn “no degrees of freedom in the model”.)
2. **Point mass tied by an `*EQUATION`, `*FREQUENCY`, one independent node held:** the node gets its DOF through the equation, but the matrix has no place for the mass terms that the equation moves to the independent DOFs. ccx stops with “\*ERROR in add\_bo\_st: coefficient should be 0” (exit 201), an internal message that names neither the element nor the node. The same stop occurs when the point mass is instead the only member of a `*RIGID BODY` whose reference node sits on a spring and whose rotation node is held.
3. **The same, both independent nodes free:** ccx prints “\*ERROR in add\_sm\_ei: coefficient should be 0”, drops the coupling mass term and goes on: “Job finished”, exit 0, and wrong eigenvalues (2000 and 2000 instead of 1000 and 10000). As an implicit `*DYNAMIC` step the same model stops with “\*ERROR in add\_sm\_st: coefficient should be 0” (exit 201).

In each case a spring of stiffness 0 from the mass node to a held node, which changes nothing physically, gives the right answer.

## Version

ccx 2.23 (macOS arm64). Source: master 9ba5d76 (16 Oct 2026).

## Already reported or fixed?

Not reported: I found no matching GitHub issue (open or closed) or pull request in Dhondtguido/CalculiX, and no calculix.discourse.group topic (searched 22 Oct 2026). Not fixed: the element loops of `mastruct.c` are unchanged on master (9ba5d76).

Related:

- [\*EQUATION that names the same DOF in two terms is mis-assembled: wrong stiffness and mass, no message · Issue #212 · Dhondtguido/CalculiX · GitHub](https://github.com/Dhondtguido/CalculiX/issues/212) (an `*EQUATION` that names one DOF twice) also mis-assembles the mass of a point mass tied by an equation, but through the repeated term in `mafillsm.f`; its fix, [equations.f: collect repeated DOFs of an equation into one term by sandervdbroek · Pull Request #245 · Dhondtguido/CalculiX · GitHub](https://github.com/Dhondtguido/CalculiX/pull/245), does not touch `mastruct.c`. Its frequency check ties the point mass to a single independent DOF, where the mass lands on the diagonal and this bug does not show.

## Minimal input

`mass_two.inp`: two point masses of 2, each pulled by the same force. Node 1 has only its MASS element; node 3 also has a spring of stiffness 0 to the held node 2.

```auto
** two point masses of 2, each pulled by a force (1, 0.5, 0) in a *DYNAMIC step:
** node 1 carries only its MASS element; node 3 also has a spring of stiffness 0
** to the held node 2
*NODE, NSET=NALL
1, 0., 0., 0.
2, 1., 0., 0.
3, 2., 0., 0.
*ELEMENT, TYPE=MASS, ELSET=EM
1, 1
3, 3
*MASS, ELSET=EM
2.
*ELEMENT, TYPE=SPRINGA, ELSET=ES
2, 3, 2
*SPRING, ELSET=ES

0.
*BOUNDARY
2, 1, 3
*STEP, INC=1000
*DYNAMIC
0.01, 1.
*CLOAD
1, 1, 1.
1, 2, 0.5
3, 1, 1.
3, 2, 0.5
*NODE PRINT, NSET=NALL, FREQUENCY=100
U
*END STEP

```

`lever_freq.inp`: a point mass of 2 (node 1) tied by an `*EQUATION` to the middle of a rigid lever between node 2, on a spring of stiffness 1000, and the held node 4. Five separate spring-mass oscillators (nodes 11-15) only give the eigensolver enough unknowns.

```auto
** point mass 2 at node 1, tied by an *EQUATION to the middle of a rigid lever:
** u1(node 1) = 0.5 u1(node 2) + 0.5 u1(node 4); node 4 is held, node 2 sits
** on a spring of stiffness 1000 to the held node 3.
** Nodes 11-15: five more spring-mass oscillators, only to give the
** eigensolver enough unknowns
*NODE, NSET=NALL
1, 1., 0., 0.
2, 2., 0., 0.
3, 3., 0., 0.
4, 0., 0., 0.
11, 4., 0., 0.
12, 5., 0., 0.
13, 6., 0., 0.
14, 7., 0., 0.
15, 8., 0., 0.
*NSET, NSET=OSC
11, 12, 13, 14, 15
*ELEMENT, TYPE=MASS, ELSET=EM
1, 1
*MASS, ELSET=EM
2.
*ELEMENT, TYPE=MASS, ELSET=EMO
21, 11
22, 12
23, 13
24, 14
25, 15
*MASS, ELSET=EMO
1.
*ELEMENT, TYPE=SPRINGA, ELSET=ES
2, 2, 3
*SPRING, ELSET=ES

1000.
*ELEMENT, TYPE=SPRINGA, ELSET=ESO
31, 11, 3
32, 12, 3
33, 13, 3
34, 14, 3
35, 15, 3
*SPRING, ELSET=ESO

10000.
*EQUATION
3
1, 1, 1., 2, 1, -0.5, 4, 1, -0.5
*BOUNDARY
1, 2, 3
2, 2, 3
3, 1, 3
4, 1, 3
OSC, 2, 3
*STEP
*FREQUENCY
1
*END STEP

```

`lever2_freq.inp`: `lever_freq.inp` with node 4 on a spring of 1000 as well instead of held in x. Changed lines (`...` stands for unchanged lines):

```diff
 *ELEMENT, TYPE=SPRINGA, ELSET=ES
 2, 2, 3
+4, 4, 3
 ...
 *BOUNDARY
 ...
-4, 1, 3
+4, 2, 3
 ...
 *FREQUENCY
-1
+2

```

`lever_freq_z.inp` and `lever2_freq_z.inp`: the two lever decks with a spring of stiffness 0 from the mass node 1 to the held node 3, these lines added just before `*EQUATION`:

```auto
*ELEMENT, TYPE=SPRINGA, ELSET=EZ
41, 1, 3
*SPRING, ELSET=EZ

0.

```

`lever2_dyn.inp`: `lever2_freq.inp` with the step replaced by

```auto
*NSET, NSET=P
2, 4
*STEP, INC=1000
*DYNAMIC
0.001, 0.1
*CLOAD
2, 1, 1.
*NODE PRINT, NSET=P, FREQUENCY=100
U
*END STEP

```

`lever_rb.inp`: `lever_freq.inp` with the point mass as the only member of a `*RIGID BODY` on node 2 instead of the `*EQUATION`: node `5, 0., 0., 0.` added after node 15, the three `*EQUATION` lines replaced by `*NSET, NSET=RB` / `1` / `*RIGID BODY, NSET=RB, REF NODE=2, ROT NODE=5`, and the boundary line `1, 2, 3` replaced by `5, 1, 3`. `lever_rb_z.inp`: the same with the spring of stiffness 0 from node 1 to node 3 (the lines added in the `_z` decks) inserted before `*NSET, NSET=RB`.

## How to run

```auto
ccx mass_two
ccx lever_freq
ccx lever_freq_z
ccx lever2_freq
ccx lever2_freq_z
ccx lever2_dyn
ccx lever_rb
ccx lever_rb_z

```

## Expected

`mass_two`: both masses move u = F t²/(2m) = (0.25, 0.125, 0) at t = 1.

`lever_freq`: the mass moves half as far as node 2, so node 2 sees a mass of m/4 = 0.5 on a spring of 1000: ω² = 2000 (7.117625 cycles/time).

`lever2_freq`: in (u2, u4) the mass matrix is (m/4)·[[1, 1], [1, 1]] and the stiffness diag(1000, 1000). The only finite mode of the lever is u2 = u4 with ω² = 2k/m = 1000; the next eigenvalue is the oscillators’ 10000.

`lever_rb`: with the rotations held, the mass moves with node 2, so ω² = k/m = 500 (3.558813 cycles/time).

## Actual

`mass_two`, t = 1:

```auto
         1 0.000000E+00 0.000000E+00 0.000000E+00
         2 0.000000E+00 0.000000E+00 0.000000E+00
         3 2.500000E-01 1.250000E-01 0.000000E+00

```

The same with `*DYNAMIC, EXPLICIT` (increment 0.001) or with `NLGEOM` on the `*STEP` card: node 1 stays at 0, node 3 moves (0.25, 0.125, 0). The only message is the usual “no elastic constants were assigned to material MASS” warning (and, in the explicit run, the note that the time increment is determined automatically).

`lever_freq`: stdout ends with

```auto
 Frequency analysis was selected

 *ERROR in add_bo_st: coefficient should be 0

```

and exit status 201. `lever_freq_z` gives `1 0.2000000E+04 0.4472136E+02 0.7117625E+01`, as expected.

`lever2_freq`: stdout shows “\*ERROR in add\_sm\_ei: coefficient should be 0”, then “Job finished” (exit 0), and the .dat file has

```auto
      1 0.2000000E+04 0.4472136E+02 0.7117625E+01 0.0000000E+00
      2 0.2000000E+04 0.4472136E+02 0.7117625E+01 0.0000000E+00

```

`lever2_freq_z` gives the expected values:

```auto
      1 0.1000000E+04 0.3162278E+02 0.5032921E+01 0.0000000E+00
      2 0.1000000E+05 0.1000000E+03 0.1591549E+02 0.0000000E+00

```

`lever2_dyn`: “\*ERROR in add\_sm\_ei: coefficient should be 0”, then “\*ERROR in add\_sm\_st: coefficient should be 0”, exit status 201.

`lever_rb`: “\*ERROR in add\_bo\_st: coefficient should be 0”, exit status 201. `lever_rb_z` gives `1 0.5000000E+03 0.2236068E+02 0.3558813E+01`, as expected.

## Where it goes wrong

`src/mastruct.c` decides which DOFs are active from the element types (lines 123-180). It knows continuum elements, user elements and the E elements (springs, dashpots, contact); every other type, MASS included, ends in

```c
	}else continue;

```

(line 180), so a node that only has a MASS element gets no DOFs. The loop that sets up the matrix structure (lines 354-411) has the same `}else continue;` (line 411), so the MASS element reserves no positions in the matrix either. `src/mastructcs.c` has the same two loops.

`src/mafillsm.f`, on the other hand, assembles MASS elements (lines 165-167: `elseif(lakon(i)(1:4).eq.'MASS') then` / `nope=1` / `ndof=3`), and the LOGBOOK entry of 16 July 2020 (“made a change in mafillsmcs.f: MASS elements were not taken into account”) shows that MASS elements are meant to be in the matrices.

The three cases above follow from that:

1. No DOFs at node 1: the force and the mass are both dropped.
2. Through the `*EQUATION`, the MPC loop of `mastruct.c` (lines 239-275) activates u1 of node 1 as a dependent DOF. In `mafillsm.f` the mass of node 1 then goes, through the “MPC id1 / MPC id1” branch (line 447 on), to the pairs of the equation’s independent DOFs: (node 2, node 2), which is on the diagonal, and (node 2, held node 4), a “boundary stiffness” column of the frequency step. That position was never reserved, so `add_bo_st.f` stops (lines 35-36).
3. With node 4 free, the pair (node 2, node 4) is an ordinary off-diagonal term. `add_sm_ei.f` finds no position for it, prints the message and returns without storing the value: its `call exit(201)` is commented out (lines 56-58). The eigenvalue problem is then solved with the diagonal terms only, which gives 4k/m = 2000 twice. In `*DYNAMIC`, `add_sm_st.f` (lines 50-51) stops at the same pair.

## Fix

Possible fix (not built or tested): in both element loops of `mastruct.c` (and `mastructcs.c`), handle MASS elements like a one-node element with three DOFs, e.g. before the final `else continue`:

```c
	else if(strcmp1(&lakon[8*i],"MASS")==0){nope=1;ndof=3;}

```

Then a point mass gets its DOFs, and the matrix gets the positions that its mass needs through MPCs. In a static step a free point mass then has three DOFs without stiffness, which is singular, as the model physically is. If that is not wanted, the DOFs of MASS-only nodes could be activated only in procedures that assemble a mass matrix.

Separately, `add_sm_ei.f` should not drop a nonzero coefficient silently after printing an \*ERROR; the commented-out `exit(201)` makes case 3 a wrong result instead of a stop.

Workaround: give every MASS-only node a spring of stiffness 0 (`SPRINGA` to a held node, as in `mass_two.inp` and the `_z` decks).

---

<div class="post-metadata">

**Author:** ![Calc\_em](https://avatars.discourse-cdn.com/v4/letter/c/43a26b/32.png) [@Calc\_em](https://calculix.discourse.group/u/Calc_em)\
**Post date:** [October 22, 2026, 7:39pm UTC](https://calculix.discourse.group/t/point-mass-mass-element-on-a-node-with-no-other-element-gets-no-dofs-stays-at-0-in-dynamic-exit-0-tied-by-equation-it-stops-frequency-or-loses-mass-terms/4229/2 "2026-10-22T19:39:11Z")

</div>

Confirmed using official build of ccx 2.23 on Windows, needs a GitHub ticket.

mass\_two.dat:

```auto
                        S T E P 1

                                INCREMENT 11

 displacements (vx,vy,vz) for set NALL and time 0.1000000E+01

         1 0.000000E+00 0.000000E+00 0.000000E+00
         2 0.000000E+00 0.000000E+00 0.000000E+00
         3 2.500000E-01 1.250000E-01 0.000000E+00

```

lever\_freq:

```auto
STEP 1

 *WARNING in calinput: no elastic constants
  were assigned to material MASS
          in a (thermo)mechanical calculation

 *WARNING in calinput: no elastic constants
  were assigned to material MASS
          in a (thermo)mechanical calculation

 Frequency analysis was selected

 Decascading the MPC's

 Determining the structure of the matrix:
 Using up to 6 cpu(s) for setting up the structure of the matrix.
 number of equations
 6
 number of nonzero lower triangular matrix elements
 0

 Using up to 6 cpu(s) for setting up the structure of the matrix.
 Using up to 12 cpu(s) for the stress calculation.

 Using up to 12 cpu(s) for the symmetric stiffness/mass contributions.

 *ERROR in add_bo_st: coefficient should be 0

```

---

<div class="post-metadata">

**Author:** ![Sandervdb](https://avatars.discourse-cdn.com/v4/letter/s/49beb7/32.png) [@Sandervdb](https://calculix.discourse.group/u/Sandervdb)\
**Post date:** [October 22, 2026, 8:36pm UTC](https://calculix.discourse.group/t/point-mass-mass-element-on-a-node-with-no-other-element-gets-no-dofs-stays-at-0-in-dynamic-exit-0-tied-by-equation-it-stops-frequency-or-loses-mass-terms/4229/3 "2026-10-22T20:36:41Z")

</div>

posted: [Point mass (MASS element) on a node with no other element gets no DOFs: stays at 0 in \*DYNAMIC (exit 0); tied by \*EQUATION it stops \*FREQUENCY or loses mass terms · Issue #279 · Dhondtguido/CalculiX · GitHub](https://github.com/Dhondtguido/CalculiX/issues/279)
