Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Added `enable` and `disable` solver events that put a branch in or out of service.
- `verify()` returns `Model::ConfigurationChecks` listing every configuration problem instead of an error count.
- Added `Model::ParameterReader`
- Added `ComponentManifest` with `MANIFEST` tables for IEEET1 and GENROU, and the `ComponentLibrary` model list.
- Removed legacy PhasorDynamics component constructors in favor of constructors taking model data.

## v0.2
Expand Down
104 changes: 104 additions & 0 deletions GridKit/Model/PhasorDynamics/ComponentData.hpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,113 @@
#pragma once

#include <array>
#include <cstddef>
#include <map>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <type_traits>
#include <variant>

#include <GridKit/Utilities/Enum.hpp>

namespace GridKit
{
namespace PhasorDynamics
{
/// Manifest entry describing one parameter
template <Utilities::SizedEnum EnumT>
struct ParameterEntry
{
EnumT key;
std::string_view units;
std::string_view symbol;
std::string_view description;

constexpr std::string_view name() const
{
return Utilities::enum_name(key);
}
};

/// Manifest entry describing one bus or signal port
template <Utilities::SizedEnum EnumT>
struct PortEntry
{
EnumT key;
std::string_view description;

constexpr std::string_view name() const
{
return Utilities::enum_name(key);
}
};

/// Manifest entry describing one monitored variable
template <Utilities::SizedEnum EnumT>
struct MonitorEntry
{
EnumT key;
std::string_view units;
std::string_view description;

constexpr std::string_view name() const
{
return Utilities::enum_name(key);
}
};

/// True when every enumeration value has exactly one described entry
template <typename EntryT, std::size_t N>
consteval bool entriesComplete(const std::array<EntryT, N>& entries)
{
for (std::size_t value = 0; value < N; ++value)
{
std::size_t described = 0;
for (const auto& entry : entries)
{
if (static_cast<std::size_t>(entry.key) == value && !entry.description.empty())
{
++described;
}
}
if (described != 1)
{
return false;
}
}
return true;
}

/// Units, symbols and descriptions of a component class, one entry per enumeration value
template <Utilities::SizedEnum ParametersT,
Utilities::SizedEnum BusesT,
Utilities::SizedEnum InputsT,
Utilities::SizedEnum OutputsT,
Utilities::SizedEnum MonitorsT>
struct ComponentManifest
{
template <typename EntryT, typename EnumT>
using Table = std::array<EntryT, Utilities::enum_size<EnumT>()>;

std::string_view class_name;
std::string_view description;
Table<ParameterEntry<ParametersT>, ParametersT> parameters;
Table<PortEntry<BusesT>, BusesT> buses;
Table<PortEntry<InputsT>, InputsT> inputs;
Table<PortEntry<OutputsT>, OutputsT> outputs;
Table<MonitorEntry<MonitorsT>, MonitorsT> monitors;

/// True when the class and description are set and every table is complete
consteval bool complete() const
{
return !class_name.empty() && !description.empty() && entriesComplete(parameters)
&& entriesComplete(buses) && entriesComplete(inputs)
&& entriesComplete(outputs) && entriesComplete(monitors);
}
};

/**
* @brief Unified interface for `Component` data containers
*
Expand Down Expand Up @@ -52,6 +149,13 @@ namespace GridKit
/// Enumeration over monitorable variables.
using MonitorableVariables = monitorable_variables_enum;

/// Units, symbols and descriptions of this component class
using Manifest = ComponentManifest<Parameters,
Buses,
SignalInputs,
SignalOutputs,
MonitorableVariables>;

/// Class of device this is for
std::string device_class;

Expand Down
26 changes: 26 additions & 0 deletions GridKit/Model/PhasorDynamics/ComponentLibrary.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#pragma once

#include <cstddef>
#include <type_traits>

#include <GridKit/Model/PhasorDynamics/Branch/Branch.hpp>
#include <GridKit/Model/PhasorDynamics/Bus/Bus.hpp>
#include <GridKit/Model/PhasorDynamics/Bus/BusInfinite.hpp>
Expand All @@ -23,3 +26,26 @@
#include <GridKit/Model/PhasorDynamics/SynchronousMachine/GENROU/Genrou.hpp>
#include <GridKit/Model/PhasorDynamics/SynchronousMachine/GENSAL/Gensal.hpp>
#include <GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp>
#include <GridKit/ScalarTraits.hpp>

namespace GridKit
{
namespace PhasorDynamics
{
/// Component models with a manifest, in `SystemModel` construction order
template <typename ScalarT = double, typename IdxT = size_t>
struct ComponentLibrary
{
/// Calls `visit` with each model type and its data type, in construction order
template <typename Visitor>
static constexpr void forEach(Visitor&& visit)
{
using RealT = typename ScalarTraits<ScalarT>::RealT;
visit(std::type_identity<Genrou<ScalarT, IdxT>>{},
std::type_identity<GenrouData<RealT, IdxT>>{});
visit(std::type_identity<Exciter::Ieeet1<ScalarT, IdxT>>{},
std::type_identity<Exciter::Ieeet1Data<RealT, IdxT>>{});
}
};
} // namespace PhasorDynamics
} // namespace GridKit
101 changes: 71 additions & 30 deletions GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file Ieeet1Data.hpp
* @author Luke Lowery (lukel@tamu.edu)
*
* @brief Data structure for IEEET1 Data
* @brief Data structure and manifest for IEEET1 Data
*
*/
#pragma once
Expand All @@ -18,42 +18,42 @@ namespace GridKit
/// Initial parameters for IEEET1 Exciter model
enum class Ieeet1Parameters : size_t
{
Tr, ///< Time constant for voltage sensing
Ka, ///< Coefficient for voltage regulation
Ta, ///< Time constant for voltage regulation
Ke, ///< Coefficient for excitation system
Te, ///< Time constant for excitation system
Kf, ///< Coefficient for feedback
Tf, ///< Time constant for feedback
Vrmin, ///< LL to voltage regulation
Vrmax, ///< HH to voltage regulation
E1, ///< Saturation parameter
E2, ///< Saturation parameter
Se1, ///< Saturation parameter
Se2, ///< Saturation parameter
Ispdlim, ///< Speed limit flag indicator
Tr,
Ka,
Ta,
Ke,
Te,
Kf,
Tf,
Vrmin,
Vrmax,
E1,
E2,
Se1,
Se2,
Ispdlim,
};

/// Buses for a IEEET1 Exciter model
enum class Ieeet1Buses : size_t
{
bus, ///< Unique ID of the terminal bus
bus,
};

/// Signal inputs for a IEEET1 Exciter model
enum class Ieeet1SignalInputs : size_t
{
speed, ///< Unique ID of the generator speed signal
vref, ///< Unique ID of the voltage reference signal (optional)
vs, ///< Unique ID of the stabilizer output signal (optional)
vuel, ///< Unique ID of the under-excitation limiter signal (optional)
voel, ///< Unique ID of the over-excitation limiter signal (optional)
speed,
vref,
vs,
vuel,
voel,
};

/// Signal outputs for a IEEET1 Exciter model
enum class Ieeet1SignalOutputs : size_t
{
efd, ///< Unique ID of the output efd signal
efd,
};

/// Variables able to be monitored for a IEEET1 Exciter model
Expand All @@ -72,14 +72,55 @@ namespace GridKit
* Integer parameters are of the same type as matrix and vector indices.
*/
template <typename real_type, typename index_type>
using Ieeet1Data =
ComponentData<real_type,
index_type,
Ieeet1Parameters,
Ieeet1Buses,
Ieeet1SignalInputs,
Ieeet1SignalOutputs,
Ieeet1MonitorableVariables>;
struct Ieeet1Data : ComponentData<real_type,
index_type,
Ieeet1Parameters,
Ieeet1Buses,
Ieeet1SignalInputs,
Ieeet1SignalOutputs,
Ieeet1MonitorableVariables>
{
/// Units, symbols and descriptions of the IEEET1 data
static constexpr typename Ieeet1Data::Manifest MANIFEST{
.class_name = "Ieeet1",
.description = "IEEE Type 1 excitation-system model",
.parameters = {{
{Ieeet1Parameters::Tr, "s", "T_R", "Time constant for voltage sensing"},
{Ieeet1Parameters::Ka, "p.u.", "K_A", "Coefficient for voltage regulation"},
{Ieeet1Parameters::Ta, "s", "T_A", "Time constant for voltage regulation"},
{Ieeet1Parameters::Ke, "p.u.", "K_E", "Exciter field resistance line slope margin, 0 requests automatic calculation"},
{Ieeet1Parameters::Te, "s", "T_E", "Time constant for excitation system"},
{Ieeet1Parameters::Kf, "p.u.", "K_F", "Coefficient for feedback"},
{Ieeet1Parameters::Tf, "s", "T_F", "Time constant for feedback"},
{Ieeet1Parameters::Vrmin, "p.u.", "V_R^{\\min}", "Lower limit to voltage regulation"},
{Ieeet1Parameters::Vrmax, "p.u.", "V_R^{\\max}", "Upper limit to voltage regulation"},
{Ieeet1Parameters::E1, "p.u.", "E_1", "Saturation parameter"},
{Ieeet1Parameters::E2, "p.u.", "E_2", "Saturation parameter"},
{Ieeet1Parameters::Se1, "p.u.", "S_1", "Saturation parameter"},
{Ieeet1Parameters::Se2, "p.u.", "S_2", "Saturation parameter"},
{Ieeet1Parameters::Ispdlim, "binary", "I_{\\mathrm{spdlim}}", "Speed limit flag indicator"},
}},
.buses = {{
{Ieeet1Buses::bus, "Terminal bus voltage"},
}},
.inputs = {{
{Ieeet1SignalInputs::speed, "Machine speed deviation"},
{Ieeet1SignalInputs::vref, "Voltage-control reference"},
{Ieeet1SignalInputs::vs, "Stabilizer input signal"},
{Ieeet1SignalInputs::vuel, "Under-excitation limiter input"},
{Ieeet1SignalInputs::voel, "Over-excitation limiter input"},
}},
.outputs = {{
{Ieeet1SignalOutputs::efd, "Field-voltage output seeded by the machine"},
}},
.monitors = {{
{Ieeet1MonitorableVariables::efd, "p.u.", "Field winding voltage"},
{Ieeet1MonitorableVariables::ksat, "p.u.", "Scaled-quadratic saturation contribution"},
}},
};

static_assert(MANIFEST.complete());
};
} // namespace Exciter
} // namespace PhasorDynamics
} // namespace GridKit
6 changes: 4 additions & 2 deletions GridKit/Model/PhasorDynamics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ files:
- `MyModel.hpp`: Component model declaration.
- `MyModelData.hpp`: Definitions of model data including model parameters,
model connection ports and model outputs (monitored
variables).
variables), and its `MANIFEST` holding their units,
symbols and descriptions.
- `MyModelDependencyTracking.cpp`: Compilation unit for Jacobian evaluation
using dependency tracking data type (a.k.a
tapeless automatic differentiation).
Expand Down Expand Up @@ -78,7 +79,8 @@ We recommend developers follow these steps when adding new component models:
should ensure residual evaluates to zero within prescribed tolerance).
5. Once model is tested, add it to the system composer. This requires following steps:
1. Add header file `MyModel.hpp` to `ComponentLibrary.hpp`, so that
`MyModel` declaration is visible to the `SystemModel` class.
`MyModel` declaration is visible to the `SystemModel` class, and add
`MyModel` to `ComponentLibrary` in construction order.
2. Modify `SystemModelDataJSONParser.hpp` so that `MyModel` is recognized by the
parser.
3. Modify `SystemModelData.hpp` so that `MyModelData` is visible to the system
Expand Down
Loading
Loading