Skip to content

Commit

Permalink
#216 Implement shunt regulation model
Browse files Browse the repository at this point in the history
  • Loading branch information
Le Courtois Florent committed Dec 8, 2021
1 parent 53855c2 commit c57cae4
Show file tree
Hide file tree
Showing 42 changed files with 6,391 additions and 5,699 deletions.
32 changes: 26 additions & 6 deletions sources/Algo/include/Algo.h
Original file line number Diff line number Diff line change
Expand Up @@ -905,23 +905,42 @@ class DynModelAlgorithm : public NodeAlgorithm {
const inputs::DynamicDataBaseManager& manager_; ///< dynamic database config manager
};

/// @brief Shunts definition for a voltage level
struct VLShuntsDefinition {
/// @brief Hash for shunts definition
struct ShuntHash {
/**
* @brief Retrieve the hash value
*
* @param shunt the shunt to hash
* @return the hash value
*/
size_t operator()(const inputs::Shunt& shunt) const noexcept;
};
using ShuntsSet = std::unordered_set<inputs::Shunt, ShuntHash>; ///< Alias for set of shunts

ShuntsSet shunts; ///< Set of shunts for current voltage level
bool dynamicModelAssociated = false; ///< determines if the current voltage level is associated with a dynamic model
};

/**
* @brief Shunt counter definition
* @brief Shunt definitions
*/
struct ShuntCounterDefinitions {
std::unordered_map<inputs::VoltageLevel::VoltageLevelId, unsigned int> nbShunts; ///< Number of shunts by voltage level
struct ShuntDefinitions {
std::unordered_map<inputs::VoltageLevel::VoltageLevelId, VLShuntsDefinition> shunts; ///< Shunt definitions by voltage level
};

/**
* @brief Counter of shunts by voltage levels
*/
class ShuntCounterAlgorithm : public NodeAlgorithm {
class ShuntDefinitionAlgorithm : public NodeAlgorithm {
public:
/**
* @brief Constructor
* @param shuntCounterDefs the counter definitions to update
* @param manager dynamic data base manager
*/
explicit ShuntCounterAlgorithm(ShuntCounterDefinitions& shuntCounterDefs);
ShuntDefinitionAlgorithm(ShuntDefinitions& shuntCounterDefs, const inputs::DynamicDataBaseManager& manager);

/**
* @brief Performs the algorithm
Expand All @@ -933,7 +952,8 @@ class ShuntCounterAlgorithm : public NodeAlgorithm {
void operator()(const NodePtr& node);

private:
ShuntCounterDefinitions& shuntCounterDefs_; ///< the counter definitions to update
ShuntDefinitions& shuntDefs_; ///< the counter definitions to update
std::unordered_set<inputs::VoltageLevel::VoltageLevelId> voltageLevelsWithAssociation_; ///< dynamic data base manager
};

/**
Expand Down
17 changes: 14 additions & 3 deletions sources/Algo/src/Algo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,12 +705,23 @@ DynModelAlgorithm::MacroConnectHash::operator()(const MacroConnect& connect) con

/////////////////////////////////////////////////////////////////////////////////

ShuntCounterAlgorithm::ShuntCounterAlgorithm(ShuntCounterDefinitions& defs) : shuntCounterDefs_(defs) {}
ShuntDefinitionAlgorithm::ShuntDefinitionAlgorithm(ShuntDefinitions& defs, const inputs::DynamicDataBaseManager& manager) : shuntDefs_(defs) {
const auto& multiAssociations = manager.assemblingDocument().multipleAssociations();
std::transform(multiAssociations.begin(), multiAssociations.end(), std::inserter(voltageLevelsWithAssociation_, voltageLevelsWithAssociation_.begin()),
[](const inputs::AssemblingXmlDocument::MultipleAssociation& association) { return association.shunt.voltageLevel; });
}

void
ShuntCounterAlgorithm::operator()(const NodePtr& node) {
ShuntDefinitionAlgorithm::operator()(const NodePtr& node) {
auto vl = node->voltageLevel.lock();
shuntCounterDefs_.nbShunts[vl->id] += node->shunts.size();
auto& map = shuntDefs_.shunts[vl->id];
std::copy(node->shunts.begin(), node->shunts.end(), std::inserter(map.shunts, map.shunts.end()));
map.dynamicModelAssociated |= (voltageLevelsWithAssociation_.count(vl->id) > 0);
}

size_t
VLShuntsDefinition::ShuntHash::operator()(const inputs::Shunt& shunt) const noexcept {
return std::hash<inputs::Shunt::ShuntId>{}(shunt.id);
}

//////////////////////////////////////////////////////////////////////////////////
Expand Down
9 changes: 5 additions & 4 deletions sources/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Context::Context(const ContextDef& def, const inputs::Configuration& config) :

networkManager_.onNode(algo::MainConnexComponentAlgorithm(mainConnexNodes_));
networkManager_.onNode(algo::DynModelAlgorithm(dynamicModels_, dynamicDataBaseManager_));
networkManager_.onNode(algo::ShuntCounterAlgorithm(counters_));
networkManager_.onNode(algo::ShuntDefinitionAlgorithm(shuntDefinitions_, dynamicDataBaseManager_));
networkManager_.onNode(algo::LinesByIdAlgorithm(linesById_));
}

Expand Down Expand Up @@ -175,7 +175,7 @@ Context::exportOutputs() {
file::path dydOutput(config_.outputDir());
dydOutput.append(basename_ + ".dyd");
outputs::Dyd dydWriter(outputs::Dyd::DydDefinition(basename_, dydOutput.generic_string(), generators_, loads_, slackNode_, hvdcLineDefinitions_,
busesWithDynamicModel_, dynamicDataBaseManager_, dynamicModels_, svarcsDefinitions_));
busesWithDynamicModel_, dynamicDataBaseManager_, dynamicModels_, svarcsDefinitions_, shuntDefinitions_));
dydWriter.write();

// Par
Expand All @@ -191,14 +191,15 @@ Context::exportOutputs() {
file::path parOutput(config_.outputDir());
parOutput.append(basename_ + ".par");
outputs::Par parWriter(outputs::Par::ParDefinition(basename_, config_.outputDir(), parOutput, generators_, hvdcLineDefinitions_,
config_.getActivePowerCompensation(), busesWithDynamicModel_, dynamicDataBaseManager_, counters_,
config_.getActivePowerCompensation(), busesWithDynamicModel_, dynamicDataBaseManager_, shuntDefinitions_,
dynamicModels_, linesById_, svarcsDefinitions_));
parWriter.write();

// Diagram
file::path diagramDirectory(config_.outputDir());
diagramDirectory.append(basename_ + outputs::constants::diagramDirectorySuffix);
outputs::Diagram diagramWriter(outputs::Diagram::DiagramDefinition(basename_, diagramDirectory.generic_string(), generators_, hvdcLineDefinitions_));
outputs::Diagram diagramWriter(
outputs::Diagram::DiagramDefinition(basename_, diagramDirectory.generic_string(), generators_, hvdcLineDefinitions_, shuntDefinitions_));
diagramWriter.write();

if (def_.simulationKind == SimulationKind::SECURITY_ANALYSIS) {
Expand Down
2 changes: 1 addition & 1 deletion sources/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class Context {
algo::HVDCLineDefinitions hvdcLineDefinitions_; ///< hvdc definitions
algo::GeneratorDefinitionAlgorithm::BusGenMap busesWithDynamicModel_; ///< map of bus ids to a generator that regulates them
algo::DynamicModelDefinitions dynamicModels_; ///< model definitions
algo::ShuntCounterDefinitions counters_; ///< shunt counters definitions
algo::ShuntDefinitions shuntDefinitions_; ///< shunt definitions
algo::LinesByIdDefinitions linesById_; ///< Lines by ids definition
algo::StaticVarCompensatorDefinitions svarcsDefinitions_; ///< Static var compensators definitions to use
boost::optional<algo::ValidContingencies> validContingencies_; ///< contingencies accepted for simulation in a Security Analyasis
Expand Down
35 changes: 32 additions & 3 deletions sources/Inputs/include/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,44 @@ class Tfo {
/// @brief Topological shunt
struct Shunt {
using ShuntId = std::string; ///< alias for shunt id
using BusId = std::string; ///< Alias for bus id regulated by the shunt

/**
* @brief Constructor
* @brief Construct a new Shunt
*
* @param id the shunt id
* @param busId the bus regulated by the shunt
* @param targetV the target voltage of the shunt
* @param voltageRegulationOn whether voltage regulation is enabled for the shunt
* @param bs the vector of the susceptance values for the shunt
* @param sectionNumber initial section index
*/
explicit Shunt(const ShuntId& id) : id(id) {}
Shunt(const ShuntId& id, const BusId& busId, double targetV, bool voltageRegulationOn, const std::vector<double>& bs, unsigned int sectionNumber) :
id(id),
busId(busId),
targetV(targetV),
voltageRegulationOn(voltageRegulationOn),
bSections(bs),
sectionNumber(sectionNumber) {}

const ShuntId id; ///< Shunt id
/**
* @brief Equality operator
*
* comparing the ids
*
* @param other the shunt to compare to
* @return @b true if the shunts are equal, @b false if not
*/
bool operator==(const Shunt& other) const {
return id == other.id;
}

const ShuntId id; ///< Shunt id
const BusId busId; ///< the connected bus of the shunt
const double targetV; ///< the target V of the shunt
const bool voltageRegulationOn; ///< whether voltage regulation is enabled for the shunt
const std::vector<double> bSections; ///< the vector of the B values for the shunt
const unsigned int sectionNumber; ///< initial section index in sections
};

/// @brief Topological dangling line
Expand Down
8 changes: 7 additions & 1 deletion sources/Inputs/src/NetworkManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,14 @@ NetworkManager::buildTree() {
const auto& shunts = networkVL->getShuntCompensators();
std::unordered_map<Node::NodeId, std::vector<Shunt>> shuntsMap;
for (const auto& shunt : shunts) {
std::size_t nbSections = shunt->getMaximumSection() + 1; // We add the first section at 0
std::vector<double> bs(nbSections);
unsigned int i = 0;
std::generate(bs.begin(), bs.end(), [&shunt, &i]() { return shunt->getB(i++); });
// We take into account even disconnected shunts as dynamic models may aim to connect them
(shuntsMap[shunt->getBusInterface()->getID()]).push_back(std::move(Shunt(shunt->getID())));
(shuntsMap[shunt->getBusInterface()->getID()])
.push_back(std::move(
Shunt(shunt->getID(), shunt->getBusInterface()->getID(), shunt->getTargetV(), shunt->isVoltageRegulationOn(), bs, shunt->getCurrentSection())));
}

auto vl = std::make_shared<VoltageLevel>(networkVL->getID());
Expand Down
27 changes: 27 additions & 0 deletions sources/Outputs/include/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,22 @@
#pragma once

#include "Algo.h"
#include "Node.h"

#include <functional>
#include <limits>
#include <string>
#include <unordered_map>
#include <vector>

namespace dfl {
namespace outputs {
/// @brief Namespace for constant variables common to all writers
namespace constants {

/// @brief Alias for map of references to shunts by regulated bus id
using RefShuntsByIdMap = std::unordered_map<inputs::Shunt::BusId, std::vector<std::reference_wrapper<const inputs::Shunt>>>;

/**
* @brief Return a hash number from a string as input
* @param str The string that will serve as input for the hash function
Expand Down Expand Up @@ -59,6 +66,25 @@ computeQmax(double powerFactor, double pMax) {
*/
std::string diagramFilename(const std::string& id);

/**
* @brief Retrieve the shunt regulation id
*
* @param busId the bus id to which the shunt is connected
* @return the computed shunt regulation id
*/
static inline std::string
computeShuntRegulationId(const std::string& busId) {
return "ShuntRegulation_" + busId;
}

/**
* @brief Compute the list of shunts, sorting by regulated bus id
*
* @param shuntDefinitions the shund definitions to use
* @return the sorted list of shunts
*/
RefShuntsByIdMap computeFilteredShuntsByIds(const algo::ShuntDefinitions& shuntDefinitions);

const std::string networkModelName{"NETWORK"}; ///< Name of the model corresponding to network
const std::string loadParId{"GenericRestorativeLoad"}; ///< PAR id common to all loads
const std::string diagramDirectorySuffix{"_Diagram"}; ///< Suffix for the diagram directory
Expand All @@ -71,6 +97,7 @@ const std::string propSignalNGeneratorFixedPParId{"propSignalNGeneratorFixedP"};
const std::string remoteVControlParId{"remoteVControl"}; ///< PAR id for using remote voltage control
const std::string remoteSignalNGeneratorFixedP{"remoteSignalNFixedP"}; ///< PAR id for using remote signal N with fixed P
const std::string xmlEncoding{"UTF-8"}; ///< Default encoding for XML outputs files
const std::string diagramTableBPu{"tableBPu"}; ///< Name of the table in b sections diagram files

constexpr double powerValueMax = std::numeric_limits<double>::max(); ///< Maximum value for powers, meaning infinite

Expand Down
21 changes: 18 additions & 3 deletions sources/Outputs/include/Diagram.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#pragma once

#include "Algo.h"
#include "Constants.h"

#include <string>
#include <vector>
Expand All @@ -39,20 +40,24 @@ class Diagram {
* @param base the basename for current file (corresponds to filepath basename)
* @param directoryPath the directory path of the diagram files to write
* @param gens generators definition coming from algorithms
* @param hvdcDefinitions the HVDC definitions to used
* @param hvdcDefinitions the HVDC definitions to use
* @param shuntDefinitions shunt definitions to use
*/
DiagramDefinition(const std::string& base, const std::string& directoryPath, const std::vector<algo::GeneratorDefinition>& gens,
const algo::HVDCLineDefinitions& hvdcDefinitions) :
const algo::HVDCLineDefinitions& hvdcDefinitions, const algo::ShuntDefinitions& shuntDefinitions) :
basename(base),
directoryPath(directoryPath),
generators(gens),
hvdcDefinitions(hvdcDefinitions) {}
hvdcDefinitions(hvdcDefinitions),
shuntDefinitions(shuntDefinitions) {}

const std::string basename; ///< basename for file
const std::string directoryPath; ///< directory path for files to write
// non const copies instead of const references because we need to modify them before use
std::vector<algo::GeneratorDefinition> generators; ///< generators found
algo::HVDCLineDefinitions hvdcDefinitions; ///< HVDC definitions
//
const algo::ShuntDefinitions& shuntDefinitions; ///< Shunt definitions
};

/**
Expand Down Expand Up @@ -106,6 +111,8 @@ class Diagram {
void writeGenerators() const;
/// @brief Write VSC converters diagrams
void writeConverters() const;
/// @brief Write shunt diagrams
void writeShunts() const;

/**
* @brief Write VSC converter diagram
Expand All @@ -121,8 +128,16 @@ class Diagram {
*/
void writeLCC(const algo::HVDCDefinition::ConverterId& converterId, double powerFactor, double pMax) const;

/**
* @brief Write Shunt diagram
*
* @param shunt the shunt to export
*/
void writeShunt(const inputs::Shunt& shunt) const;

private:
DiagramDefinition def_; ///< Diagram file information
constants::RefShuntsByIdMap shuntsByBusId_;
};
} // namespace outputs
} // namespace dfl
37 changes: 35 additions & 2 deletions sources/Outputs/include/Dyd.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,13 @@ class Dyd {
* @param dynamicDataBaseManager the database manager to use
* @param models the list of dynamic models to use
* @param svarcsDefinitions the SVarC definitions to use
* @param shuntsDefinitions the shuntsDefinitions to use
*/
DydDefinition(const std::string& base, const std::string& filepath, const std::vector<algo::GeneratorDefinition>& gens,
const std::vector<algo::LoadDefinition>& loaddefs, const std::shared_ptr<inputs::Node>& slacknode,
const algo::HVDCLineDefinitions& hvdcDefinitions, const algo::GeneratorDefinitionAlgorithm::BusGenMap& busesWithDynamicModel,
const inputs::DynamicDataBaseManager& dynamicDataBaseManager, const algo::DynamicModelDefinitions& models,
const algo::StaticVarCompensatorDefinitions& svarcsDefinitions) :
const algo::StaticVarCompensatorDefinitions& svarcsDefinitions, const algo::ShuntDefinitions& shuntsDefinitions) :
basename(base),
filename(filepath),
generators(gens),
Expand All @@ -119,7 +120,8 @@ class Dyd {
busesWithDynamicModel(busesWithDynamicModel),
dynamicDataBaseManager(dynamicDataBaseManager),
dynamicModelsDefinitions(models),
svarcsDefinitions(svarcsDefinitions) {}
svarcsDefinitions(svarcsDefinitions),
shuntsDefinitions(shuntsDefinitions) {}

std::string basename; ///< basename for file
std::string filename; ///< filepath for file to write
Expand All @@ -131,6 +133,7 @@ class Dyd {
const inputs::DynamicDataBaseManager& dynamicDataBaseManager; ///< dynamic database manager
const algo::DynamicModelDefinitions& dynamicModelsDefinitions; ///< the list of dynamic models to export
const algo::StaticVarCompensatorDefinitions& svarcsDefinitions; ///< the SVarC definitions to use
const algo::ShuntDefinitions& shuntsDefinitions; ///< the shuntsDefinitions to use
};

/**
Expand Down Expand Up @@ -186,6 +189,24 @@ class Dyd {
*/
static boost::shared_ptr<dynamicdata::BlackBoxModel> writeHvdcLine(const algo::HVDCDefinition& hvdcLine, const std::string& basename);

/**
* @brief Write the black box model for shunt regulation
*
* @param busId the bus id to use
* @param basename the basename of the writer
* @return the model of the shunt regulation
*/
static boost::shared_ptr<dynamicdata::BlackBoxModel> writeShuntRegulation(const inputs::Shunt::BusId& busId, const std::string& basename);

/**
* @brief Write model for shunt with sections
*
* @param shunt the shunt to define the mode for
* @param basename the basename of the writer
* @return the model of the shunt with section
*/
static boost::shared_ptr<dynamicdata::BlackBoxModel> writeShuntBSections(const inputs::Shunt& shunt, const std::string& basename);

/**
* @brief Create constant models
*
Expand Down Expand Up @@ -302,6 +323,16 @@ class Dyd {
*/
static boost::shared_ptr<dynamicdata::MacroConnect> writeSVarCMacroConnect(const inputs::StaticVarCompensator& svarc);

/**
* @brief Write connection for shunt
*
* @param dynamicModelsToConnect the list of connections to update
* @param shunt the shunt to connect
* @param index the index of the shunts in the list of shunts by bus
*/
static void writeShuntConnect(const boost::shared_ptr<dynamicdata::DynamicModelsCollection>& dynamicModelsToConnect, const inputs::Shunt& shunt,
unsigned int index);

private:
static const std::unordered_map<algo::GeneratorDefinition::ModelType, std::string>
correspondence_lib_; ///< Correspondance between generator model type and library name in dyd file
Expand All @@ -318,6 +349,8 @@ class Dyd {
static const std::string macroStaticRefLoadName_; ///< Name for the static ref macro for loads
static const std::string signalNModelName_; ///< Name of the SignalN model
static const std::string modelSignalNQprefix_; ///< Prefix for SignalN models
static const std::string macroStaticRefShuntName_; ///< Static ref macro element name for shunt definition
static const std::string macroConnectorShuntName_; ///< macro connector name for shunt deifnition

private:
DydDefinition def_; ///< Dyd file information
Expand Down
Loading

0 comments on commit c57cae4

Please sign in to comment.