DPsim
Loading...
Searching...
No Matches
PFSolver.cpp
1/* Copyright 2017-2021 Institute for Automation of Complex Power Systems,
2 * EONERC, RWTH Aachen University
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 *********************************************************************************/
8
9#include <dpsim/PFSolver.h>
10#include <dpsim/SequentialScheduler.h>
11#include <iostream>
12
13using namespace DPsim;
14using namespace CPS;
15
16PFSolver::PFSolver(CPS::String name, CPS::SystemTopology system,
17 CPS::Real timeStep, CPS::Logger::Level logLevel)
18 : Solver(name + "_PF", logLevel) {
19 mSystem = system;
20 mTimeStep = timeStep;
21}
22
24 SPDLOG_LOGGER_INFO(mSLog, "#### INITIALIZATION OF POWERFLOW SOLVER ");
25 for (auto comp : mSystem.mComponents) {
26 if (std::shared_ptr<CPS::SP::Ph1::SynchronGenerator> gen =
27 std::dynamic_pointer_cast<CPS::SP::Ph1::SynchronGenerator>(comp))
28 mSynchronGenerators.push_back(gen);
29 else if (std::shared_ptr<CPS::SP::Ph1::Load> load =
30 std::dynamic_pointer_cast<CPS::SP::Ph1::Load>(comp))
31 mLoads.push_back(load);
32 else if (std::shared_ptr<CPS::SP::Ph1::Transformer> trafo =
33 std::dynamic_pointer_cast<CPS::SP::Ph1::Transformer>(comp))
34 mTransformers.push_back(trafo);
35 else if (std::shared_ptr<CPS::SP::Ph1::PiLine> line =
36 std::dynamic_pointer_cast<CPS::SP::Ph1::PiLine>(comp))
37 mLines.push_back(line);
38 else if (std::shared_ptr<CPS::SP::Ph1::NetworkInjection> extnet =
39 std::dynamic_pointer_cast<CPS::SP::Ph1::NetworkInjection>(
40 comp))
41 mExternalGrids.push_back(extnet);
42 else if (std::shared_ptr<CPS::SP::Ph1::Shunt> shunt =
43 std::dynamic_pointer_cast<CPS::SP::Ph1::Shunt>(comp))
44 mShunts.push_back(shunt);
45 else if (std::shared_ptr<CPS::SP::Ph1::SolidStateTransformer> sst =
46 std::dynamic_pointer_cast<CPS::SP::Ph1::SolidStateTransformer>(
47 comp))
48 mSolidStateTransformers.push_back(sst);
49 else if (std::shared_ptr<CPS::SP::Ph1::AvVoltageSourceInverterDQ> vsi =
50 std::dynamic_pointer_cast<
52 mAverageVoltageSourceInverters.push_back(vsi);
53 }
54 }
55
62
64 mX.setZero(mNumUnknowns);
65 mF.setZero(mNumUnknowns);
66}
67
71
73 auto sparseJ = mJ.sparseView();
74 Eigen::SparseLU<SparseMatrix> lu(sparseJ);
75 mX = lu.solve(mF);
76}
77
79 SPDLOG_LOGGER_INFO(mSLog, "Assigning simulation nodes to topology nodes:");
80 UInt matrixNodeIndexIdx = 0;
81 for (UInt idx = 0; idx < mSystem.mNodes.size(); ++idx) {
82 mSystem.mNodes[idx]->setMatrixNodeIndex(0, matrixNodeIndexIdx);
83 SPDLOG_LOGGER_INFO(mSLog, "Node {}: MatrixNodeIndex {}",
84 mSystem.mNodes[idx]->uid(),
85 mSystem.mNodes[idx]->matrixNodeIndex());
86 ++matrixNodeIndexIdx;
87 }
88 SPDLOG_LOGGER_INFO(mSLog, "Number of simulation nodes: {:d}",
89 matrixNodeIndexIdx);
90}
91
93 for (auto comp : mSystem.mComponents) {
94 std::dynamic_pointer_cast<SimPowerComp<Complex>>(comp)
95 ->updateMatrixNodeIndices();
96 }
97
98 SPDLOG_LOGGER_INFO(
99 mSLog, "-- Initialize components from terminals or nodes of topology");
100 for (auto comp : mSystem.mComponents) {
101 auto pComp = std::dynamic_pointer_cast<SimPowerComp<Complex>>(comp);
102 if (!pComp)
103 continue;
105 pComp->initializeFromNodesAndTerminals(mSystem.mSystemFrequency);
106 }
107
108 SPDLOG_LOGGER_INFO(mSLog,
109 "-- Calculate per unit parameters for all components");
110 for (auto extnet : mExternalGrids) {
111 extnet->calculatePerUnitParameters(mBaseApparentPower,
112 mSystem.mSystemOmega);
113 }
114 for (auto line : mLines) {
115 line->calculatePerUnitParameters(mBaseApparentPower, mSystem.mSystemOmega);
116 }
117 for (auto trans : mTransformers) {
118 trans->calculatePerUnitParameters(mBaseApparentPower, mSystem.mSystemOmega);
119 }
120 for (auto shunt : mShunts) {
121 shunt->calculatePerUnitParameters(mBaseApparentPower, mSystem.mSystemOmega);
122 }
123 for (auto load : mLoads) {
124 load->calculatePerUnitParameters(mBaseApparentPower, mSystem.mSystemOmega);
125 }
126 for (auto gen : mSynchronGenerators) {
127 gen->calculatePerUnitParameters(mBaseApparentPower, mSystem.mSystemOmega);
128 }
129 for (auto sst : mSolidStateTransformers) {
130 sst->calculatePerUnitParameters(mBaseApparentPower, mSystem.mSystemOmega);
131 }
132}
133
135 Real maxPower = 0.;
136 if (!mSynchronGenerators.empty()) {
137 for (auto gen : mSynchronGenerators)
138 if (std::abs(gen->attributeTyped<Real>("P_set")->get()) > maxPower)
139 maxPower = std::abs(gen->attributeTyped<Real>("P_set")->get());
140 } else if (!mTransformers.empty()) {
141 for (auto trafo : mTransformers)
142 if (trafo->attributeTyped<Real>("S")->get() > maxPower)
143 maxPower = trafo->attributeTyped<Real>("S")->get();
144 }
145 if (maxPower != 0.)
146 mBaseApparentPower = pow(10, 1 + floor(log10(maxPower)));
147 else {
148 mBaseApparentPower = 100000000;
149 SPDLOG_LOGGER_WARN(mSLog,
150 "No suitable quantity found for setting "
151 "mBaseApparentPower. Using {} VA.",
153 }
154 SPDLOG_LOGGER_INFO(mSLog, "Base power = {} VA", mBaseApparentPower);
155}
156
158 mPQBusIndices.clear();
159 mPVBusIndices.clear();
160 mVDBusIndices.clear();
161
162 SPDLOG_LOGGER_INFO(mSLog, "-- Determine powerflow bus type for each node");
163
164 // Determine powerflow bus type of each node through analysis of system topology
165 for (auto node : mSystem.mNodes) {
166 bool connectedPV = false;
167 bool connectedPQ = false;
168 bool connectedVD = false;
169
170 for (auto comp : mSystem.mComponentsAtNode[node]) {
171 if (std::shared_ptr<CPS::SP::Ph1::Load> load =
172 std::dynamic_pointer_cast<CPS::SP::Ph1::Load>(comp)) {
173 if (load->mPowerflowBusType == CPS::PowerflowBusType::PQ) {
174 connectedPQ = true;
175 }
176 } else if (std::shared_ptr<CPS::SP::Ph1::SynchronGenerator> gen =
177 std::dynamic_pointer_cast<CPS::SP::Ph1::SynchronGenerator>(
178 comp)) {
179 if (gen->mPowerflowBusType == CPS::PowerflowBusType::PV) {
180 connectedPV = true;
181 } else if (gen->mPowerflowBusType == CPS::PowerflowBusType::VD) {
182 connectedVD = true;
183 }
184 } else if (std::shared_ptr<CPS::SP::Ph1::NetworkInjection> extnet =
185 std::dynamic_pointer_cast<CPS::SP::Ph1::NetworkInjection>(
186 comp)) {
187 if (extnet->mPowerflowBusType == CPS::PowerflowBusType::VD) {
188 connectedVD = true;
189 } else if (extnet->mPowerflowBusType == CPS::PowerflowBusType::PV) {
190 connectedPV = true;
191 }
192 }
193 }
194
195 // determine powerflow bus types according connected type of connected components
196 // only PQ type component connected -> set as PQ bus
197 if (!connectedPV && connectedPQ && !connectedVD) {
198 SPDLOG_LOGGER_INFO(
199 mSLog, "{}: only PQ type component connected -> set as PQ bus",
200 node->name());
201 mPQBusIndices.push_back(node->matrixNodeIndex());
202 mPQBuses.push_back(node);
203 } // no component connected -> set as PQ bus (P & Q will be zero)
204 else if (!connectedPV && !connectedPQ && !connectedVD) {
205 SPDLOG_LOGGER_INFO(mSLog, "{}: no component connected -> set as PQ bus",
206 node->name());
207 mPQBusIndices.push_back(node->matrixNodeIndex());
208 mPQBuses.push_back(node);
209 } // only PV type component connected -> set as PV bus
210 else if (connectedPV && !connectedPQ && !connectedVD) {
211 SPDLOG_LOGGER_INFO(
212 mSLog, "{}: only PV type component connected -> set as PV bus",
213 node->name());
214 mPVBusIndices.push_back(node->matrixNodeIndex());
215 mPVBuses.push_back(node);
216 } // PV and PQ type component connected -> set as PV bus (TODO: bus type should be modifiable by user afterwards)
217 else if (connectedPV && connectedPQ && !connectedVD) {
218 SPDLOG_LOGGER_INFO(
219 mSLog, "{}: PV and PQ type component connected -> set as PV bus",
220 node->name());
221 mPVBusIndices.push_back(node->matrixNodeIndex());
222 mPVBuses.push_back(node);
223 } // only VD type component connected -> set as VD bus
224 else if (!connectedPV && !connectedPQ && connectedVD) {
225 SPDLOG_LOGGER_INFO(
226 mSLog, "{}: only VD type component connected -> set as VD bus",
227 node->name());
228 mVDBusIndices.push_back(node->matrixNodeIndex());
229 mVDBuses.push_back(node);
230 } // VD and PV type component connect -> set as VD bus
231 else if (connectedPV && !connectedPQ && connectedVD) {
232 SPDLOG_LOGGER_INFO(
233 mSLog, "{}: VD and PV type component connect -> set as VD bus",
234 node->name());
235 mVDBusIndices.push_back(node->matrixNodeIndex());
236 mVDBuses.push_back(node);
237 } // VD, PV and PQ type component connect -> set as VD bus
238 else if (connectedPV && connectedPQ && connectedVD) {
239 SPDLOG_LOGGER_INFO(
240 mSLog, "{}: VD, PV and PQ type component connect -> set as VD bus",
241 node->name());
242 mVDBusIndices.push_back(node->matrixNodeIndex());
243 mVDBuses.push_back(node);
244 } else {
245 std::stringstream ss;
246 ss << "Node>>" << node->name()
247 << ": combination of connected components is invalid";
248 throw std::invalid_argument(ss.str());
249 }
250 }
251
252 mNumPQBuses = mPQBusIndices.size();
253 mNumPVBuses = mPVBusIndices.size();
254 mNumVDBuses = mVDBusIndices.size();
256
257 // Aggregate PQ bus and PV bus index vectors for easy handling in solver
259 mPQPVBusIndices.insert(mPQPVBusIndices.end(), mPQBusIndices.begin(),
260 mPQBusIndices.end());
261 mPQPVBusIndices.insert(mPQPVBusIndices.end(), mPVBusIndices.begin(),
262 mPVBusIndices.end());
263
264 SPDLOG_LOGGER_INFO(mSLog, "#### Create index vectors for power flow solver:");
265 SPDLOG_LOGGER_INFO(mSLog, "PQ Buses: {}", logVector(mPQBusIndices));
266 SPDLOG_LOGGER_INFO(mSLog, "PV Buses: {}", logVector(mPVBusIndices));
267 SPDLOG_LOGGER_INFO(mSLog, "VD Buses: {}", logVector(mVDBusIndices));
268}
269
271
272 SPDLOG_LOGGER_INFO(mSLog, "-- Determine base voltages for each node "
273 "according to connected components");
274 mSLog->flush();
275
276 for (auto node : mSystem.mNodes) {
277 CPS::Real baseVoltage_ = 0;
278 for (auto comp : mSystem.mComponentsAtNode[node]) {
279 if (std::shared_ptr<CPS::SP::Ph1::AvVoltageSourceInverterDQ> vsi =
280 std::dynamic_pointer_cast<
282 baseVoltage_ = vsi->getNomVoltage();
283 SPDLOG_LOGGER_INFO(
284 mSLog,
285 "Choose base voltage {}V of {} to convert pu-solution of {}.",
286 baseVoltage_, vsi->name(), node->name());
287 break;
288 } else if (std::shared_ptr<CPS::SP::Ph1::RXLine> rxline =
289 std::dynamic_pointer_cast<CPS::SP::Ph1::RXLine>(comp)) {
290 baseVoltage_ = rxline->getBaseVoltage();
291 SPDLOG_LOGGER_INFO(
292 mSLog,
293 "Choose base voltage {}V of {} to convert pu-solution of {}.",
294 baseVoltage_, rxline->name(), node->name());
295 break;
296 } else if (std::shared_ptr<CPS::SP::Ph1::PiLine> line =
297 std::dynamic_pointer_cast<CPS::SP::Ph1::PiLine>(comp)) {
298 baseVoltage_ = line->getBaseVoltage();
299 SPDLOG_LOGGER_INFO(
300 mSLog,
301 "Choose base voltage {}V of {} to convert pu-solution of {}.",
302 baseVoltage_, line->name(), node->name());
303 break;
304 } else if (std::shared_ptr<CPS::SP::Ph1::Transformer> trans =
305 std::dynamic_pointer_cast<CPS::SP::Ph1::Transformer>(
306 comp)) {
307 if (trans->terminal(0)->node()->name() == node->name()) {
308 baseVoltage_ = trans->getNominalVoltageEnd1();
309 SPDLOG_LOGGER_INFO(
310 mSLog,
311 "Choose base voltage {}V of {} to convert pu-solution of {}.",
312 baseVoltage_, trans->name(), node->name());
313 break;
314 } else if (trans->terminal(1)->node()->name() == node->name()) {
315 baseVoltage_ = trans->getNominalVoltageEnd2();
316 SPDLOG_LOGGER_INFO(
317 mSLog,
318 "Choose base voltage {}V of {} to convert pu-solution of {}.",
319 baseVoltage_, trans->name(), node->name());
320 break;
321 }
322 } else if (std::shared_ptr<CPS::SP::Ph1::SynchronGenerator> gen =
323 std::dynamic_pointer_cast<CPS::SP::Ph1::SynchronGenerator>(
324 comp)) {
325 baseVoltage_ = gen->getBaseVoltage();
326 SPDLOG_LOGGER_INFO(
327 mSLog,
328 "Choose base voltage {}V of {} to convert pu-solution of {}.",
329 baseVoltage_, gen->name(), node->name());
330 break;
331 } else if (std::shared_ptr<CPS::SP::Ph1::Load> load =
332 std::dynamic_pointer_cast<CPS::SP::Ph1::Load>(comp)) {
333 baseVoltage_ = load->getNomVoltage();
334 SPDLOG_LOGGER_INFO(
335 mSLog, "Choose base voltage of {} V to convert pu-solution of {}.",
336 baseVoltage_, load->name(), node->name());
337 break;
338 } else if (std::shared_ptr<CPS::SP::Ph1::NetworkInjection> extnet =
339 std::dynamic_pointer_cast<CPS::SP::Ph1::NetworkInjection>(
340 comp)) {
341 baseVoltage_ = extnet->getBaseVoltage();
342 SPDLOG_LOGGER_INFO(
343 mSLog, "Choose base voltage of {}V to convert pu-solution of {}.",
344 baseVoltage_, extnet->name(), node->name());
345 break;
346 } else {
347 SPDLOG_LOGGER_WARN(mSLog, "Unable to get base voltage at {}",
348 node->name());
349 }
350 }
351 mBaseVoltageAtNode[node] = baseVoltage_;
352 }
353 UInt numMissing = 0;
354 UInt numZero = 0;
355
356 for (auto node : mSystem.mNodes) {
357
358 auto it = mBaseVoltageAtNode.find(node);
359
360 if (it == mBaseVoltageAtNode.end()) {
361 SPDLOG_LOGGER_WARN(mSLog, "No base voltage entry for {}", node->name());
362
363 numMissing++;
364 continue;
365 }
366
367 if (std::abs(it->second) < 1e-6) {
368 SPDLOG_LOGGER_WARN(mSLog, "Zero base voltage for {}", node->name());
369
370 numZero++;
371 }
372 }
373
374 SPDLOG_LOGGER_INFO(mSLog, "Base voltage summary: missing={}, zero={}",
375 numMissing, numZero);
376}
377
378void PFSolver::setVDNode(CPS::String name) {
379 if (!mExternalGrids.empty()) {
380 if (mExternalGrids[0]->node(0)->name() == name) {
381 mExternalGrids[0]->modifyPowerFlowBusType(CPS::PowerflowBusType::VD);
382 }
383 } else {
384 for (auto gen : mSynchronGenerators) {
385 if (gen->node(0)->name() == name) {
386 gen->modifyPowerFlowBusType(CPS::PowerflowBusType::VD);
387 return;
388 }
389 }
390 throw std::invalid_argument("Invalid slack bus, no external grid or "
391 "synchronous generator attached");
392 }
393}
394
396 CPS::String name, CPS::PowerflowBusType powerFlowBusType) {
397 for (auto comp : mSystem.mComponents) {
398 if (comp->name() == name) {
399 if (std::shared_ptr<CPS::SP::Ph1::NetworkInjection> extnet =
400 std::dynamic_pointer_cast<CPS::SP::Ph1::NetworkInjection>(comp))
401 extnet->modifyPowerFlowBusType(powerFlowBusType);
402 else if (std::shared_ptr<CPS::SP::Ph1::SynchronGenerator> gen =
403 std::dynamic_pointer_cast<CPS::SP::Ph1::SynchronGenerator>(
404 comp))
405 gen->modifyPowerFlowBusType(powerFlowBusType);
406 }
407 }
408}
409
410void PFSolver::setSolverAndComponentBehaviour(Solver::Behaviour behaviour) {
411 mBehaviour = behaviour;
412 if (mBehaviour == Behaviour::Initialization) {
413 SPDLOG_LOGGER_INFO(mSLog, "-- Set solver behaviour to Initialization");
414 // TODO: solver setting specific to initialization (e.g. one single PF run)
415
416 SPDLOG_LOGGER_INFO(mSLog, "-- Set component behaviour to Initialization");
417 for (auto comp : mSystem.mComponents) {
418 auto powerComp =
419 std::dynamic_pointer_cast<CPS::TopologicalPowerComp>(comp);
420 if (powerComp)
421 powerComp->setBehaviour(
422 TopologicalPowerComp::Behaviour::Initialization);
423 }
424 } else {
425 SPDLOG_LOGGER_INFO(mSLog, "-- Set solver behaviour to Simulation");
426 // TODO: solver setting specific to simulation
427
428 SPDLOG_LOGGER_INFO(mSLog, "-- Set component behaviour to PFSimulation");
429 for (auto comp : mSystem.mComponents) {
430 auto powerComp =
431 std::dynamic_pointer_cast<CPS::TopologicalPowerComp>(comp);
432 if (powerComp)
433 powerComp->setBehaviour(TopologicalPowerComp::Behaviour::PFSimulation);
434 }
435 }
436}
437
439 int n = mSystem.mNodes.size();
440 if (n > 0) {
441 mY = CPS::SparseMatrixComp(n, n);
442 for (auto line : mLines) {
443 line->pfApplyAdmittanceMatrixStamp(mY);
444 }
445 for (auto trans : mTransformers) {
446 //to check if this transformer could be ignored
447 if (**trans->mResistance == 0 && **trans->mInductance == 0) {
448 SPDLOG_LOGGER_INFO(mSLog, "{} {} ignored for R = 0 and L = 0",
449 trans->type(), trans->name());
450 continue;
451 }
452 trans->pfApplyAdmittanceMatrixStamp(mY);
453 }
454 for (auto shunt : mShunts) {
455 shunt->pfApplyAdmittanceMatrixStamp(mY);
456 }
457 }
458 if (mLines.empty() && mTransformers.empty()) {
459 throw std::invalid_argument("There are no bus");
460 }
461}
462
463CPS::Real PFSolver::G(int i, int j) { return mY.coeff(i, j).real(); }
464
465CPS::Real PFSolver::B(int i, int j) { return mY.coeff(i, j).imag(); }
466
468 // Converged if all mismatches are below the tolerance
469 for (CPS::UInt i = 0; i < mNumUnknowns; i++) {
470 if (abs(mF(i)) > mTolerance)
471 return false;
472 }
473 return true;
474}
475
477
478 // Reset values for new power flow run
479 isConverged = false;
480 mIterations = 0;
481 mX.setZero();
482 mF.setZero();
483
484 // Calculate the mismatch according to the initial solution
486
487 // Check whether model already converged
489
490 for (unsigned i = 1; i < mMaxIterations && !isConverged; ++i) {
491
493
494 // Solve system mJ*mX = mF
496
497 // Calculate new solution based on mX increments obtained from equation system
499
500 // Calculate the mismatch according to the current solution
502
503 SPDLOG_LOGGER_DEBUG(mSLog, "Mismatch vector at iteration {}: \n {}", i, mF);
504 mSLog->flush();
505
506 // Check convergence
508 mIterations = i;
509 }
510 return isConverged;
511}
512
513void PFSolver::SolveTask::execute(Real time, Int timeStepCount) {
514 // apply keepLastSolution to save computation time
515 mSolver.generateInitialSolution(time, mSolver.mKeepLastSolution);
516 mSolver.solvePowerflow();
517 mSolver.setSolution();
518}
519
520Task::List PFSolver::getTasks() {
521 return Task::List{std::make_shared<SolveTask>(*this)};
522}
void determinePFBusType()
Determine bus type for all buses.
Definition PFSolver.cpp:157
std::vector< std::shared_ptr< CPS::SP::Ph1::Load > > mLoads
Vector of load components.
Definition PFSolver.h:67
CPS::Bool mKeepLastSolution
Use last converged solution as initial guess.
Definition PFSolver.h:96
CPS::TopologicalNode::List mPQBuses
Vector of nodes characterized as PQ buses.
Definition PFSolver.h:32
UInt mNumPQBuses
Number of PQ nodes.
Definition PFSolver.h:24
virtual void solveJacobianSystem()
Solve the linearized system mJ*mX = mF into mX; sparse subclass overrides.
Definition PFSolver.cpp:72
UInt mNumVDBuses
Number of PV nodes.
Definition PFSolver.h:28
Real mTolerance
Solver tolerance.
Definition PFSolver.h:81
CPS::String logVector(std::vector< CPS::UInt > indexVector)
Logging for integer vectors.
Definition PFSolver.h:138
std::vector< std::shared_ptr< CPS::SP::Ph1::PiLine > > mLines
Vector of line components.
Definition PFSolver.h:69
CPS::Task::List getTasks() override
Get tasks for scheduler.
Definition PFSolver.cpp:520
void assignMatrixNodeIndices()
Assignment of matrix indices for nodes.
Definition PFSolver.cpp:78
std::vector< CPS::UInt > mVDBusIndices
Vector with indices of VD buses.
Definition PFSolver.h:42
virtual void setUpJacobianStorage()
Allocate Jacobian storage; dense by default, sparse subclass overrides.
Definition PFSolver.cpp:68
void initializeComponents()
Initialization of individual components.
Definition PFSolver.cpp:92
std::vector< std::shared_ptr< CPS::SP::Ph1::SynchronGenerator > > mSynchronGenerators
Vector of synchronous generator components.
Definition PFSolver.h:65
std::vector< CPS::UInt > mPQBusIndices
Vector with indices of PQ buses.
Definition PFSolver.h:38
void modifyPowerFlowBusComponent(CPS::String name, CPS::PowerflowBusType powerFlowBusType)
Allows to modify the powerflow bus type of a specific component.
Definition PFSolver.cpp:395
std::vector< std::shared_ptr< CPS::SP::Ph1::NetworkInjection > > mExternalGrids
Vector of external grid components.
Definition PFSolver.h:73
std::vector< std::shared_ptr< CPS::SP::Ph1::SolidStateTransformer > > mSolidStateTransformers
Vector of solid state transformer components.
Definition PFSolver.h:62
std::vector< CPS::UInt > mPVBusIndices
Vector with indices of PV buses.
Definition PFSolver.h:40
void setVDNode(CPS::String name)
Set a node to VD using its name.
Definition PFSolver.cpp:378
std::vector< std::shared_ptr< CPS::SP::Ph1::Transformer > > mTransformers
Vector of transformer components.
Definition PFSolver.h:59
std::vector< std::shared_ptr< CPS::SP::Ph1::Shunt > > mShunts
Vector of shunt components.
Definition PFSolver.h:71
CPS::Bool checkConvergence()
Check whether below tolerance.
Definition PFSolver.cpp:467
CPS::Matrix mJ
Jacobian matrix.
Definition PFSolver.h:50
CPS::UInt mMaxIterations
Maximum number of iterations.
Definition PFSolver.h:83
CPS::Vector mX
Solution vector.
Definition PFSolver.h:52
std::vector< std::shared_ptr< CPS::SP::Ph1::AvVoltageSourceInverterDQ > > mAverageVoltageSourceInverters
Vector of average voltage source inverters.
Definition PFSolver.h:76
CPS::Real mBaseApparentPower
Base power of per-unit system.
Definition PFSolver.h:87
void setBaseApparentPower()
Set apparent base power of per-unit system.
Definition PFSolver.cpp:134
virtual void calculateMismatch()=0
Calculate mismatch.
CPS::SparseMatrixCompRow mY
Admittance matrix.
Definition PFSolver.h:47
UInt mNumPVBuses
Number of PV nodes.
Definition PFSolver.h:26
CPS::Real B(int i, int j)
Gets the imaginary part of admittance matrix element.
Definition PFSolver.cpp:465
void composeAdmittanceMatrix()
Compose admittance matrix.
Definition PFSolver.cpp:438
CPS::Bool isConverged
Convergence flag.
Definition PFSolver.h:89
CPS::Vector mF
Vector of mismatch values.
Definition PFSolver.h:54
CPS::UInt mIterations
Actual number of iterations.
Definition PFSolver.h:85
PFSolver(CPS::String name, CPS::SystemTopology system, Real timeStep, CPS::Logger::Level logLevel)
Constructor to be used in simulation examples.
Definition PFSolver.cpp:16
CPS::SystemTopology mSystem
System list.
Definition PFSolver.h:57
virtual void calculateJacobian()=0
Calculate the Jacobian.
void determineNodeBaseVoltages()
Determine base voltages for each node.
Definition PFSolver.cpp:270
void setSolverAndComponentBehaviour(Solver::Behaviour behaviour) override
set solver and component to initialization or simulation behaviour
Definition PFSolver.cpp:410
std::map< CPS::TopologicalNode::Ptr, CPS::Real > mBaseVoltageAtNode
Map providing determined base voltages for each node.
Definition PFSolver.h:78
virtual void setSolution()=0
Set final solution.
void initialize() override
Initialization of the solver.
Definition PFSolver.cpp:23
virtual void generateInitialSolution(Real time, bool keep_last_solution=false)=0
Generate initial solution for current time step.
virtual void updateSolution()=0
Update solution in each iteration.
Bool solvePowerflow()
Solves the powerflow problem.
Definition PFSolver.cpp:476
CPS::TopologicalNode::List mVDBuses
Vector of nodes characterized as VD buses.
Definition PFSolver.h:36
CPS::TopologicalNode::List mPVBuses
Vector of nodes characterized as PV buses.
Definition PFSolver.h:34
UInt mNumUnknowns
Number of unknowns, defining system dimension.
Definition PFSolver.h:30
CPS::Real G(int i, int j)
Gets the real part of admittance matrix element.
Definition PFSolver.cpp:463
std::vector< CPS::UInt > mPQPVBusIndices
Vector with indices of both PQ and PV buses.
Definition PFSolver.h:44
Real mTimeStep
Time step for fixed step solvers.
Definition Solver.h:47
Behaviour mBehaviour
Solver behaviour initialization or simulation.
Definition Solver.h:67
CPS::Logger::Log mSLog
Logger.
Definition Solver.h:45
Bool mInitFromNodesAndTerminals
Definition Solver.h:62