ModelingToolkit -- can I use `min` and `max` functions?

I agree with what you say. The closed-loop system is causal and better shows its issue is indeed with wind-up. I was suspicious of the open-loop example because it’s acausal, perhaps leading to the crash without clipping. I think open- and closed-loop crashed at different times and slightly different reasons. (Also I should have noticed you’re clamping in closed loop rather than back-calculating.)

This previous thread discusses the differences with OpenModelica. They have nonlinear blocks that are saturation (limiter) aware:

This code allows several ways to saturate. It’s implemented explicitly with if u > uMax.... The smooth(0, is option to smooth with a given polynomial order, currently disabled with 0. The other branch with homotopy is for reinitializing integrator states after hitting a discrete change, difficult when algebraic equations contain if. They can iteratively solve starting with simplified knowledge of the rail.

I would expect MTK if-lifting to be great for identifying discrete changes. Not sure about initialization, but it’s possible to furnish MTK with guesses for solving algebraic equations, where the first guess is that system is stuck on rail.