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 VTypeVariableSSNComp::setParameters(aMatrix, bMatrix, cMatrix, dMatrix);
58 updateComponentParameters();
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;
97 const Bool changed = (!mC.isApprox(newC)) || (!outputOffset().isApprox(newF));
101 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.