IEEEST Stabilizer Improvements/Corrections - #460
Conversation
|
@pelesh this fix is also ready to be merged I forgot to make a PR for this one. |
509506c to
e2c07d8
Compare
pelesh
left a comment
There was a problem hiding this comment.
The logic governing changing differential into algebraic equations and vice versa does not seem to be sustainable. This requires more offline discussion.
e2c07d8 to
bab57ad
Compare
8bbbad6 to
090289b
Compare
|
I have rebased and adjusted the formulation to align with #463 . |
755ee20 to
282fc1d
Compare
nkoukpaizan
left a comment
There was a problem hiding this comment.
I have a few comments here. Perhaps worth discussing at our next meeting.
| const auto U = static_cast<size_t>(IeeestExternalVariables::U); | ||
|
|
||
| const ScalarT x1 = y[X1]; | ||
| const ScalarT x2 = y[X2]; |
There was a problem hiding this comment.
Same here, the indirection from the enum is less readable to me. We should discuss a sustainable way to use the enums.
| using Variable = typename ModelDataT::MonitorableVariables; | ||
| monitor_->set(Variable::vss, [this] | ||
| { return y_[11]; }); | ||
| auto index = [](IeeestInternalVariables variable) |
There was a problem hiding this comment.
I've seen this pattern a few times. Consider defining once if it is really needed. I would argue it's less readable.
282fc1d to
579b3c1
Compare
|
Testing Ground for template parameters |
579b3c1 to
9fb15fa
Compare
|
general implementation of the template parameter done |
7336d1f to
1104b91
Compare
d0dc95a to
d2be200
Compare
|
@nkoukpaizan what are your thoughts on my template implementation? |
The model implementation is cleaner with the |
|
@nkoukpaizan we could possibly require the order to be passed as a parameter of IEEEST model, would that resolve your concern? "Order" is not usually directly exposed as a model parameter and so would require some knowledge of how IEEEST works to pass valid parameters. Can you give an example where the runtime comparison is bad/fails? I might be able to resolve both our concerns if I understand better. |
Yes, exposing the order as a parameter to the model is what I had in mind. Understood that that's not the domain practice. That's why as was asking whether this is possible as a question. Floating point values are stored with limited precision. We'd have to guarantee that the value returned by the parser is bit-for-bit equal to zero. That may be the case for nlohmann-json, but considering #227 and the possibility of using a different parser, that's not guaranteed. |
|
@nkoukpaizan i see the issue now thank you, that was very clarifying. After reflecting on my past experience and discussing with others at TAMU, I think deriving the order from the parameters alone is not intuitive or safe, either. As discussed, we should add an integer parameter to the IEEEST model, "order" and use that for the StabilizerFactory (rename to IeeestFactory). Then, our parameter validation can gate for zero division relevant to each static order (e.g. I will make this change then we can reasess. |
d2be200 to
47a31f1
Compare
47a31f1 to
5205fbe
Compare
|
@nkoukpaizan I have made the proposed edits. For future models with many different "orders" for subsystems the template arguments might get long, but it works well for one argument here |
nkoukpaizan
left a comment
There was a problem hiding this comment.
The template for the stabilizer object looks a lot cleaner to me!
I'm having a hard time reading the StabilizerIeeestTests at the moment, especially where multiple cases are defined as vectors of arrays. I would split the cases into separate tests and implement specific, reusable private methods.
| /// (a1 = a3 = 0) | ||
| /// | ||
| /// The Enzyme-vs-dependency-tracking Jacobian comparison is not run for | ||
| /// this configuration: Enzyme's `sparse_store` drops exact-zero entries |
There was a problem hiding this comment.
Enzyme should not drop non-structural zeros. May be worth looking into it if the Jacobians differ. I recommend starting with an implementation of the test with an expectFailure outcome.
| int ret = 0; | ||
|
|
||
| if (signals_.template isAttached<IeeestExternalVariables::U>()) | ||
| if (value != ZERO<RealT>) |
There was a problem hiding this comment.
I think isEqual would be appropriate here. I recommend a PR that moves it from the Testing namespace to, e.g., Math. @lukelowry Let me know if you can do that or if you'd rather me to.
| * @brief Compare DependencyTracking Jacobian against Enzyme Jacobian. | ||
| */ | ||
| TestOutcome jacobian() | ||
| TestOutcome verify() |
There was a problem hiding this comment.
Verify currently logs some errors. Make sure to message the user about expected errors, similar to #500.
| result += test.zeroInitialResidual(); | ||
| result += test.residual(); | ||
|
|
||
| result += test.init<0>(); |
There was a problem hiding this comment.
It might be cleaner to template the test class rather than individual member functions.
If I understand correctly, some tests are manipulating stabilizer objects of different orders. Consider two test objects:
- One templated to check all orders
- Another one that manipulates/compares objects of different orders.
| @@ -19,10 +19,11 @@ namespace GridKit | |||
| * | |||
| * @tparam ScalarT - Scalar data type | |||
| * @tparam IdxT - Index data type | |||
| using Params = PhasorDynamics::Stabilizer::IeeestParameters; | ||
|
|
||
| // The second case exercises the TIME_CONSTANT_MINIMUM flooring. | ||
| const std::vector<std::array<RealT, 3>> time_constant_cases = { |
There was a problem hiding this comment.
I would split into two different tests.
b33b975 to
fe235d0
Compare
Description
Fixes and cleans up the
IEEESTstabilizer implementation and documentation.This updates the older initial implementation style so that reduced-order notch filters and zero denominator time constants are handled consistently
Proposed changes
IEEESTfrom the attached input signal instead of forcing all states to zero.Checklist
-Wall -Wpedantic -Wconversion -Wextra.Changelog changes N/A
Further comments
This is cleanup/correction work for the existing
IEEESTmodel, not a new model