30 size_t nRows = mat.rows();
31 size_t nCols = mat.cols();
32 Matrix res(mat.rows(), mat.cols());
34 for (
size_t i = 0; i < nRows; ++i) {
35 for (
size_t j = 0; j < nCols; ++j) {
36 res(i, j) = std::abs(mat(i, j));
43 size_t nRows = mat.rows();
44 size_t nCols = mat.cols();
45 Matrix res(mat.rows(), mat.cols());
47 for (
size_t i = 0; i < nRows; ++i) {
48 for (
size_t j = 0; j < nCols; ++j) {
49 res(i, j) = std::arg(mat(i, j));
65 std::memcpy(&bits, &value,
sizeof(bits));
66 return (bits & 0x7FF0000000000000ULL) != 0x7FF0000000000000ULL;
74 Int maxFreq,
Int freqIdx, Matrix::Index colOffset) {
75 Eigen::Index harmonicOffset = mat.rows() / maxFreq;
76 Eigen::Index complexOffset = harmonicOffset / 2;
77 Eigen::Index harmRow = row + harmonicOffset * freqIdx;
79 mat(harmRow, colOffset) = value.real();
80 mat(harmRow + complexOffset, colOffset) = value.imag();
84 Int maxFreq,
Int freqIdx) {
85 Eigen::Index harmonicOffset = mat.rows() / maxFreq;
86 Eigen::Index complexOffset = harmonicOffset / 2;
87 Eigen::Index harmRow = row + harmonicOffset * freqIdx;
89 mat(harmRow, 0) = mat(harmRow, 0) + value.real();
90 mat(harmRow + complexOffset, 0) =
91 mat(harmRow + complexOffset, 0) + value.imag();
95 Int maxFreq,
Int freqIdx) {
96 Eigen::Index harmonicOffset = mat.rows() / maxFreq;
97 Eigen::Index complexOffset = harmonicOffset / 2;
98 Eigen::Index harmRow = row + harmonicOffset * freqIdx;
100 return Complex(mat(harmRow, 0), mat(harmRow + complexOffset, 0));
104 mat(row, 0) = mat(row, 0) + value;
116 Matrix::Index column,
Complex value,
Int maxFreq,
119 Eigen::Index harmonicOffset = mat.rows() / maxFreq;
120 Eigen::Index complexOffset = harmonicOffset / 2;
121 Eigen::Index harmRow = row + harmonicOffset * freqIdx;
122 Eigen::Index harmCol = column + harmonicOffset * freqIdx;
124 mat.coeffRef(harmRow, harmCol) = value.real();
125 mat.coeffRef(harmRow + complexOffset, harmCol + complexOffset) = value.real();
126 mat.coeffRef(harmRow, harmCol + complexOffset) = -value.imag();
127 mat.coeffRef(harmRow + complexOffset, harmCol) = value.imag();
131 Matrix::Index column,
Complex value,
Int maxFreq,
134 Eigen::Index harmonicOffset = mat.rows() / maxFreq;
135 Eigen::Index complexOffset = harmonicOffset / 2;
136 Eigen::Index harmRow = row + harmonicOffset * freqIdx;
137 Eigen::Index harmCol = column + harmonicOffset * freqIdx;
139 mat.coeffRef(harmRow, harmCol) += value.real();
140 mat.coeffRef(harmRow + complexOffset, harmCol + complexOffset) +=
142 mat.coeffRef(harmRow, harmCol + complexOffset) -= value.imag();
143 mat.coeffRef(harmRow + complexOffset, harmCol) += value.imag();
147 Matrix::Index column,
Matrix value,
Int maxFreq,
150 Eigen::Index harmonicOffset = mat.rows() / maxFreq;
151 Eigen::Index complexOffset = harmonicOffset / 2;
152 Eigen::Index harmRow = row + harmonicOffset * freqIdx;
153 Eigen::Index harmCol = column + harmonicOffset * freqIdx;
155 mat.coeffRef(harmRow, harmCol) += value(0, 0);
156 mat.coeffRef(harmRow + complexOffset, harmCol + complexOffset) += value(1, 1);
157 mat.coeffRef(harmRow, harmCol + complexOffset) += value(0, 1);
158 mat.coeffRef(harmRow + complexOffset, harmCol) += value(1, 0);
162 Matrix::Index column,
Real value) {
163 mat.coeffRef(row, column) = value;
167 std::vector<UInt> columns,
Complex value) {
173 Matrix::Index column,
Real value) {
174 mat.coeffRef(row, column) = mat.coeff(row, column) + value;
178 std::vector<UInt> columns,
Real value) {
184 const Int n = Eigen::internal::convert_index<Int>(mat.cols());
186 const Real determinant = mat(0, 0) * mat(1, 1) - mat(0, 1) * mat(1, 0);
187 matInv(0, 0) = mat(1, 1) / determinant;
188 matInv(0, 1) = -mat(0, 1) / determinant;
189 matInv(1, 0) = -mat(1, 0) / determinant;
190 matInv(1, 1) = mat(0, 0) / determinant;
192 const Real determinant =
193 (mat(0, 0) * mat(1, 1) * mat(2, 2) + mat(0, 1) * mat(1, 2) * mat(2, 0) +
194 mat(1, 0) * mat(2, 1) * mat(0, 2)) -
195 (mat(2, 0) * mat(1, 1) * mat(0, 2) + mat(1, 0) * mat(0, 1) * mat(2, 2) +
196 mat(2, 1) * mat(1, 2) * mat(0, 0));
198 (mat(1, 1) * mat(2, 2) - mat(1, 2) * mat(2, 1)) / determinant;
200 (mat(0, 2) * mat(2, 1) - mat(0, 1) * mat(2, 2)) / determinant;
202 (mat(0, 1) * mat(1, 2) - mat(0, 2) * mat(1, 1)) / determinant;
204 (mat(1, 2) * mat(2, 0) - mat(1, 0) * mat(2, 2)) / determinant;
206 (mat(0, 0) * mat(2, 2) - mat(0, 2) * mat(2, 0)) / determinant;
208 (mat(0, 2) * mat(1, 0) - mat(0, 0) * mat(1, 2)) / determinant;
210 (mat(1, 0) * mat(2, 1) - mat(1, 1) * mat(2, 0)) / determinant;
212 (mat(0, 1) * mat(2, 0) - mat(0, 0) * mat(2, 1)) / determinant;
214 (mat(0, 0) * mat(1, 1) - mat(0, 1) * mat(1, 0)) / determinant;
216 matInv = mat.inverse();
227 Matrix param_3ph = Matrix::Zero(3, 3);
228 param_3ph << parameter, 0., 0., 0., parameter, 0., 0, 0., parameter;
233 Matrix power_3ph = Matrix::Zero(3, 3);
234 power_3ph << power / 3., 0., 0., 0., power / 3., 0., 0, 0., power / 3.;
243 if (std::abs(rc) < 1e-12 || vPccPeakPhase < 1e-9)
244 return {pFilterRef, qFilterRef};
246 const Real qPccRef = qFilterRef;
247 const Real a = rc / (1.5 * vPccPeakPhase * vPccPeakPhase);
248 const Real discriminant =
249 1.0 + 4.0 * a * (pFilterRef - a * qPccRef * qPccRef);
250 if (discriminant < 0.0)
251 throw std::runtime_error(
"No feasible PCC power for the given filter-side "
252 "power reference, rc, and PCC voltage estimate.");
254 const Real sqrtDisc = std::sqrt(discriminant);
255 const Real p1 = (-1.0 + sqrtDisc) / (2.0 * a);
256 const Real p2 = (-1.0 - sqrtDisc) / (2.0 * a);
258 std::abs(p1 - pFilterRef) < std::abs(p2 - pFilterRef) ? p1 : p2;
259 return {pPccRef, qPccRef};
264 Matrix::Index n = states.rows();
265 Matrix I = Matrix::Identity(n, n);
269 Matrix F2inv = F2.inverse();
271 return F2inv * F1 * states + F2inv * (dt / 2.) *
B * (u_new + u_old);
276 Matrix::Index n = states.rows();
277 Matrix I = Matrix::Identity(n, n);
281 Matrix F2inv = F2.inverse();
283 return F2inv * F1 * states + F2inv * (dt / 2.) *
B * (u_new + u_old) +
289 Matrix::Index n = states.rows();
290 Matrix I = Matrix::Identity(n, n);
294 Matrix F2inv = F2.inverse();
296 return F2inv * F1 * states + F2inv * dt *
B * u + F2inv * dt *
C;
301 Real F1 = 1. + (dt / 2.) *
A;
302 Real F2 = 1. - (dt / 2.) *
A;
303 Real F2inv = 1. / F2;
305 return F2inv * F1 * states + F2inv * dt *
B * u + F2inv * dt *
C;
310 Matrix::Index n = states.rows();
311 Matrix I = Matrix::Identity(n, n);
315 Matrix F2inv = F2.inverse();
317 return F2inv * F1 * states + F2inv * dt *
B * u;
322 Matrix::Index n = states.rows();
323 Matrix I = Matrix::Identity(n, n);
327 Matrix F2inv = F2.inverse();
329 return F2inv * F1 * states + F2inv * dt * input;
333 Real F1 = 1. + (dt / 2.) *
A;
334 Real F2 = 1. - (dt / 2.) *
A;
335 Real F2inv = 1. / F2;
337 return F2inv * F1 * states + F2inv * dt *
B * u;
342 return states + dt * (
A * states +
B * u);
346 return states + dt * (
A * states +
B * u);
351 return states + dt * (
A * states +
B * u +
C);
356 return states + dt * (
A * states +
B * u +
C);
360 return states + dt * (
A * states + input);
368 Matrix::Index n =
A.rows();
369 Matrix I = Matrix::Identity(n, n);
373 Matrix F2inv = F2.inverse();
376 Bd = F2inv * (dt / 2.) *
B;
384 Matrix::Index n =
A.rows();
385 Matrix I = Matrix::Identity(n, n);
389 Matrix F2inv = F2.inverse();
392 Bd = F2inv * (dt / 2.) *
B;
398 const Matrix &statesPrevStep,
399 const Matrix &inputCurrStep,
400 const Matrix &inputPrevStep) {
401 return Ad * statesPrevStep + Bd * (inputCurrStep + inputPrevStep) + Cd;
406 size_t N = samples.size();
409 double thetaT =
M_PI / N;
416 for (
size_t l = 0; l < k; l++) {
417 for (
size_t a = l; a < N; a += n) {
419 Complex t = samples[a] - samples[b];
420 samples[a] += samples[b];
427 UInt m =
static_cast<UInt>(log2(N));
428 for (
UInt a = 0; a < N; a++) {
431 b = (((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1));
432 b = (((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2));
433 b = (((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4));
434 b = (((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8));
435 b = ((b >> 16) | (b << 16)) >> (32 - m);
438 samples[a] = samples[b];
445 Real delta = theta2 - theta1;
446 Real f1_real = f2.real() * cos(delta) - f2.imag() * sin(delta);
447 Real f1_imag = f2.real() * sin(delta) + f2.imag() * cos(delta);
448 return Complex(f1_real, f1_imag);
456 Matrix transform = Matrix::Zero(2, 3);
458 const Real k = std::sqrt(2.0 / 3.0);
460 transform << k * std::cos(theta), k * std::cos(theta - 2.0 *
M_PI / 3.0),
461 k * std::cos(theta + 2.0 *
M_PI / 3.0), -k * std::sin(theta),
462 -k * std::sin(theta - 2.0 *
M_PI / 3.0),
463 -k * std::sin(theta + 2.0 *
M_PI / 3.0);
473 Matrix transform = Matrix::Zero(3, 2);
475 const Real k = std::sqrt(2.0 / 3.0);
477 transform << k * std::cos(theta), -k * std::sin(theta),
478 k * std::cos(theta - 2.0 *
M_PI / 3.0),
479 -k * std::sin(theta - 2.0 *
M_PI / 3.0),
480 k * std::cos(theta + 2.0 *
M_PI / 3.0),
481 -k * std::sin(theta + 2.0 *
M_PI / 3.0);
static Complex polar(Real abs, Real phase)
static std::pair< Real, Real > pccPowerFromFilterPowerReference(Real pFilterRef, Real qFilterRef, Real rc, Real vGridRmsLL)
static Matrix singlePhasePowerToThreePhase(Real power)
To convert single phase power to symmetrical three phase.
static Complex polarDeg(Real abs, Real phase)
static Matrix StateSpaceEuler(Matrix states, Matrix A, Matrix B, Real dt, Matrix u)
static Complex complexFromVectorElement(const Matrix &mat, Matrix::Index row, Int maxFreq=1, Int freqIdx=0)
static Real degToRad(Real deg)
static Real realFromVectorElement(const Matrix &mat, Matrix::Index row)
static void calculateStateSpaceTrapezoidalMatrices(const Matrix &A, const Matrix &B, const Matrix &C, const Real &dt, Matrix &Ad, Matrix &Bd, Matrix &Cd)
Calculate the discretized state space matrices Ad, Bd, Cd using trapezoidal rule.
static void setVectorElement(Matrix &mat, Matrix::Index row, Complex value, Int maxFreq=1, Int freqIdx=0, Matrix::Index colOffset=0)
static void addToVectorElement(Matrix &mat, Matrix::Index row, Complex value, Int maxFreq=1, Int freqIdx=0)
static Complex rotatingFrame2to1(Complex f2, Real theta1, Real theta2)
static Matrix inverseParkTransformMatrixPowerInvariant(Real theta)
static Real phaseDeg(Complex value)
static Real phase(Complex value)
static void setMatrixElement(SparseMatrixRow &mat, Matrix::Index row, Matrix::Index column, Complex value, Int maxFreq=1, Int freqIdx=0)
static Matrix parkTransformPowerInvariant(Real theta, const Matrix &fabc)
static Matrix applyStateSpaceTrapezoidalMatrices(const Matrix &Ad, const Matrix &Bd, const Matrix &Cd, const Matrix &statesPrevStep, const Matrix &inputCurrStep, const Matrix &inputPrevStep)
Apply the trapezoidal based state space matrices Ad, Bd, Cd to get the states at the current time ste...
static Matrix singlePhaseParameterToThreePhase(Real parameter)
To convert single phase parameters to symmetrical three phase ones.
static bool isFinite(Real value)
static Real abs(Complex value)
static void addToMatrixElement(SparseMatrixRow &mat, Matrix::Index row, Matrix::Index column, Complex value, Int maxFreq=1, Int freqIdx=0)
static void invertMatrix(const Matrix &mat, Matrix &matInv)
static Matrix inverseParkTransformPowerInvariant(Real theta, const Matrix &fdq)
static Matrix parkTransformMatrixPowerInvariant(Real theta)
static void FFT(std::vector< Complex > &samples)
static Real radtoDeg(Real rad)
static MatrixComp singlePhaseVariableToThreePhase(Complex var_1ph)
To convert single phase complex variables (voltages, currents) to symmetrical three phase ones.
static Matrix StateSpaceTrapezoidal(Matrix states, Matrix A, Matrix B, Real dt, Matrix u_new, Matrix u_old)
#define RMS3PH_TO_PEAK1PH
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > Matrix
Dense matrix for real numbers.
std::complex< Real > Complex
Eigen::Matrix< Complex, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > MatrixComp
Dense matrix for complex numbers.
Eigen::SparseMatrix< Real, Eigen::RowMajor > SparseMatrixRow
Sparse matrix for real numbers (row major).