/** * Form a new external, quantized state model (QSS-specific). * * @param stateIdx The state index. */ protected final void _triggerQuantizationEventWorker(final int stateIdx) { // Note the superclass takes care of updating status variables and so on. // Initialize. final ModelPolynomial qStateMdl = _qStateMdls[stateIdx]; final ModelPolynomial cStateMdl = _cStateMdls[stateIdx]; final double dtStateMdl = _currSimTime.subtractToDouble(cStateMdl.tMdl); // Update the external, quantized state model. qStateMdl.tMdl = _currSimTime; qStateMdl.coeffs[0] = cStateMdl.evaluate(dtStateMdl); qStateMdl.coeffs[1] = cStateMdl.evaluateDerivative(dtStateMdl); }
/** Form new internal, continuous state models (QSS-specific). */ protected final void _triggerRateEventWorker() throws Exception { // Note the superclass takes care of updating status variables and so on. // Get values, at {_currSimTime}, of arguments to derivative function. // In general, expect the integrator formed all of its // continuous state models at the same time. If so, can find a // single delta-time, rather than having to find multiple differences // from {_currSimTime}. Know that finding time differences is // expensive in Ptolemy, so want to avoid doing that if possible. // However, there is a chance that the continuous state models were // formed at different times. For example: // (1) User can reset a single state at any simulation time. // (2) In future, might be possible to avoid updating a // continuous state model if know none of its arguments changed. Time tStateMdl = null; double dtStateMdl = 0; for (int ii = 0; ii < _stateCt; ++ii) { final ModelPolynomial cStateMdl = _cStateMdls[ii]; // Check for different model time. Note testing object identity OK. if (cStateMdl.tMdl != tStateMdl) { tStateMdl = cStateMdl.tMdl; dtStateMdl = _currSimTime.subtractToDouble(tStateMdl); } _stateVals_xx[ii] = cStateMdl.evaluate(dtStateMdl); } // In general, don't expect input variable models to have same times. for (int ii = 0; ii < _ivCt; ++ii) { _ivVals_xx[ii] = _ivMdls[ii].evaluate(_currSimTime); } // Evaluate derivative function at {_currSimTime}. int retVal = _derivFcn.evaluateDerivatives(_currSimTime, _stateVals_xx, _ivVals_xx, _stateDerivs_xx); if (0 != retVal) { throw new Exception("_derivFcn.evalDerivs() returned " + retVal); } // Update the internal, continuous state models. // Note this is a partial update, since don't yet know the second // derivatives. Do the update now so that, when find the sample point // needed to estimate second derivatives, will be able to use as much // current information about the continuous state as possible. // This also updates the rate model, which is just the derivative of // the state model. for (int ii = 0; ii < _stateCt; ++ii) { final ModelPolynomial cStateMdl = _cStateMdls[ii]; cStateMdl.tMdl = _currSimTime; cStateMdl.coeffs[0] = _stateVals_xx[ii]; cStateMdl.coeffs[1] = _stateDerivs_xx[ii]; cStateMdl.coeffs[2] = 0; } // Choose a sample time, different from {_currSimTime}. // For estimating second derivatives. final double dtSampleFD = 1e-8 * Math.max(1, Math.abs(_currSimTime.getDoubleValue())); double dtSample = Double.POSITIVE_INFINITY; for (int ii = 0; ii < _stateCt; ++ii) { final double derivii = _stateDerivs_xx[ii]; double dtii; if (derivii != 0) { dtii = _dqs[ii] / Math.abs(derivii); } else { dtii = dtSampleFD; } if (dtii < dtSample && dtii > 0.0) { dtSample = dtii; } } assert (dtSample > 0); final Time tSample = _currSimTime.addUnchecked(dtSample); // Get values, at {tSample}, of arguments to derivative function. // Note that here, know all continous state models have same time. // Therefore can use same delta-time for all evals. for (int ii = 0; ii < _stateCt; ++ii) { _stateVals_xx[ii] = _cStateMdls[ii].evaluate(dtSample); } for (int ii = 0; ii < _ivCt; ++ii) { _ivVals_xx[ii] = _ivMdls[ii].evaluate(tSample); } // Evaluate derivative function at {tSample}. retVal = _derivFcn.evaluateDerivatives(tSample, _stateVals_xx, _ivVals_xx, _stateDerivsSample_xx); if (0 != retVal) { throw new Exception("_derivFcn.evalDerivs() returned " + retVal); } // Update the internal, continuous state models. final double oneOverTwoDtSample = 0.5 / dtSample; for (int ii = 0; ii < _stateCt; ++ii) { _cStateMdls[ii].coeffs[2] = oneOverTwoDtSample * (_stateDerivsSample_xx[ii] - _stateDerivs_xx[ii]); } }