9 #include <dpsim-models/SP/SP_Ph1_Load.h>
18 mActivePowerPerUnit(mAttributes->create<Real>(
"P_pu")),
19 mReactivePowerPerUnit(mAttributes->create<Real>(
"Q_pu")),
20 mActivePower(mAttributes->createDynamic<Real>(
22 mReactivePower(mAttributes->createDynamic<Real>(
24 mNomVoltage(mAttributes->create<Real>(
"V_nom")) {
26 SPDLOG_LOGGER_INFO(
mSLog,
"Create {} of type {}", **
mName, this->
type());
33 void SP::Ph1::Load::setParameters(Real activePower, Real reactivePower,
34 Real nominalVoltage) {
35 **mActivePower = activePower;
36 **mReactivePower = reactivePower;
37 **mNomVoltage = nominalVoltage;
39 SPDLOG_LOGGER_INFO(mSLog,
"Active Power={} [W] Reactive Power={} [VAr]",
40 **mActivePower, **mReactivePower);
43 mParametersSet =
true;
49 SPDLOG_LOGGER_INFO(mSLog,
"#### Calculate Per Unit Parameters for {}",
51 mBaseApparentPower = baseApparentPower;
52 mBaseOmega = baseOmega;
53 SPDLOG_LOGGER_INFO(mSLog,
"Base Power={} [VA] Base Omega={} [1/s]",
54 mBaseApparentPower, mBaseOmega);
56 **mActivePowerPerUnit = **mActivePower / mBaseApparentPower;
57 **mReactivePowerPerUnit = **mReactivePower / mBaseApparentPower;
58 SPDLOG_LOGGER_INFO(mSLog,
"Active Power={} [pu] Reactive Power={} [pu]",
59 **mActivePowerPerUnit, **mReactivePowerPerUnit);
64 switch (powerflowBusType) {
65 case CPS::PowerflowBusType::PV:
66 throw std::invalid_argument(
67 " Power flow bus type error, load currently cannot be set as PVNode ");
69 case CPS::PowerflowBusType::PQ:
70 mPowerflowBusType = powerflowBusType;
72 case CPS::PowerflowBusType::VD:
73 throw std::invalid_argument(
74 " Power flow bus type error, load cannot be set as VDNode ");
76 case CPS::PowerflowBusType::None:
79 throw std::invalid_argument(
" Invalid power flow bus type ");
85 if (mLoadProfile.weightingFactors.empty()) {
86 **mActivePower = mLoadProfile.pqData.find(time)->second.p;
87 **mReactivePower = mLoadProfile.pqData.find(time)->second.q;
89 Real wf = mLoadProfile.weightingFactors.find(time)->second;
91 Real P_new = this->attributeTyped<Real>(
"P_nom")->get() * wf;
92 Real Q_new = this->attributeTyped<Real>(
"Q_nom")->get() * wf;
93 **mActivePower = P_new;
94 **mReactivePower = Q_new;
100 if (!mParametersSet) {
101 setParameters(mTerminals[0]->singleActivePower(),
102 mTerminals[0]->singleReactivePower(),
103 std::abs(mTerminals[0]->initialSingleVoltage()));
107 if (**mActivePower != 0) {
108 mResistance = std::pow(**mNomVoltage, 2) / **mActivePower;
109 mConductance = 1.0 / mResistance;
110 mSubResistor = std::make_shared<SP::Ph1::Resistor>(
111 **mUID +
"_res", **mName +
"_res", Logger::Level::off);
112 mSubResistor->setParameters(mResistance);
113 mSubResistor->connect({SimNode::GND, mTerminals[0]->node()});
114 mSubResistor->initialize(mFrequencies);
115 mSubResistor->initializeFromNodesAndTerminals(frequency);
116 addMNASubComponent(mSubResistor, MNA_SUBCOMP_TASK_ORDER::NO_TASK,
117 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
false);
120 if (**mReactivePower != 0)
121 mReactance = std::pow(**mNomVoltage, 2) / **mReactivePower;
126 if (mReactance > 0) {
127 mInductance = mReactance / (2 * PI * frequency);
128 mSubInductor = std::make_shared<SP::Ph1::Inductor>(
129 **mUID +
"_res", **mName +
"_ind", Logger::Level::off);
130 mSubInductor->setParameters(mInductance);
131 mSubInductor->connect({SimNode::GND, mTerminals[0]->node()});
132 mSubInductor->initialize(mFrequencies);
133 mSubInductor->initializeFromNodesAndTerminals(frequency);
134 addMNASubComponent(mSubInductor, MNA_SUBCOMP_TASK_ORDER::NO_TASK,
135 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
false);
136 }
else if (mReactance < 0) {
137 mCapacitance = -1 / (2 * PI * frequency) / mReactance;
138 mSubCapacitor = std::make_shared<SP::Ph1::Capacitor>(
139 **mUID +
"_res", **mName +
"_cap", Logger::Level::off);
140 mSubCapacitor->setParameters(mCapacitance);
141 mSubCapacitor->connect({SimNode::GND, mTerminals[0]->node()});
142 mSubCapacitor->initialize(mFrequencies);
143 mSubCapacitor->initializeFromNodesAndTerminals(frequency);
144 addMNASubComponent(mSubCapacitor, MNA_SUBCOMP_TASK_ORDER::NO_TASK,
145 MNA_SUBCOMP_TASK_ORDER::TASK_BEFORE_PARENT,
false);
148 (**mIntfVoltage)(0, 0) = mTerminals[0]->initialSingleVoltage();
149 (**mIntfCurrent)(0, 0) = std::conj(Complex(attributeTyped<Real>(
"P")->get(),
150 attributeTyped<Real>(
"Q")->get()) /
151 (**mIntfVoltage)(0, 0));
153 SPDLOG_LOGGER_INFO(mSLog,
154 "\n--- Initialization from powerflow ---"
155 "\nVoltage across: {:s}"
157 "\nTerminal 0 voltage: {:s}"
158 "\n--- Initialization from powerflow finished ---",
159 Logger::phasorToString((**mIntfVoltage)(0, 0)),
160 Logger::phasorToString((**mIntfCurrent)(0, 0)),
161 Logger::phasorToString(initialSingleVoltage(0)));
162 SPDLOG_LOGGER_INFO(mSLog,
163 "Updated parameters according to powerflow:\n"
164 "Active Power={} [W] Reactive Power={} [VAr]",
165 attributeTyped<Real>(
"P")->get(),
166 attributeTyped<Real>(
"Q")->get());
172 void SP::Ph1::Load::mnaParentAddPostStepDependencies(
173 AttributeBase::List &prevStepDependencies,
174 AttributeBase::List &attributeDependencies,
175 AttributeBase::List &modifiedAttributes,
177 attributeDependencies.push_back(leftVector);
178 modifiedAttributes.push_back(mIntfCurrent);
179 modifiedAttributes.push_back(mIntfVoltage);
184 mnaCompUpdateVoltage(**leftVector);
185 mnaCompUpdateCurrent(**leftVector);
189 (**mIntfVoltage)(0, 0) =
190 Math::complexFromVectorElement(leftVector, matrixNodeIndex(0));
194 (**mIntfCurrent)(0, 0) = 0;
196 for (
auto &subc : mSubComponents) {
197 (**mIntfCurrent)(0, 0) += subc->intfCurrent()(0, 0);
Base class for composite power components.
const Attribute< String >::Ptr mName
Human readable name.
String type()
Get component type (cross-platform)
void mnaCompUpdateVoltage(const Matrix &leftVector) override
Updates internal voltage variable of the component.
void modifyPowerFlowBusType(PowerflowBusType powerflowBusType) override
Modify powerflow bus type.
void initializeFromNodesAndTerminals(Real frequency) override
Initializes component from power flow data.
Load(String uid, String name, Logger::Level logLevel=Logger::Level::off)
Defines UID, name and logging level.
void updatePQ(Real time)
Update PQ for this load for power flow calculation at next time step.
void mnaParentPostStep(Real time, Int timeStepCount, Attribute< Matrix >::Ptr &leftVector) override
MNA post step operations.
void mnaCompUpdateCurrent(const Matrix &leftVector) override
Updates internal current variable of the component.
void calculatePerUnitParameters(Real baseApparentPower, Real baseOmega)
Calculates component's parameters in specified per-unit system.
const Attribute< MatrixVar< Complex > >::Ptr mIntfCurrent
Current through component.
const Attribute< MatrixVar< Complex > >::Ptr mIntfVoltage
Voltage between terminals.
Logger::Log mSLog
Component logger.