17 copy->setParameters(mFluxBreakpoints, mCurrentBreakpoints);
22 const std::vector<Real> &fluxBreakpoints,
23 const std::vector<Real> ¤tBreakpoints) {
24 if (fluxBreakpoints.size() < 2)
25 throw std::invalid_argument(
"At least two flux breakpoints are required.");
27 if (fluxBreakpoints.size() != currentBreakpoints.size())
28 throw std::invalid_argument(
29 "Flux and current breakpoint vectors must have the same size.");
31 constexpr Real originTolerance = 1e-12;
33 if (std::abs(fluxBreakpoints.front()) > originTolerance ||
34 std::abs(currentBreakpoints.front()) > originTolerance)
35 throw std::invalid_argument(
36 "Piecewise-linear characteristic must start at the origin.");
38 for (
size_t k = 0; k + 1 < fluxBreakpoints.size(); ++k) {
39 if (fluxBreakpoints[k + 1] <= fluxBreakpoints[k])
40 throw std::invalid_argument(
41 "Flux breakpoints must be strictly increasing.");
42 if (currentBreakpoints[k + 1] <= currentBreakpoints[k])
43 throw std::invalid_argument(
44 "Current breakpoints must be strictly increasing.");
47 mFluxBreakpoints = fluxBreakpoints;
48 mCurrentBreakpoints = currentBreakpoints;
50 Matrix aMatrix = Matrix::Zero(3, 3);
51 Matrix bMatrix = Matrix::Identity(3, 3);
52 Matrix cMatrix = Matrix::Zero(3, 3);
53 Matrix dMatrix = Matrix::Zero(3, 3);
62EMT::Ph3::PiecewiseLinearInductor::slopeAndOffsetFromFlux(
Real flux)
const {
63 const Real sign = (flux < 0.0) ? -1.0 : 1.0;
64 const Real absFlux = std::abs(flux);
66 size_t segment = mFluxBreakpoints.size() - 2;
67 for (
size_t k = 0; k + 1 < mFluxBreakpoints.size(); ++k) {
68 if (absFlux <= mFluxBreakpoints[k + 1]) {
74 const Real dFlux = mFluxBreakpoints[segment + 1] - mFluxBreakpoints[segment];
76 mCurrentBreakpoints[segment + 1] - mCurrentBreakpoints[segment];
78 const Real slope = dCurrent / dFlux;
79 const Real intercept =
80 mCurrentBreakpoints[segment] - slope * mFluxBreakpoints[segment];
82 return std::make_pair(slope, sign * intercept);
86 Matrix newC = Matrix::Zero(3, 3);
87 Matrix newF = Matrix::Zero(3, 1);
89 for (
Int phase = 0; phase < 3; ++phase) {
90 const Real flux = (**mX)(phase, 0);
91 const auto [slope, offset] = slopeAndOffsetFromFlux(flux);
93 newC(phase, phase) = slope;
94 newF(phase, 0) = offset;
PiecewiseLinearInductor(String uid, String name, Logger::Level logLevel=Logger::Level::off)
void setParameters(const std::vector< Real > &fluxBreakpoints, const std::vector< Real > ¤tBreakpoints)
Bool updateComponentParameters() override final
SimPowerComp< Real >::Ptr clone(String name) override final
Returns a modified copy of the component with the given suffix added to the name and without.
TwoTerminalVTypeVariableSSNComp(String uid, String name, Logger::Level logLevel=Logger::Level::off)
void setParameters(const Matrix &A, const Matrix &B, const Matrix &C, const Matrix &D)
void setOutputOffset(const Matrix &F)
const Matrix & outputOffset() const
String uid()
Returns unique id.
spdlog::level::level_enum Level
std::shared_ptr< SimPowerComp< VarType > > Ptr
Logger::Level mLogLevel
Component logger control for internal variables.
static std::shared_ptr< T > make(Args &&...args)
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > Matrix
Dense matrix for real numbers.