9 #include <dpsim-models/SP/SP_Ph1_PiLine.h>
14 : Base::Ph1::
PiLine(mAttributes),
16 mBaseVoltage(mAttributes->create<Real>(
"base_Voltage")),
17 mCurrent(mAttributes->create<MatrixComp>(
"current_vector")),
18 mActivePowerBranch(mAttributes->create<Matrix>(
"p_branch_vector")),
19 mReactivePowerBranch(mAttributes->create<Matrix>(
"q_branch_vector")),
20 mActivePowerInjection(mAttributes->create<Real>(
"p_inj")),
21 mReactivePowerInjection(mAttributes->create<Real>(
"q_inj")) {
23 SPDLOG_LOGGER_INFO(
mSLog,
"Create {} {}", this->
type(), name);
26 setVirtualNodeNumber(1);
35 void SP::Ph1::PiLine::setParameters(Real resistance, Real inductance,
36 Real capacitance, Real conductance) {
38 **mSeriesRes = resistance;
39 **mSeriesInd = inductance;
40 SPDLOG_LOGGER_INFO(mSLog,
"Resistance={} [Ohm] Inductance={} [H]",
41 **mSeriesRes, **mSeriesInd);
43 if (capacitance > 0) {
44 **mParallelCap = capacitance;
46 **mParallelCap = 1e-12;
48 mSLog,
"Zero value for Capacitance, setting default value of C={} [F]",
51 if (conductance > 0) {
52 **mParallelCond = conductance;
54 if (mBehaviour == Behaviour::Initialization)
60 **mParallelCond = (conductance > 0) ? conductance : 1e-6;
62 mSLog,
"Zero value for Conductance, setting default value of G={} [S]",
65 SPDLOG_LOGGER_INFO(mSLog,
"Capacitance={} [F] Conductance={} [S]",
66 **mParallelCap, **mParallelCond);
68 mParametersSet =
true;
73 auto copy = PiLine::make(name, mLogLevel);
74 copy->setParameters(**mSeriesRes, **mSeriesInd, **mParallelCap,
81 **mBaseVoltage = baseVoltage;
86 SPDLOG_LOGGER_INFO(mSLog,
"#### Calculate Per Unit Parameters for {}",
88 mBaseApparentPower = baseApparentPower;
89 mBaseOmega = baseOmega;
90 SPDLOG_LOGGER_INFO(mSLog,
"Base Power={} [VA] Base Omega={} [1/s]",
91 baseApparentPower, baseOmega);
93 mBaseImpedance = (**mBaseVoltage * **mBaseVoltage) / mBaseApparentPower;
94 mBaseAdmittance = 1.0 / mBaseImpedance;
95 mBaseInductance = mBaseImpedance / mBaseOmega;
96 mBaseCapacitance = 1.0 / mBaseOmega / mBaseImpedance;
97 mBaseCurrent = baseApparentPower /
100 SPDLOG_LOGGER_INFO(mSLog,
"Base Voltage={} [V] Base Impedance={} [Ohm]",
101 **mBaseVoltage, mBaseImpedance);
103 mSeriesResPerUnit = **mSeriesRes / mBaseImpedance;
104 mSeriesIndPerUnit = **mSeriesInd / mBaseInductance;
105 mParallelCapPerUnit = **mParallelCap / mBaseCapacitance;
106 mParallelCondPerUnit = **mParallelCond / mBaseAdmittance;
108 SPDLOG_LOGGER_INFO(mSLog,
"Resistance={} [pu] Reactance={} [pu]",
109 mSeriesResPerUnit, 1. * mSeriesIndPerUnit);
110 SPDLOG_LOGGER_INFO(mSLog,
"Susceptance={} [pu] Conductance={} [pu]",
111 1. * mParallelCapPerUnit, mParallelCondPerUnit);
116 int bus1 = this->matrixNodeIndex(0);
117 int bus2 = this->matrixNodeIndex(1);
121 Complex(1, 0) / Complex(mSeriesResPerUnit, 1. * mSeriesIndPerUnit);
123 Complex(mParallelCondPerUnit, 1. * mParallelCapPerUnit) / Complex(2, 0);
126 mY_element = MatrixComp(2, 2);
127 mY_element(0, 0) = y + ys;
128 mY_element(0, 1) = -y;
129 mY_element(1, 0) = -y;
130 mY_element(1, 1) = y + ys;
133 for (
int i = 0; i < 2; i++)
134 for (
int j = 0; j < 2; j++)
135 if (std::isinf(mY_element.coeff(i, j).real()) ||
136 std::isinf(mY_element.coeff(i, j).imag())) {
137 std::cout << mY_element << std::endl;
138 std::stringstream ss;
139 ss <<
"Line>>" << this->name()
140 <<
": infinite or nan values in the element Y at: " << i <<
"," << j;
141 throw std::invalid_argument(ss.str());
142 std::cout <<
"Line>>" << this->name()
143 <<
": infinite or nan values in the element Y at: " << i
144 <<
"," << j << std::endl;
148 Y.coeffRef(bus1, bus1) += mY_element.coeff(0, 0);
149 Y.coeffRef(bus1, bus2) += mY_element.coeff(0, 1);
150 Y.coeffRef(bus2, bus2) += mY_element.coeff(1, 1);
151 Y.coeffRef(bus2, bus1) += mY_element.coeff(1, 0);
153 SPDLOG_LOGGER_INFO(mSLog,
"#### PF Y matrix stamping #### ");
154 SPDLOG_LOGGER_INFO(mSLog,
"{}", mY_element);
159 VectorComp &powerflow) {
160 **mCurrent = current * mBaseCurrent;
161 **mActivePowerBranch = powerflow.real() * mBaseApparentPower;
162 **mReactivePowerBranch = powerflow.imag() * mBaseApparentPower;
166 **mActivePowerInjection = std::real(powerInjection) * mBaseApparentPower;
167 **mReactivePowerInjection = std::imag(powerInjection) * mBaseApparentPower;
176 **mParallelCond = (**mParallelCond >= 0) ? **mParallelCond : 1e-6;
179 Real omega = 2. * PI * frequency;
180 Complex impedance = {**mSeriesRes, omega * **mSeriesInd};
181 (**mIntfVoltage)(0, 0) = initialSingleVoltage(1) - initialSingleVoltage(0);
182 (**mIntfCurrent)(0, 0) = (**mIntfVoltage)(0, 0) / impedance;
185 mVirtualNodes[0]->setInitialVoltage(initialSingleVoltage(0) +
186 (**mIntfCurrent)(0, 0) * **mSeriesRes);
190 std::make_shared<SP::Ph1::Resistor>(**mName +
"_res", mLogLevel);
191 mSubSeriesResistor->setParameters(**mSeriesRes);
192 mSubSeriesResistor->connect({mTerminals[0]->node(), mVirtualNodes[0]});
193 mSubSeriesResistor->initialize(mFrequencies);
194 mSubSeriesResistor->initializeFromNodesAndTerminals(frequency);
195 addMNASubComponent(mSubSeriesResistor, MNA_SUBCOMP_TASK_ORDER::NO_TASK,
196 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
false);
199 std::make_shared<SP::Ph1::Inductor>(**mName +
"_ind", mLogLevel);
200 mSubSeriesInductor->setParameters(**mSeriesInd);
201 mSubSeriesInductor->connect({mVirtualNodes[0], mTerminals[1]->node()});
202 mSubSeriesInductor->initialize(mFrequencies);
203 mSubSeriesInductor->initializeFromNodesAndTerminals(frequency);
204 addMNASubComponent(mSubSeriesInductor, MNA_SUBCOMP_TASK_ORDER::NO_TASK,
205 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
208 if (**mParallelCond >= 0) {
209 mSubParallelResistor0 =
210 std::make_shared<SP::Ph1::Resistor>(**mName +
"_con0", mLogLevel);
211 mSubParallelResistor0->setParameters(2. / **mParallelCond);
212 mSubParallelResistor0->connect(
213 SimNode::List{SimNode::GND, mTerminals[0]->node()});
214 mSubParallelResistor0->initialize(mFrequencies);
215 mSubParallelResistor0->initializeFromNodesAndTerminals(frequency);
216 addMNASubComponent(mSubParallelResistor0, MNA_SUBCOMP_TASK_ORDER::NO_TASK,
217 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
false);
219 mSubParallelResistor1 =
220 std::make_shared<SP::Ph1::Resistor>(**mName +
"_con1", mLogLevel);
221 mSubParallelResistor1->setParameters(2. / **mParallelCond);
222 mSubParallelResistor1->connect(
223 SimNode::List{SimNode::GND, mTerminals[1]->node()});
224 mSubParallelResistor1->initialize(mFrequencies);
225 mSubParallelResistor1->initializeFromNodesAndTerminals(frequency);
226 addMNASubComponent(mSubParallelResistor1, MNA_SUBCOMP_TASK_ORDER::NO_TASK,
227 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
false);
230 if (**mParallelCap >= 0) {
231 mSubParallelCapacitor0 =
232 std::make_shared<SP::Ph1::Capacitor>(**mName +
"_cap0", mLogLevel);
233 mSubParallelCapacitor0->setParameters(**mParallelCap / 2.);
234 mSubParallelCapacitor0->connect(
235 SimNode::List{SimNode::GND, mTerminals[0]->node()});
236 mSubParallelCapacitor0->initialize(mFrequencies);
237 mSubParallelCapacitor0->initializeFromNodesAndTerminals(frequency);
238 addMNASubComponent(mSubParallelCapacitor0, MNA_SUBCOMP_TASK_ORDER::NO_TASK,
239 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
241 mSubParallelCapacitor1 =
242 std::make_shared<SP::Ph1::Capacitor>(**mName +
"_cap1", mLogLevel);
243 mSubParallelCapacitor1->setParameters(**mParallelCap / 2.);
244 mSubParallelCapacitor1->connect(
245 SimNode::List{SimNode::GND, mTerminals[1]->node()});
246 mSubParallelCapacitor1->initialize(mFrequencies);
247 mSubParallelCapacitor1->initializeFromNodesAndTerminals(frequency);
248 addMNASubComponent(mSubParallelCapacitor1, MNA_SUBCOMP_TASK_ORDER::NO_TASK,
249 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
true);
254 "\n--- Initialization from powerflow ---"
255 "\nVoltage across: {:s}"
257 "\nTerminal 0 voltage: {:s}"
258 "\nTerminal 1 voltage: {:s}"
259 "\nVirtual Node 1 voltage: {:s}"
260 "\n--- Initialization from powerflow finished ---",
261 Logger::phasorToString((**mIntfVoltage)(0, 0)),
262 Logger::phasorToString((**mIntfCurrent)(0, 0)),
263 Logger::phasorToString(initialSingleVoltage(0)),
264 Logger::phasorToString(initialSingleVoltage(1)),
265 Logger::phasorToString(mVirtualNodes[0]->initialSingleVoltage()));
269 AttributeBase::List &prevStepDependencies,
270 AttributeBase::List &attributeDependencies,
271 AttributeBase::List &modifiedAttributes,
273 attributeDependencies.push_back(leftVector);
274 modifiedAttributes.push_back(mIntfVoltage);
275 modifiedAttributes.push_back(mIntfCurrent);
280 this->mnaUpdateVoltage(**leftVector);
281 this->mnaUpdateCurrent(**leftVector);
285 (**mIntfVoltage)(0, 0) = 0;
286 if (terminalNotGrounded(1))
287 (**mIntfVoltage)(0, 0) =
288 Math::complexFromVectorElement(leftVector, matrixNodeIndex(1));
289 if (terminalNotGrounded(0))
290 (**mIntfVoltage)(0, 0) =
291 (**mIntfVoltage)(0, 0) -
292 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0));
296 (**mIntfCurrent)(0, 0) = mSubSeriesInductor->intfCurrent()(0, 0);
299 MNAInterface::List SP::Ph1::PiLine::mnaTearGroundComponents() {
300 MNAInterface::List gndComponents;
302 gndComponents.push_back(mSubParallelResistor0);
303 gndComponents.push_back(mSubParallelResistor1);
305 if (**mParallelCap >= 0) {
306 gndComponents.push_back(mSubParallelCapacitor0);
307 gndComponents.push_back(mSubParallelCapacitor1);
310 return gndComponents;
313 void SP::Ph1::PiLine::mnaTearInitialize(Real omega, Real timeStep) {
314 mSubSeriesResistor->mnaTearSetIdx(mTearIdx);
315 mSubSeriesResistor->mnaTearInitialize(omega, timeStep);
316 mSubSeriesInductor->mnaTearSetIdx(mTearIdx);
317 mSubSeriesInductor->mnaTearInitialize(omega, timeStep);
320 void SP::Ph1::PiLine::mnaTearApplyMatrixStamp(SparseMatrixRow &tearMatrix) {
321 mSubSeriesResistor->mnaTearApplyMatrixStamp(tearMatrix);
322 mSubSeriesInductor->mnaTearApplyMatrixStamp(tearMatrix);
325 void SP::Ph1::PiLine::mnaTearApplyVoltageStamp(Matrix &voltageVector) {
326 mSubSeriesInductor->mnaTearApplyVoltageStamp(voltageVector);
329 void SP::Ph1::PiLine::mnaTearPostStep(Complex voltage, Complex current) {
330 mSubSeriesInductor->mnaTearPostStep(voltage - current * **mSeriesRes,
Base class for composite power components.
String type()
Get component type (cross-platform)
PI-line static phasor model.
void setBaseVoltage(Real baseVoltage)
Set base voltage.
void calculatePerUnitParameters(Real baseApparentPower, Real baseOmega)
Calculates component's parameters in specified per-unit system.
const Attribute< Matrix >::Ptr mActivePowerBranch
branch active powerflow [W], coef(0) has data from node 0, coef(1) from node 1.
const Attribute< MatrixComp >::Ptr mCurrent
branch Current flow [A], coef(0) has data from node 0, coef(1) from node 1.
const Attribute< Matrix >::Ptr mReactivePowerBranch
branch reactive powerflow [Var], coef(0) has data from node 0, coef(1) from node 1.
void mnaParentAddPostStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes, Attribute< Matrix >::Ptr &leftVector) override
add MNA post-step dependencies
void updateBranchFlow(VectorComp ¤t, VectorComp &powerflow)
updates branch current and power flow, input pu value, update with real value
void mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post-step operations.
MatrixComp Y_element()
get admittance matrix
void pfApplyAdmittanceMatrixStamp(SparseMatrixCompRow &Y) override
Stamps admittance matrix.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Updates internal current variable of the component.
PiLine(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
SimPowerComp< Complex >::Ptr clone(String copySuffix) override
DEPRECATED: Delete method.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes component from power flow data.
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Updates internal voltage variable of the component.
void storeNodalInjection(Complex powerInjection)
stores nodal injection power in this line object
Base class for all components that are transmitting power.
const Attribute< MatrixVar< Complex > >::Ptr mIntfCurrent
Current through component.
const Attribute< MatrixVar< Complex > >::Ptr mIntfVoltage
Voltage between terminals.
Logger::Log mSLog
Component logger.