Implementation in a submodel
Resetting a state variable
State variables Explicit and implicit state variables (related to ODE and DAE equations) are not directly computed in a submodel. The role of the submodel consists in defining respectively the time derivative and the residual of these 2 types of variables. The Simcenter Amesim solver computes the values of the state variables during the integration process.
When an explicit state variable (named “y” with derivative named “dy”) is defined in a submodel, the calculation code of the submodel receives “y” as an input, and must compute the value of the time derivative, “dy”. Any attempt to modify the value of y during the integration is forbidden.
However, it is possible to modify “y” on 2 occasions:
at the beginning of the simulation,
during a discontinuity restart.
The beginning of the simulation is covered by the submodel initialization function, but also by the first call to the calculation function. This first call can be detected by using the firstc function. This function returns an integer value, set to 1 the first time the calculation function is called, and set to 0 otherwise. This case does not concern discontinuity handling. It is then not described in the code example.
The discontinuity restart concerns the "if (*flag==0)" part of the code. When this test is true, the submodel is allowed to re-initialize the value of a state variable.
The following code example is an integrator with saturation. The Ordinary Differential Equation consists in integrating the input “x”, as long as the output value “y” lies in the authorized range. When the output value goes outside this range, the integration is canceled, and the state variable is reset to one of the boundary values when necessary.
The main equation is then
dy/dt = x when y is in the range ]ymin, ymax[
dy/dt = 0otherwise
Copy
void resetint_(int *n, double *z, double *y, double *x,
double rp[2], int ic[2], int *flag)
{
int logi, stuck_high, stuck_low;
double ymax, ymin;
ymax = rp[0];
ymin = rp[1];
logi = 0;
/* Conditions for state variable stuck at high or low levels. */
stuck_high = (*y >= ymax) && (*x > 0.0);
stuck_low = (*y <= ymin) && (*x < 0.0);
/* Discontinuity restart. */
if (*flag == 0)
{
/* Determine free or constrained modes. */
if (stuck_high) /* Stuck at high level. */
{
ic[0] = 1;
}
else if (stuck_low) /* Stuck at low level. */
{
ic[0] = -1;
}
else /* Inside free range. */
{
ic[0] = 0;
}
/* Reset state if necessary. Note that the test does
not consider the sign of x. */
if (*y > ymax)
{
*y = ymax;
}
else if (*y < ymin)
{
*y = ymin;
}
}
if (ic[0] == 0) /* Integrating normally. */
{
*dy = *x;
logi = (stuck_high || stuck_low);
}
else if (ic[0] == 1) /* Stuck at high level. */
{
*dy = 0.0;
logi = !stuck_high;
}
else /* Stuck at low level. */
{
*dy = 0.0;
logi = !stuck_low;
}
if (logi) /* logi is true (1) when using wrong equation. */
{
/* Send a warning to the solver. */
disloc_(&logi);
}
/* <<<<<<<<<<<<End of Calculation Executable Statements. */
}
This code example is inspired from the LINT0 submodel, form the Signal, Control library.
Source: https://docs.sw.siemens.com/en-US/doc/254352342/PL20250521841123434.amesim_collection.TB121_Discontinuity_Handling/xid1849192 · retrieved 2026-07-17