*TEMPERATURE with a step-time AMPLITUDE: at most one node is held at its end-of-step value; the others follow the amplitude again in the next step (exit 0)

Summary

Section 7.1 (*AMPLITUDE) of the 2.23 manual, which names *TEMPERATURE among the loading definitions, says: “Reference loads which are not changed in a new step remain active, their amplitude description, however, becomes void, unless the TIME=TOTAL TIME parameter is activated. Beware that at the end of a step, all reference values for which an amplitude was specified are replaced by their actual values at that time.” Section 7.132 (*TEMPERATURE) says the same for temperatures: “At the end of the step the reference value is replaced by the actual value at that time, for use in subsequent steps.”

ccx does this for point loads, distributed loads, body loads and boundary conditions. For temperatures it does it at one node at most (node 2 in a model without body loads). Every other node keeps its step-time amplitude, so in the next step its temperature is again the reference value times the amplitude, now evaluated at the new step’s time.

Test: a free C3D8 cube. Step 1 applies a reference temperature of 100 with the amplitude A (0 at 0, 1 at 0.5, 0.5 at 1), so it ends at 50. Step 2 (period 0.5) has no *TEMPERATURE card, so it should stay at 50. Instead:

  • nodes 1 and 3-8 are at 100 (100 times A(0.5));
  • only node 2 stays at 50;
  • the cube expands to U = 0.09375 instead of 0.05 (C3D8 takes the mean of its nodal temperatures, (7 · 100 + 50) / 8 = 93.75).

Exit 0, no message.

With the common ramp amplitude (0 at 0, 1 at 1) the end values happen to agree, but during the next step the temperatures start again from 0: at 25 % of step 2 the nodes are at 25 instead of 100. A *CLOAD with the same amplitude is held at its end value, as the manual says.

Version

ccx 2.23 (macOS arm64) and a build of master 9ba5d76 (16 Oct 2026): the same numbers.

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: CalculiX.c and CalculiXstep.c are unchanged on master (9ba5d76).

Related:

Minimal input

amp_step.inp:

** One C3D8 cube, held so that it can expand freely, alpha = 1.E-3.
** Step 1: reference temperature 100 with the step-time amplitude A
** (0 at 0, 1 at 0.5, 0.5 at 1): the cube ends at 50.
** Step 2 (period 0.5): no *TEMPERATURE card.
*NODE, NSET=NALL
1, 0., 0., 0.
2, 1., 0., 0.
3, 1., 1., 0.
4, 0., 1., 0.
5, 0., 0., 1.
6, 1., 0., 1.
7, 1., 1., 1.
8, 0., 1., 1.
*ELEMENT, TYPE=C3D8, ELSET=E
1, 1, 2, 3, 4, 5, 6, 7, 8
*MATERIAL, NAME=M
*ELASTIC
1000., 0.3
*EXPANSION
1.E-3
*DENSITY
1.E-6
*SOLID SECTION, ELSET=E, MATERIAL=M
*BOUNDARY
1, 1, 3
4, 1, 1
4, 3, 3
5, 1, 2
8, 1, 1
*AMPLITUDE, NAME=A
0., 0., 0.5, 1., 1., 0.5
*INITIAL CONDITIONS, TYPE=TEMPERATURE
NALL, 0.
*STEP
*STATIC
*TEMPERATURE, AMPLITUDE=A
NALL, 100.
*NODE PRINT, NSET=NALL
NT, U
*EL PRINT, ELSET=E
S
*END STEP
*STEP
*STATIC
0.5, 0.5, 1.E-5, 0.5
*END STEP

Variants:

  • amp_step_held.inp: step 2 also has *TEMPERATURE / NALL, 50., the end value of step 1 written out.
  • amp_step_cload.inp: the two lines *TEMPERATURE, AMPLITUDE=A / NALL, 100. of step 1 replaced by *CLOAD, AMPLITUDE=A / 7, 3, 1..
  • amp_step_grav.inp: *DLOAD / E, GRAV, 0., 0., 0., -1. (a body load of magnitude 0) added to step 1 after NALL, 100..
  • amp_ramp.inp: the ramp amplitude 0., 0., 1., 1. instead of A, and step 2 as *STEP, NLGEOM / *STATIC / 0.25, 1., 1.E-5, 0.25, so that it has four increments.

How to run

ccx amp_step
ccx amp_step_held
ccx amp_step_cload
ccx amp_step_grav
ccx amp_ramp

Expected

Step 2 at 50 everywhere, with the cube as at the end of step 1: U = 0.05 at node 7 in all three directions, no stress. That is what amp_step_held.inp gives. The same for amp_step_grav.inp.

In amp_ramp.inp all nodes stay at 100 in every increment of step 2.

Actual

Exit 0 and no warning for every deck. Step 1 of the temperature decks is right: NT = 50 at every node and U = 5.000000E-02 at node 7 (NT = 100 and U = 1.000000E-01 for amp_ramp).

Step 2:

deck NT U at node 7 (each direction)
amp_step 50 at node 2, 100 at nodes 1 and 3-8 9.375000E-02
amp_step_grav 50 at node 5, 100 at the other nodes 9.375000E-02
amp_step_held 50 everywhere 5.000000E-02

amp_step_cload.inp: node 7 has the same displacement in both steps (-1.463664E-03, -1.438423E-03, 5.711577E-03), so the force is held at its end value 0.5.

amp_ramp.inp, node 1 in step 2: NT = 25, 50, 75, 100 at total times 1.25, 1.5, 1.75 and 2; node 2 stays at 100.

Where it goes wrong

At the end of each step (except a PERTURBATION *BUCKLE step), CalculiX.c replaces the reference values that have a step-time amplitude by their actual values, under the comment “resetting the amplitude to none except for time=total time amplitudes” (lines 1772-1810 on master 9ba5d76). Each load type has its own loop, except the temperatures (lines 1803-1809, shown here after the body-load loop):

	for(i=1;i<3*nbody;i=i+3){
	  if(ibody[i]>0){
	    if(namta[3*ibody[i]-1]>0){
	      ibody[i]=0;
	      xbody[7*(i-1)/3]=xbodyold[7*(i-1)/3];}
	  }
	}
	if(ithermal[0]==1){
	  if(iamt1[i]>0){
	    if(namta[3*iamt1[i]-1]>0){
	      iamt1[i]=0;
	      t1[i]=t1old[i];}
	  }
	}

i is whatever the loop over the body loads left:

  • 1 without body loads, i.e. node 2;
  • 3 · nbody + 1 otherwise: node 5 with one body load in amp_step_grav.inp.

If the model’s highest node number is below 3 · nbody + 2, it points past the end of iamt1. All other nodes keep iamt1 and their reference value. CalculiXstep.c has the same block (lines 1929-1935).

Fix

Loop over the nodes:

--- a/src/CalculiX.c
+++ b/src/CalculiX.c
@@ -1801,10 +1801,12 @@
 	  }
 	}
 	if(ithermal[0]==1){
-	  if(iamt1[i]>0){
-	    if(namta[3*iamt1[i]-1]>0){
-	      iamt1[i]=0;
-	      t1[i]=t1old[i];}
+	  for(i=0;i<nk;i++){
+	    if(iamt1[i]>0){
+	      if(namta[3*iamt1[i]-1]>0){
+		iamt1[i]=0;
+		t1[i]=t1old[i];}
+	    }
 	  }
 	}
       }
--- a/src/CalculiXstep.c
+++ b/src/CalculiXstep.c
@@ -1927,10 +1927,12 @@
 	  }
 	}
 	if(ithermal[0]==1) {
-	  if(iamt1[i]>0){
-	    if(namta[3*iamt1[i]-1]>0){
-	      iamt1[i]=0;
-	      t1[i]=t1old[i];}
+	  for(i=0;i<*nk;i++){
+	    if(iamt1[i]>0){
+	      if(namta[3*iamt1[i]-1]>0){
+		iamt1[i]=0;
+		t1[i]=t1old[i];}
+	    }
 	  }
 	}
       }

I built master 9ba5d76 with this change (macOS arm64, SPOOLES) and ran the decks above:

  • amp_step and amp_step_grav: NT = 50 at every node and U = 5.000000E-02 in step 2, as amp_step_held.
  • amp_ramp: all nodes stay at 100 in every increment of step 2.
  • amp_step_cload and amp_step_held: unchanged.

Total-time amplitudes are kept as before (the namta test stays). Only four decks in test/ have both *TEMPERATURE cards and amplitudes (acou3, acou4, beamcr2, multistage), and none of them puts an amplitude on a temperature. Their .dat files are byte-identical with and without the change.

Workaround: give the temperatures again, with their end values, in the step after a step with a step-time temperature amplitude (as in amp_step_held.inp).

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

amp_step.dat:

                        S T E P       2


                                INCREMENT     1


 temperatures for set NALL and time  0.1500000E+01

         1  1.000000E+02
         2  5.000000E+01
         3  1.000000E+02
         4  1.000000E+02
         5  1.000000E+02
         6  1.000000E+02
         7  1.000000E+02
         8  1.000000E+02

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

         1  0.000000E+00  0.000000E+00  0.000000E+00
         2  9.375000E-02 -3.061738E-15  3.023195E-16
         3  9.375000E-02  9.375000E-02  1.538805E-15
         4  0.000000E+00  9.375000E-02  0.000000E+00
         5  0.000000E+00  0.000000E+00  9.375000E-02
         6  9.375000E-02 -7.056974E-15  9.375000E-02
         7  9.375000E-02  9.375000E-02  9.375000E-02
         8  0.000000E+00  9.375000E-02  9.375000E-02

amp_step_grav.dat:

                        S T E P       2


                                INCREMENT     1


 temperatures for set NALL and time  0.1500000E+01

         1  1.000000E+02
         2  1.000000E+02
         3  1.000000E+02
         4  1.000000E+02
         5  5.000000E+01
         6  1.000000E+02
         7  1.000000E+02
         8  1.000000E+02

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

         1  0.000000E+00  0.000000E+00  0.000000E+00
         2  9.375000E-02 -3.061738E-15  3.023195E-16
         3  9.375000E-02  9.375000E-02  1.538805E-15
         4  0.000000E+00  9.375000E-02  0.000000E+00
         5  0.000000E+00  0.000000E+00  9.375000E-02
         6  9.375000E-02 -7.056974E-15  9.375000E-02
         7  9.375000E-02  9.375000E-02  9.375000E-02
         8  0.000000E+00  9.375000E-02  9.375000E-02

amp_step_held.dat:

                        S T E P       2


                                INCREMENT     1


 temperatures for set NALL and time  0.1500000E+01

         1  5.000000E+01
         2  5.000000E+01
         3  5.000000E+01
         4  5.000000E+01
         5  5.000000E+01
         6  5.000000E+01
         7  5.000000E+01
         8  5.000000E+01

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

         1  0.000000E+00  0.000000E+00  0.000000E+00
         2  5.000000E-02 -2.669924E-16  3.406840E-15
         3  5.000000E-02  5.000000E-02 -1.298997E-15
         4  0.000000E+00  5.000000E-02  0.000000E+00
         5  0.000000E+00  0.000000E+00  5.000000E-02
         6  5.000000E-02  4.569517E-15  5.000000E-02
         7  5.000000E-02  5.000000E-02  5.000000E-02
         8  0.000000E+00  5.000000E-02  5.000000E-02
1 Like

posted: *TEMPERATURE with a step-time AMPLITUDE: at most one node is held at its end-of-step value; the others follow the amplitude again in the next step (exit 0) · Issue #284 · Dhondtguido/CalculiX · GitHub

1 Like