7#include <dpsim-models/EMT/EMT_Ph3_PiecewiseLinearInductor.h>
11EMT::Ph3::PiecewiseLinearInductor::PiecewiseLinearInductor(
12 String uid, String name, Logger::Level logLevel)
13 : TwoTerminalVTypeVariableSSNComp(uid, name, logLevel) {}
16 auto copy = SharedFactory<PiecewiseLinearInductor>::make(name,
mLogLevel);
17 copy->setParameters(mFluxBreakpoints, mCurrentBreakpoints);
21void EMT::Ph3::PiecewiseLinearInductor::setParameters(
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);
55 SSNComp::setParameters(aMatrix, bMatrix, cMatrix, dMatrix);
56 setOutputOffset(Matrix::Zero(3, 1));
59 updateComponentParameters();
63EMT::Ph3::PiecewiseLinearInductor::slopeAndOffsetFromFlux(Real flux)
const {
64 const Real sign = (flux < 0.0) ? -1.0 : 1.0;
65 const Real absFlux = std::abs(flux);
67 size_t segment = mFluxBreakpoints.size() - 2;
68 for (
size_t k = 0; k + 1 < mFluxBreakpoints.size(); ++k) {
69 if (absFlux <= mFluxBreakpoints[k + 1]) {
75 const Real dFlux = mFluxBreakpoints[segment + 1] - mFluxBreakpoints[segment];
77 mCurrentBreakpoints[segment + 1] - mCurrentBreakpoints[segment];
79 const Real slope = dCurrent / dFlux;
80 const Real intercept =
81 mCurrentBreakpoints[segment] - slope * mFluxBreakpoints[segment];
83 return std::make_pair(slope, sign * intercept);
87 Matrix newC = Matrix::Zero(3, 3);
88 Matrix newF = Matrix::Zero(3, 1);
90 for (Int phase = 0; phase < 3; ++phase) {
91 const Real flux = (**mX)(phase, 0);
92 const auto [slope, offset] = slopeAndOffsetFromFlux(flux);
94 newC(phase, phase) = slope;
95 newF(phase, 0) = offset;
98 const Bool changed = (!mC.isApprox(newC)) || (!outputOffset().isApprox(newF));
102 setOutputOffset(newF);
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.
Logger::Level mLogLevel
Component logger control for internal variables.