From 68253cb37136ce2ba31da10a557f64a9a2dbbc79 Mon Sep 17 00:00:00 2001 From: lukelowry Date: Mon, 5 Oct 2026 13:21:14 -0500 Subject: [PATCH 1/6] remove BusFault and apply directly to bus instead --- CHANGELOG.md | 2 +- .../PhasorDynamics/BusFault/BusFault.cpp | 31 -- .../PhasorDynamics/BusFault/BusFault.hpp | 130 ----- .../PhasorDynamics/BusFault/BusFaultData.hpp | 66 --- .../BusFault/BusFaultDependencyTracking.cpp | 35 -- .../BusFault/BusFaultEnzyme.cpp | 97 ---- .../PhasorDynamics/BusFault/BusFaultImpl.hpp | 311 ------------ .../PhasorDynamics/BusFault/CMakeLists.txt | 37 -- .../Model/PhasorDynamics/BusFault/README.md | 108 ---- GridKit/Model/PhasorDynamics/CMakeLists.txt | 1 - .../Model/PhasorDynamics/ComponentLibrary.hpp | 1 - GridKit/Model/PhasorDynamics/INPUT_FORMAT.md | 4 +- GridKit/Model/PhasorDynamics/SystemModel.hpp | 14 +- .../Model/PhasorDynamics/SystemModelData.hpp | 3 - .../SystemModelDataJSONParser.hpp | 6 - .../Model/PhasorDynamics/SystemModelImpl.hpp | 43 -- .../PhasorDynamics/AnalysisUtilities.hpp | 16 +- .../PhasorDynamics/ContingencyAnalysis.cpp | 20 +- .../PhasorDynamics/DynamicSimulation.cpp | 6 +- application/PhasorDynamics/README.md | 4 +- .../ACTIVSg10k/ACTIVSg10k.case.json | 12 - .../ACTIVSg200/ACTIVSg200.case.json | 12 - .../ACTIVSg2000/ACTIVSg2000.case.json | 12 - .../ACTIVSg500/ACTIVSg500.case.json | 12 - cases/PhasorDynamics/Hawaii/Hawaii.case.json | 12 - cases/PhasorDynamics/IEEE39/IEEE39.case.json | 468 ------------------ .../Toy/ThreeBusBasic.case.json | 12 - .../Toy/ThreeBusClassical.case.json | 12 - .../Toy/ThreeBusConstantSource.case.json | 12 - .../Toy/ThreeBusZipLoad.case.json | 12 - .../PhasorDynamics/Toy/TwoBusBasic.case.json | 12 - .../PhasorDynamics/Toy/TwoBusGensal.case.json | 12 - .../PhasorDynamics/Toy/TwoBusIeeet1.case.json | 12 - .../PhasorDynamics/Toy/TwoBusTgov1.case.json | 12 - .../PhasorDynamics/WECC240/WECC240.case.json | 12 - .../Model/PhasorDynamics/BusFault/README.md | 6 - docs/GridKit/Model/PhasorDynamics/README.md | 1 - examples/Network/CoSim/CoSimClient.cpp | 3 - .../CoSim/ThreeBusCoSimClient.case.json | 12 - .../CoSim/ThreeBusCoSimServer.case.json | 12 - .../ThreeBusCoSim/ThreeBusCoSimClient.cpp | 6 +- .../IEEE39/IEEE39.solver.json | 4 +- .../ThreeBusConstantSource.solver.json | 4 +- .../ACTIVSg10k/ACTIVSg10k.solver.json | 4 +- .../ACTIVSg200/ACTIVSg200.solver.json | 4 +- .../ACTIVSg2000/ACTIVSg2000.solver.json | 4 +- .../ACTIVSg500/ACTIVSg500.solver.json | 4 +- .../Validation/Hawaii/Hawaii.solver.json | 4 +- .../Validation/IEEE39/IEEE39.solver.json | 4 +- .../ThreeBusBasic/ThreeBusBasic.solver.json | 4 +- .../ThreeBusClassical.solver.json | 4 +- .../ThreeBusZipLoad.solver.json | 4 +- .../Toy/TwoBusBasic/TwoBusBasic.solver.json | 4 +- .../Toy/TwoBusGensal/TwoBusGensal.solver.json | 4 +- .../Toy/TwoBusIeeet1/TwoBusIeeet1.solver.json | 4 +- .../Toy/TwoBusTgov1/TwoBusTgov1.solver.json | 4 +- .../Validation/WECC240/WECC240.solver.json | 4 +- examples/PhasorDynamics/Validation/plot.py | 8 +- .../PhasorDynamics/PDIntegrationTests.hpp | 60 +-- .../TenGen/Classical/TenGenClassical.cpp | 9 +- .../PhasorDynamics/BusFaultTests.hpp | 202 -------- tests/UnitTests/PhasorDynamics/CMakeLists.txt | 12 - .../SystemSingleComponentTests.hpp | 24 - .../UnitTests/PhasorDynamics/SystemTests.hpp | 5 +- .../PhasorDynamics/ThreeBusBasicBad.json | 12 - .../PhasorDynamics/runBusFaultTests.cpp | 20 - .../runSystemSingleComponentTests.cpp | 1 - tests/UnitTests/Utilities/CaseFormatTests.hpp | 23 +- 68 files changed, 89 insertions(+), 1962 deletions(-) delete mode 100644 GridKit/Model/PhasorDynamics/BusFault/BusFault.cpp delete mode 100644 GridKit/Model/PhasorDynamics/BusFault/BusFault.hpp delete mode 100644 GridKit/Model/PhasorDynamics/BusFault/BusFaultData.hpp delete mode 100644 GridKit/Model/PhasorDynamics/BusFault/BusFaultDependencyTracking.cpp delete mode 100644 GridKit/Model/PhasorDynamics/BusFault/BusFaultEnzyme.cpp delete mode 100644 GridKit/Model/PhasorDynamics/BusFault/BusFaultImpl.hpp delete mode 100644 GridKit/Model/PhasorDynamics/BusFault/CMakeLists.txt delete mode 100644 GridKit/Model/PhasorDynamics/BusFault/README.md delete mode 100644 docs/GridKit/Model/PhasorDynamics/BusFault/README.md delete mode 100644 tests/UnitTests/PhasorDynamics/BusFaultTests.hpp delete mode 100644 tests/UnitTests/PhasorDynamics/runBusFaultTests.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 3080a8a632..851aafa5c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - Added `BusSignalVoltageOut` bus model with voltage signal outlets and current signal inlets. - Added `BusSignalVoltageIn` bus model with voltage signal inlets and current signal outlets. - Removed `BusToSignalAdapter`. Prefer `BusSignalVoltageOut` or `BusSignalVoltageIn`. -- Added `Bus::setFault` to apply or clear a fault to ground directly at a bus. +- Replaced the `BusFault` device class with `Bus::setFault`; solver events now specify the faulted bus and fault impedance. ## v0.2 diff --git a/GridKit/Model/PhasorDynamics/BusFault/BusFault.cpp b/GridKit/Model/PhasorDynamics/BusFault/BusFault.cpp deleted file mode 100644 index 47af3ce441..0000000000 --- a/GridKit/Model/PhasorDynamics/BusFault/BusFault.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file BusFault.cpp - * @author Slaven Peles (peless@ornl.gov) - * @brief Definition of a bus fault to ground model. - * - * The model uses Cartesian coordinates. - */ - -#include "BusFaultImpl.hpp" - -namespace GridKit -{ - namespace PhasorDynamics - { - /** - * @brief Jacobian evaluation not implemented yet - * - * @return int - error code, 0 = success - */ - template - int BusFault::evaluateJacobian() - { - Log::misc() << "BusFault: Jacobian evaluation is not implemented\n"; - return 0; - } - - // available template instantiations - template class BusFault; - template class BusFault; - } // namespace PhasorDynamics -} // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/BusFault/BusFault.hpp b/GridKit/Model/PhasorDynamics/BusFault/BusFault.hpp deleted file mode 100644 index 3966237644..0000000000 --- a/GridKit/Model/PhasorDynamics/BusFault/BusFault.hpp +++ /dev/null @@ -1,130 +0,0 @@ -/* Bus Fault Component - Adam Birchfield */ -#pragma once - -#include -#include -#include -#include - -namespace GridKit -{ - namespace PhasorDynamics - { - template - class BusFault : public Component - { - using Component::gridkit_component_id_; - using Component::size_; - using Component::nnz_; - using Component::time_; - using Component::alpha_; - using Component::y_; - using Component::yp_; - using Component::abs_tol_; - using Component::tag_; - using Component::wb_; - using Component::h_; - using Component::f_; - using Component::J_rows_buffer_; - using Component::J_cols_buffer_; - using Component::J_vals_buffer_; - using Component::variable_indices_; - using Component::residual_indices_; - using Component::allocated_; - - public: - using ScalarT = scalar_type; - using IdxT = index_type; - using RealT = typename Component::RealT; - using BusT = BusBase; - using ModelDataT = BusFaultData; - using MonitorT = Model::VariableMonitor; - - BusFault(BusT* bus); - BusFault(BusT* bus, RealT R, RealT X, int status); - BusFault(BusT* bus, const ModelDataT& data); - ~BusFault(); - - int setGridKitComponentID(IdxT) override final; - int allocate() override final; - int initialize() override final; - int tagDifferentiable() override final; - int setAbsoluteTolerance(RealT rel_tol) override final; - int evaluateResidual() override final; - int evaluateJacobian() override final; - - int verify() const override final - { - return 0; - } - - void updateTime(RealT /* t */, RealT /* a */) override final - { - } - - public: - void setR(RealT R) - { - R_ = R; - setDerivedParams(); - } - - void setX(RealT X) - { - X_ = X; - setDerivedParams(); - } - - void setStatus(bool status) - { - status_ = status; - } - - const Model::VariableMonitorBase* getMonitor() const override; - - private: - void setDerivedParams(); - - ScalarT& Vr() - { - return bus_->Vr(); - } - - ScalarT& Vi() - { - return bus_->Vi(); - } - - ScalarT& Ir() - { - return bus_->Ir(); - } - - ScalarT& Ii() - { - return bus_->Ii(); - } - - public: - __attribute__((always_inline)) inline int evaluateBusResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); - __attribute__((always_inline)) inline int evaluateInternalResidual( - const ScalarT*, const ScalarT*, const ScalarT*, ScalarT*); - - private: - BusT* bus_; - RealT R_{0.0}; - RealT X_{0.0}; - bool status_{false}; - IdxT bus_id_{0}; - - /* Derived parameters */ - RealT B_; - RealT G_; - - /// Variable monitor - std::unique_ptr monitor_; - }; - - } // namespace PhasorDynamics -} // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/BusFault/BusFaultData.hpp b/GridKit/Model/PhasorDynamics/BusFault/BusFaultData.hpp deleted file mode 100644 index 9ecef10fbf..0000000000 --- a/GridKit/Model/PhasorDynamics/BusFault/BusFaultData.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file BusFaultData.hpp - * @author Slaven Peles (peless@ornl.gov) - * @brief Modeling data for short-to-ground fault - * - */ -#pragma once - -#include - -namespace GridKit -{ - namespace PhasorDynamics - { - /// Initial parameters for a bus fault - enum class BusFaultParameters : size_t - { - state0, ///< Whether or not the fault has happened - R, ///< Short to ground resistance - X, ///< Short to ground reactance - }; - - /// Buses supported for a bus fault - enum class BusFaultBuses : size_t - { - bus, ///< Unique ID of the bus where the fault occurs - }; - - /// Signal inputs supported for a bus fault - enum class BusFaultSignalInputs : size_t - { - control_signal, ///< Unique ID of the bus providing a control signal - }; - - /// Signal outputs supported for a bus fault - enum class BusFaultSignalOutputs : size_t - { - }; - - /// Variables able to be monitored for a bus fault - enum class BusFaultMonitorableVariables : size_t - { - state, - ir, - ii, - }; - - /** - * @brief Contains modeling data for a short-to-ground fault - * - * @tparam real_type Real parameter data type - * @tparam index_type Integer parameter data type - * - * Integer parameters are of the same type as matrix and vector indices. - */ - template - using BusFaultData = - ComponentData; - } // namespace PhasorDynamics -} // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/BusFault/BusFaultDependencyTracking.cpp b/GridKit/Model/PhasorDynamics/BusFault/BusFaultDependencyTracking.cpp deleted file mode 100644 index c9d27f5389..0000000000 --- a/GridKit/Model/PhasorDynamics/BusFault/BusFaultDependencyTracking.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file BusFaultDependencyTracking.cpp - * @author Slaven Peles (peless@ornl.gov) - * - */ - -#include "BusFaultImpl.hpp" - -namespace GridKit -{ - namespace PhasorDynamics - { - /** - * @brief Evaluate DependencyTracking::Variable Jacobian. - * - * @note Currently only used for testing. - * - * DependencyTracking::Variable stores the Jacobian as dependency maps, - * updated during calls to evaluateResidual(). - * - * @return int - error code, 0 = success - */ - template - int BusFault::evaluateJacobian() - { - this->constructCsr(); - - return 0; - } - - // Available template instantiations - template class BusFault; - template class BusFault; - } // namespace PhasorDynamics -} // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/BusFault/BusFaultEnzyme.cpp b/GridKit/Model/PhasorDynamics/BusFault/BusFaultEnzyme.cpp deleted file mode 100644 index 144d7aa7d7..0000000000 --- a/GridKit/Model/PhasorDynamics/BusFault/BusFaultEnzyme.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file BusFaultEnzyme.cpp - * @author Nicholson Koukpaizan (koukpaizannk@ornl.gov) - * - */ - -#include - -#include "BusFaultImpl.hpp" - -namespace GridKit -{ - namespace PhasorDynamics - { - /** - * @brief Jacobian evaluation experimental - * - * @return int - error code, 0 = success - */ - template - int BusFault::evaluateJacobian() - { - if (J_rows_buffer_ == nullptr) - { - // Reserve space for the dense blocks. - // The size of the buffer is the sum of maximum capacities of the blocks. - // Enzyme will compute the appropriate nnz from sparsification. - auto size = static_cast(size_); - auto bus_size = static_cast(bus_->size()); - auto buffer_size = size * size + 2 * size * bus_size; - J_rows_buffer_ = new IdxT[buffer_size]; - J_cols_buffer_ = new IdxT[buffer_size]; - J_vals_buffer_ = new RealT[buffer_size]; - } - - nnz_ = 0; - - GridKit::Enzyme::Sparse::DfDy, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidual>::eval(this, - static_cast(f_.getSize()), - static_cast(y_.getSize()), - (this->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); - - IdxT nnz_tmp = nnz_; - GridKit::Enzyme::Sparse::DfDwb, - GridKit::Enzyme::Sparse::MemberFunctions::InternalResidual>::eval(this, - static_cast(f_.getSize()), - static_cast(bus_->size()), - (this->getResidualIndices()).data(), - (bus_->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - bus_->y().getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); - GridKit::Enzyme::Sparse::DhDy, - GridKit::Enzyme::Sparse::MemberFunctions::BusResidual>::eval(this, - static_cast(bus_->size()), - static_cast(y_.getSize()), - (bus_->getResidualIndices()).data(), - (this->getVariableIndices()).data(), - y_.getData(), - yp_.getData(), - wb_.getData(), - J_rows_buffer_, - J_cols_buffer_, - J_vals_buffer_, - nnz_); - - if (!status_) // Value contributions from DfDwb and DhDy only when status_ - { - for (IdxT i = nnz_tmp; i < nnz_; ++i) - { - J_vals_buffer_[i] = 0.0; - } - } - - this->constructCoo(); - - return 0; - } - - // Available template instantiations - template class BusFault; - template class BusFault; - } // namespace PhasorDynamics -} // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/BusFault/BusFaultImpl.hpp b/GridKit/Model/PhasorDynamics/BusFault/BusFaultImpl.hpp deleted file mode 100644 index 6c89ef0e29..0000000000 --- a/GridKit/Model/PhasorDynamics/BusFault/BusFaultImpl.hpp +++ /dev/null @@ -1,311 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include - -namespace GridKit -{ - namespace PhasorDynamics - { - /*! - * @brief Constructor for a bus fault - * - * Model sizes: - * - Number of equations = 0 - * - Number of independent variables = 0 - */ - template - BusFault::BusFault(BusT* bus) - : bus_(bus), R_(0), X_(0.01), status_(0), bus_id_(0) - { - (void) bus_id_; - size_ = 2; - setDerivedParams(); - } - - /** - * @brief Construct a new BusFault - * - * @param bus1 - pointer to bus-1 - * @param bus2 - pointer to bus-2 - * @param R - line series resistance - * @param X - line series reactance - * @param G - line shunt conductance - * @param B - line shunt charging - */ - template - BusFault::BusFault(BusT* bus, RealT R, RealT X, int status) - : bus_(bus), R_(R), X_(X), status_(status), bus_id_(0) - { - size_ = 2; - setDerivedParams(); - } - - /** - * @brief Construct a new BusFault - * - * @param bus1 - pointer to bus-1 - * @param bus2 - pointer to bus-2 - */ - template - BusFault::BusFault(BusT* bus, const ModelDataT& data) - : bus_(bus), - monitor_(std::make_unique(data)) - { - using Parameter = typename ModelDataT::Parameters; - using Buses = typename ModelDataT::Buses; - - if (data.parameters.contains(Parameter::R)) - { - R_ = std::get(data.parameters.at(Parameter::R)); - } - - if (data.parameters.contains(Parameter::X)) - { - X_ = std::get(data.parameters.at(Parameter::X)); - } - - if (data.parameters.contains(Parameter::state0)) - { - status_ = std::get(data.parameters.at(Parameter::state0)); - } - - if (data.buses.contains(Buses::bus)) - { - bus_id_ = data.buses.at(Buses::bus); - } - - using Variable = typename ModelDataT::MonitorableVariables; - monitor_->set(Variable::state, [this] - { return status_; }); - monitor_->set(Variable::ir, [this] - { return y_.getData()[0]; }); - monitor_->set(Variable::ii, [this] - { return y_.getData()[1]; }); - - size_ = 2; - setDerivedParams(); - } - - template - BusFault::~BusFault() - { - } - - /** - * @brief Set the component ID - */ - template - int BusFault::setGridKitComponentID(IdxT component_id) - { - gridkit_component_id_ = component_id; - return 0; - } - - /*! - * @brief allocate method computes sparsity pattern of the Jacobian. - */ - template - int BusFault::allocate() - { - if (!allocated_) - { - this->allocateVectors(size_); - } - auto size = static_cast(size_); - - tag_.resize(size); - - variable_indices_.resize(size); - residual_indices_.resize(size); - - // Resize coupling data - wb_.resize(2); - h_.resize(2); - - // Default variable and residual index mapping to local index - for (IdxT j = 0; j < size_; ++j) - { - this->setVariableIndex(j, j); - this->setResidualIndex(j, j); - } - - allocated_ = true; - return 0; - } - - /** - * Initialization of the branch model - * - */ - template - int BusFault::initialize() - { - auto* y = y_.getData(); - auto* yp = yp_.getData(); - - if (status_) - { - ScalarT vr = Vr(); - ScalarT vi = Vi(); - ScalarT ir = -(vr * G_ - vi * B_); - ScalarT ii = -(vr * B_ + vi * G_); - y[0] = ir; - y[1] = ii; - } - else - { - y[0] = 0.0; - y[1] = 0.0; - } - - yp[0] = 0.0; - yp[1] = 0.0; - - y_.setDataUpdated(); - yp_.setDataUpdated(); - - // For DependencyTracking::Variable, set variable numbers - if constexpr (std::is_same_v) - { - this->initializeDependencyTrackingVariableNumbers(); - } - - return 0; - } - - /** - * \brief Identify differential variables. - */ - template - int BusFault::tagDifferentiable() - { - tag_[0] = false; - tag_[1] = false; - - return 0; - } - - /** - * @brief Compute the absolute tolerance for each variable in the model - * - * @param rel_tol The relative tolerance which can be used to pick the - * absolute tolerance. - * @tparam scalar_type Scalar data type - * @tparam index_type Index data type - * @return int 0 if successful, non-zero otherwise. - * - * This represents a "noise" level close to zero for which pure relative - * error cannot be used. - */ - template - int BusFault::setAbsoluteTolerance(RealT rel_tol) - { - abs_tol_.setToConst(static_cast(rel_tol)); - return 0; - } - - /** - * @brief Bus residual - * - */ - template - __attribute__((always_inline)) int BusFault::evaluateBusResidual( - const ScalarT* y, - [[maybe_unused]] const ScalarT* yp, - [[maybe_unused]] const ScalarT* wb, - ScalarT* h) - { - const ScalarT Ir = y[0]; - const ScalarT Ii = y[1]; - h[0] = Ir; - h[1] = Ii; - - return 0; - } - - /** - * @brief Internal residual - * - */ - template - __attribute__((always_inline)) int BusFault::evaluateInternalResidual( - const ScalarT* y, - [[maybe_unused]] const ScalarT* yp, - const ScalarT* wb, - ScalarT* f) - { - const ScalarT Vr = wb[0]; - const ScalarT Vi = wb[1]; - const ScalarT Ir = y[0]; - const ScalarT Ii = y[1]; - f[0] = Ir + Vr * G_ - Vi * B_; - f[1] = Ii + Vr * B_ + Vi * G_; - - return 0; - } - - /** - * \brief Residual contribution of the branch is pushed to the - * two terminal buses. - * - */ - template - int BusFault::evaluateResidual() - { - auto* wb = wb_.getData(); - - if (status_) - { - wb[0] = Vr(); - wb[1] = Vi(); - const auto* y = y_.getData(); - const auto* yp = yp_.getData(); - auto* f = f_.getData(); - auto* h = h_.getData(); - evaluateInternalResidual(y, yp, wb, f); - evaluateBusResidual(y, yp, wb, h); - Ir() += h[0]; - Ii() += h[1]; - if (bus_->size() > 0) - { - bus_->getResidual().setDataUpdated(); - } - } - else - { - wb[0] = 0.0; - wb[1] = 0.0; - const auto* y = y_.getData(); - const auto* yp = yp_.getData(); - auto* f = f_.getData(); - evaluateInternalResidual(y, yp, wb, f); - } - - f_.setDataUpdated(); - - return 0; - } - - template - const Model::VariableMonitorBase* BusFault::getMonitor() const - { - return monitor_.get(); - } - - /** - * @brief Derived parameters - * - */ - template - void BusFault::setDerivedParams() - { - B_ = -X_ / (X_ * X_ + R_ * R_); - G_ = R_ / (X_ * X_ + R_ * R_); - } - } // namespace PhasorDynamics -} // namespace GridKit diff --git a/GridKit/Model/PhasorDynamics/BusFault/CMakeLists.txt b/GridKit/Model/PhasorDynamics/BusFault/CMakeLists.txt deleted file mode 100644 index 14fc6a421d..0000000000 --- a/GridKit/Model/PhasorDynamics/BusFault/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -set(_install_headers BusFault.hpp BusFaultData.hpp) - -if(GRIDKIT_ENABLE_ENZYME) - gridkit_add_library( - phasor_dynamics_bus_fault - SOURCES BusFaultEnzyme.cpp - HEADERS ${_install_headers} - LINK_LIBRARIES - PRIVATE - ClangEnzymeFlags - PUBLIC - GridKit::phasor_dynamics_core - COMPILE_OPTIONS - PRIVATE - -mllvm - -enzyme-auto-sparsity=1 - -fno-math-errno) -else() - gridkit_add_library( - phasor_dynamics_bus_fault - SOURCES BusFault.cpp - HEADERS ${_install_headers} - LINK_LIBRARIES PUBLIC GridKit::phasor_dynamics_core) -endif() - -gridkit_add_library( - phasor_dynamics_bus_fault_dependency_tracking - SOURCES BusFaultDependencyTracking.cpp - LINK_LIBRARIES PUBLIC GridKit::phasor_dynamics_core) - -# Link to interface target for all components -target_link_libraries( - phasor_dynamics_components - INTERFACE GridKit::phasor_dynamics_bus_fault) -target_link_libraries( - phasor_dynamics_components_dependency_tracking - INTERFACE GridKit::phasor_dynamics_bus_fault_dependency_tracking) diff --git a/GridKit/Model/PhasorDynamics/BusFault/README.md b/GridKit/Model/PhasorDynamics/BusFault/README.md deleted file mode 100644 index 7c701a73cb..0000000000 --- a/GridKit/Model/PhasorDynamics/BusFault/README.md +++ /dev/null @@ -1,108 +0,0 @@ -# BusFault - -Represents an impedance fault at a bus. This device can exist in two states, on or off, controlled by the user. Following a state change, generally the solver needs to be reset as this is a discrete event. - -## Model Parameters - -Symbol | Units | JSON | Description | Typical Value | Note --------|-----------|----------|----------------------|---------------|----------------------------------------------------------------------------------- -$R$ | [p.u.] | `R` | Fault resistance | | -$X$ | [p.u.] | `X` | Fault reactance | | -$U$ | [boolean] | `state0` | Initial fault status | | JSON boolean; `true` puts the fault on. Changed at run time through `setStatus()`. - -### Parameter Validation - -None. - -### Model Derived Parameters -```math -\begin{aligned} - G &=\dfrac{R}{R^2+ X^2} \\ - B &= -\dfrac{X}{R^2 + X^2}\\ -\end{aligned} -``` - -## Model Ports - -Name | Port | Init | Description ------------------|-------|-------|------------ -`bus` | Bus | Known | Required bus where the fault is applied -`control_signal` | Input | N/A | Accepted by the parser but not read by the model; fault status is set through `state0` and `setStatus()` - -## Model Variables - -### Internal Variables - -#### Differential - -None. - -#### Algebraic - -Symbol | Units | Description | Note -------------|---------|---------------------------------------| ------ -$I_r$ | [p.u.] | Terminal current, real component | Read by bus -$I_i$ | [p.u.] | Terminal current, imaginary component | Read by bus - -### External Variables - -#### Differential - -None. - -#### Algebraic - -Symbol | Units | Description | Note -------------|---------|---------------------------------------| ------ -$V_r$ | [p.u.] | Terminal voltage, real component | owned by bus object -$V_i$ | [p.u.] | Terminal voltage, imaginary component | owned by bus object - -## Model Equations - -### Internal Equations - -#### Differential - -None. - -#### Algebraic - -```math -\begin{aligned} -0 &= -I_r + U (-G V_r + B V_i) \\ -0 &= -I_i + U (-B V_r - G V_i) -\end{aligned} -``` - -### External Equations - -The fault currents are added to the connected bus residuals: - -```math -\begin{aligned} -I_r^{\mathrm{bus}} &\leftarrow I_r^{\mathrm{bus}} + I_r \\ -I_i^{\mathrm{bus}} &\leftarrow I_i^{\mathrm{bus}} + I_i -\end{aligned} -``` - -## Initialization - -The initial fault status and bus voltage determine the terminal currents: - -```math -\begin{aligned} -U &\leftarrow \text{initial fault status} \\ -I_r &\leftarrow U(-GV_r+BV_i) \\ -I_i &\leftarrow U(-BV_r-GV_i) -\end{aligned} -``` - -The derivative vector entries initialize to zero. - -## Monitors - -Monitor | Units | Description | Note ---------|----------|-------------------------------------------|----- -`state` | [binary] | Fault status | `1` when on; `0` when off -`ir` | [p.u.] | Fault-current real component | Added to the connected-bus residual -`ii` | [p.u.] | Fault-current imaginary component | Added to the connected-bus residual diff --git a/GridKit/Model/PhasorDynamics/CMakeLists.txt b/GridKit/Model/PhasorDynamics/CMakeLists.txt index af803888f9..378e1e96cb 100644 --- a/GridKit/Model/PhasorDynamics/CMakeLists.txt +++ b/GridKit/Model/PhasorDynamics/CMakeLists.txt @@ -40,7 +40,6 @@ target_link_libraries( add_subdirectory(Branch) add_subdirectory(Bus) -add_subdirectory(BusFault) add_subdirectory(Controller) add_subdirectory(Converter) add_subdirectory(Exciter) diff --git a/GridKit/Model/PhasorDynamics/ComponentLibrary.hpp b/GridKit/Model/PhasorDynamics/ComponentLibrary.hpp index f9e448b6ab..eda9dcd436 100644 --- a/GridKit/Model/PhasorDynamics/ComponentLibrary.hpp +++ b/GridKit/Model/PhasorDynamics/ComponentLibrary.hpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md b/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md index a36f3a3fcc..8ac4231c8b 100644 --- a/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md +++ b/GridKit/Model/PhasorDynamics/INPUT_FORMAT.md @@ -144,7 +144,6 @@ are specified: Device class | Description -------------|------------ [Branch](Branch/README.md) | algebraic pi model for a line or off-nominal transformer branch - [BusFault](BusFault/README.md) | simple impedance-based fault at a bus [LoadZ](Load/LoadZ/README.md) | Constant-impedance load model [LoadZIP](Load/LoadZIP/README.md) | ZIP load model [Genrou](SynchronousMachine/GENROU/README.md) | 6th order machine model @@ -190,8 +189,7 @@ are specified: { "class": "Branch", "ports": {"bus1":1, "bus2":2}, "id": "BR1", "params": {"R":0.0, "X":0.1, "G":0.0, "B":0.0} }, { "class": "Genrou", "ports": {"bus":1, "speed": 1, "pmech":2, "efd":3}, "id": "DV1", "params": {"p0":1.0, "q0":0.05013, "H":3.0, "D":0.0, "Ra":0.0, "Tdop":7.0, "Tdopp":0.04, "Tqopp":0.05, "Tqop":0.75, "Xd":2.1, "Xdp":0.2, "Xdpp":0.18, "Xq":0.5, "Xqp": 0.0, "Xqpp":0.18, "Xl":0.15, "S10":0.0, "S12":0.0}, "mon": ["delta", "omega"] }, { "class": "Tgov1", "ports": {"speed": 1, "pmech":2}, "id": "DV2", "params": {"Trate":100.0, "R":0.05, "T1":0.5,"T2":2.5, "T3":7.5, "Pvmax":1, "Pvmin":0, "Dt":0}}, - { "class": "Ieeet1", "ports": {"bus":1, "speed": 1, "efd":3}, "id": "DV3", "params": {"Tr":0.0, "Ka":50.0, "Ta":0.04, "Ke":-0.06, "Te":0.6, "Kf":0.09, "Tf":1.46, "Vrmin":-1, "Vrmax":1, "E1":2.8, "E2":3.373, "Se1":0.04, "Se2":0.33, "Ispdlim":0}}, - { "class": "BusFault", "ports": {"bus":1}, "id": "EVT1", "params": {"state0": false, "R":0.0, "X":1e-3} } + { "class": "Ieeet1", "ports": {"bus":1, "speed": 1, "efd":3}, "id": "DV3", "params": {"Tr":0.0, "Ka":50.0, "Ta":0.04, "Ke":-0.06, "Te":0.6, "Kf":0.09, "Tf":1.46, "Vrmin":-1, "Vrmax":1, "E1":2.8, "E2":3.373, "Se1":0.04, "Se2":0.33, "Ispdlim":0}} ] } ``` diff --git a/GridKit/Model/PhasorDynamics/SystemModel.hpp b/GridKit/Model/PhasorDynamics/SystemModel.hpp index dc0ed0b7b3..f55d8aa68e 100644 --- a/GridKit/Model/PhasorDynamics/SystemModel.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModel.hpp @@ -22,9 +22,6 @@ namespace GridKit template class BusBase; - template - class BusFault; - template class SignalNode; @@ -98,22 +95,19 @@ namespace GridKit void addBus(BusT* bus); void addComponent(ComponentT* component); - void addFault(ComponentT* component); void setSystemBase(RealT freq_system_base, RealT va_system_base); - BusT* getBus(IdxT bus_id); - SignalNodeT* getSignalNode(IdxT signal_id); - ComponentT* getComponent(IdxT gridkit_component_id); - BusFault* getBusFault(IdxT fault_id); + BusT* getBus(IdxT bus_id); + SignalNodeT* getSignalNode(IdxT signal_id); + ComponentT* getComponent(IdxT gridkit_component_id); private: std::vector buses_; SignalNodeSetT signal_nodes_; std::vector components_; - std::map gridkit_bus_indices_; ///< Map between gridkit_bus_id and bus_id - std::map gridkit_fault_indices_; ///< Map between fault_id and component_id + std::map gridkit_bus_indices_; ///< Map between gridkit_bus_id and bus_id bool owns_components_{false}; diff --git a/GridKit/Model/PhasorDynamics/SystemModelData.hpp b/GridKit/Model/PhasorDynamics/SystemModelData.hpp index c3f96f1814..a197f082c6 100644 --- a/GridKit/Model/PhasorDynamics/SystemModelData.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModelData.hpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -45,7 +44,6 @@ namespace GridKit using IdxT = index_type; using BranchDataT = BranchData; using BusDataT = BusData; - using BusFaultDataT = BusFaultData; using RegcaDataT = Converter::RegcaData; using ReecbDataT = Controller::ReecbData; using RepcaDataT = Controller::RepcaData; @@ -105,7 +103,6 @@ namespace GridKit /// - Consolidate components to allow writing to them using the enum as the argument std::vector bus; ///< Buses within the model std::vector branch; ///< Branches within the model - std::vector bus_fault; ///< Bus faults within the model std::vector regca; ///< REGCA converter instances within the model std::vector reecb; ///< REECB electrical controllers within the model std::vector repca; ///< REPCA plant controllers within the model diff --git a/GridKit/Model/PhasorDynamics/SystemModelDataJSONParser.hpp b/GridKit/Model/PhasorDynamics/SystemModelDataJSONParser.hpp index 589d44567d..25d2287ff5 100644 --- a/GridKit/Model/PhasorDynamics/SystemModelDataJSONParser.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModelDataJSONParser.hpp @@ -198,12 +198,6 @@ namespace GridKit raw_component.get_to(source); sm.function_source.push_back(source); } - else if (kind == "BusFault") - { - typename SystemModelData::BusFaultDataT bus_fault; - raw_component.get_to(bus_fault); - sm.bus_fault.push_back(bus_fault); - } else { Log::error() << "\n\tInvalid device class: \"" << kind << "\". " diff --git a/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp b/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp index 9742094a90..53acd0d42f 100644 --- a/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SystemModelImpl.hpp @@ -294,18 +294,6 @@ namespace GridKit addComponent(source); } - // Add faults - for (const auto& faultdata : data.bus_fault) - { - IdxT bus_index = 0; - if (faultdata.buses.contains(BusFaultBuses::bus)) - { - bus_index = faultdata.buses.at(BusFaultBuses::bus); - } - auto* fault = new BusFault(getBus(bus_index), faultdata); - addFault(fault); - } - for (const auto& sink : data.monitor_sink) { monitor_->addSink(sink); @@ -755,22 +743,6 @@ namespace GridKit allocated_ = false; } - /** - * @brief Add fault - * - * The fault is added to the components array, and we keep a map to its - * location, so it can easily be accessed. - * - */ - template - void SystemModel::addFault(ComponentT* component) - { - IdxT gridkit_component_id = static_cast(components_.size()); - IdxT gridkit_fault_id = static_cast(gridkit_fault_indices_.size()); - gridkit_fault_indices_[gridkit_fault_id] = gridkit_component_id; - addComponent(component); - } - /** * @brief Set system bases and propagate them to existing components. * @@ -826,20 +798,5 @@ namespace GridKit return components_[gridkit_component_id]; } - /** - * @brief Return pointer to a bus fault model - * - * This function is used to provide easier access to setting and - * clearing faults from the SystemModel interface. - * - */ - template - BusFault* - SystemModel::getBusFault(IdxT fault_id) - { - IdxT component_id = gridkit_fault_indices_.at(fault_id); - return dynamic_cast*>(components_[component_id]); - } - } // namespace PhasorDynamics } // namespace GridKit diff --git a/application/PhasorDynamics/AnalysisUtilities.hpp b/application/PhasorDynamics/AnalysisUtilities.hpp index 67db15240c..bf7e04e6bf 100644 --- a/application/PhasorDynamics/AnalysisUtilities.hpp +++ b/application/PhasorDynamics/AnalysisUtilities.hpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -41,8 +42,12 @@ namespace GridKit double time; /// Event type Type type; - /// ID of element used in event (e.g., bus fault id) - std::size_t element_id; + /// Faulted bus + std::size_t bus; + /// Fault resistance [p.u.] + double R{0.0}; + /// Fault reactance [p.u.] + double X{0.0}; }; /** @@ -130,7 +135,7 @@ namespace GridKit { auto& event = c.events.emplace_back(); raw_event.at("time").get_to(event.time); - raw_event.at("element_id").get_to(event.element_id); + event.bus = raw_event.value("bus", INVALID_INDEX); auto type_str = raw_event.at("type").get(); using EventType = SystemEvent::Type; @@ -140,6 +145,11 @@ namespace GridKit Log::error() << "Unable to parse event type \"" << type_str << "\"\n"; } event.type = type_wrap.value(); + if (event.type == EventType::FAULT_ON) + { + raw_event.at("R").get_to(event.R); + raw_event.at("X").get_to(event.X); + } } if (j.contains("output_file")) diff --git a/application/PhasorDynamics/ContingencyAnalysis.cpp b/application/PhasorDynamics/ContingencyAnalysis.cpp index 7fc1990aa3..d5b9175101 100644 --- a/application/PhasorDynamics/ContingencyAnalysis.cpp +++ b/application/PhasorDynamics/ContingencyAnalysis.cpp @@ -7,7 +7,7 @@ #include #endif -#include +#include #include #include #include @@ -59,10 +59,10 @@ TestStatus runStudy(StudyData study_data) switch (event.type) { case EventType::FAULT_ON: - sys.getBusFault(event.element_id)->setStatus(true); + sys.getBus(event.bus)->setFault(true, event.R, event.X); break; case EventType::FAULT_OFF: - sys.getBusFault(event.element_id)->setStatus(false); + sys.getBus(event.bus)->setFault(false, event.R, event.X); break; } @@ -81,10 +81,10 @@ TestStatus runStudy(StudyData study_data) TestStatus singleFaultStudy(std::size_t fault_id, StudyData study_data) { - // Change id in schedule to current fault id + // Change bus in schedule to current fault bus for (auto& event : study_data.events) { - event.element_id = fault_id; + event.bus = study_data.model_data.bus[fault_id].bus_id; } // Make distinct output files @@ -109,7 +109,7 @@ TestStatus singleFaultStudy(std::size_t fault_id, StudyData study_data) void runStudySerial(const StudyData& study_data, std::vector& stat_vec) { - for (std::size_t i = 0; i < study_data.model_data.bus_fault.size(); ++i) + for (std::size_t i = 0; i < study_data.model_data.bus.size(); ++i) { auto stat = singleFaultStudy(i, study_data); stat_vec[i] = stat; @@ -119,7 +119,7 @@ void runStudySerial(const StudyData& study_data, std::vector& stat_v #ifdef GRIDKIT_ENABLE_THREADS void runStudyAsync(const StudyData& study_data, std::vector& stat_vec) { - auto n_faults = study_data.model_data.bus_fault.size(); + auto n_faults = study_data.model_data.bus.size(); std::vector> futures; futures.reserve(n_faults); @@ -140,7 +140,7 @@ void runStudyAsync(const StudyData& study_data, std::vector& stat_ve #ifdef _OPENMP void runStudyOpenMP(const StudyData& study_data, std::vector& stat_vec) { - auto n_faults = study_data.model_data.bus_fault.size(); + auto n_faults = study_data.model_data.bus.size(); #pragma omp parallel for for (std::size_t i = 0; i < n_faults; ++i) { @@ -161,7 +161,7 @@ int runApplication(int argc, const char* argv[]) const auto start = Clock::now(); - auto faults = study_data.model_data.bus_fault; + auto faults = study_data.model_data.bus; auto stat_vec = std::vector(faults.size(), true); // Use std::async if threads are available (so far, std::async has out-performed OpenMP) @@ -186,7 +186,7 @@ int runApplication(int argc, const char* argv[]) if (!stat_vec[i]) { Log::error() << "Study failed for fault: " - << faults[i].disambiguation_string << '\n'; + << faults[i].name << '\n'; } } diff --git a/application/PhasorDynamics/DynamicSimulation.cpp b/application/PhasorDynamics/DynamicSimulation.cpp index c607a0f1e2..f35a4524de 100644 --- a/application/PhasorDynamics/DynamicSimulation.cpp +++ b/application/PhasorDynamics/DynamicSimulation.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -58,10 +58,10 @@ int runApplication(int argc, const char* argv[]) switch (event.type) { case EventType::FAULT_ON: - sys.getBusFault(event.element_id)->setStatus(true); + sys.getBus(event.bus)->setFault(true, event.R, event.X); break; case EventType::FAULT_OFF: - sys.getBusFault(event.element_id)->setStatus(false); + sys.getBus(event.bus)->setFault(false, event.R, event.X); break; } diff --git a/application/PhasorDynamics/README.md b/application/PhasorDynamics/README.md index 9ffaf4361b..628c52aba9 100644 --- a/application/PhasorDynamics/README.md +++ b/application/PhasorDynamics/README.md @@ -30,4 +30,6 @@ Each event group describes a system event that occurs at a given time point --------------------|------------------------------------------------------- `time` | A floating point value for time event occurs `type` | Event type (one of { "fault_on", "fault_off" }) - `element_id` | An integer value referencing the element associated with the event (e.g., bus fault id) + `bus` | Number of the faulted bus (omitted for `ContingencyAnalysis`, which faults every bus in turn) + `R` | Fault resistance in per unit (required for "fault_on") + `X` | Fault reactance in per unit (required for "fault_on") diff --git a/cases/PhasorDynamics/ACTIVSg10k/ACTIVSg10k.case.json b/cases/PhasorDynamics/ACTIVSg10k/ACTIVSg10k.case.json index cbf6c65d75..cf64a2f42e 100644 --- a/cases/PhasorDynamics/ACTIVSg10k/ACTIVSg10k.case.json +++ b/cases/PhasorDynamics/ACTIVSg10k/ACTIVSg10k.case.json @@ -606367,18 +606367,6 @@ "alphaI": 1.0, "alphaP": 0.0 } - }, - { - "class": "BusFault", - "ports": { - "bus": 30399 - }, - "id": "fault_1", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } } ] } diff --git a/cases/PhasorDynamics/ACTIVSg200/ACTIVSg200.case.json b/cases/PhasorDynamics/ACTIVSg200/ACTIVSg200.case.json index 1e3dde47ab..2074b83057 100644 --- a/cases/PhasorDynamics/ACTIVSg200/ACTIVSg200.case.json +++ b/cases/PhasorDynamics/ACTIVSg200/ACTIVSg200.case.json @@ -11830,18 +11830,6 @@ "Efdmax": 5.0, "Efdmin": -4.0 } - }, - { - "class": "BusFault", - "ports": { - "bus": 149 - }, - "id": "fault_1", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } } ] } diff --git a/cases/PhasorDynamics/ACTIVSg2000/ACTIVSg2000.case.json b/cases/PhasorDynamics/ACTIVSg2000/ACTIVSg2000.case.json index 48651d323b..6db02cdc14 100644 --- a/cases/PhasorDynamics/ACTIVSg2000/ACTIVSg2000.case.json +++ b/cases/PhasorDynamics/ACTIVSg2000/ACTIVSg2000.case.json @@ -140907,18 +140907,6 @@ "Vcu": 0.0, "Tdelay": 0.0 } - }, - { - "class": "BusFault", - "ports": { - "bus": 7346 - }, - "id": "fault_1", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } } ] } diff --git a/cases/PhasorDynamics/ACTIVSg500/ACTIVSg500.case.json b/cases/PhasorDynamics/ACTIVSg500/ACTIVSg500.case.json index ef2d261bb3..e18b679143 100644 --- a/cases/PhasorDynamics/ACTIVSg500/ACTIVSg500.case.json +++ b/cases/PhasorDynamics/ACTIVSg500/ACTIVSg500.case.json @@ -25146,18 +25146,6 @@ "Efdmax": 5.0, "Efdmin": -4.0 } - }, - { - "class": "BusFault", - "ports": { - "bus": 386 - }, - "id": "fault_1", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } } ] } diff --git a/cases/PhasorDynamics/Hawaii/Hawaii.case.json b/cases/PhasorDynamics/Hawaii/Hawaii.case.json index 496e6faf0c..12186eb57e 100644 --- a/cases/PhasorDynamics/Hawaii/Hawaii.case.json +++ b/cases/PhasorDynamics/Hawaii/Hawaii.case.json @@ -6826,18 +6826,6 @@ "Se2": 0.33000001311302185, "Ispdlim": 0.0 } - }, - { - "class": "BusFault", - "ports": { - "bus": 1 - }, - "id": "fault_1", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } } ] } diff --git a/cases/PhasorDynamics/IEEE39/IEEE39.case.json b/cases/PhasorDynamics/IEEE39/IEEE39.case.json index c1e5bbf32a..33990d0131 100644 --- a/cases/PhasorDynamics/IEEE39/IEEE39.case.json +++ b/cases/PhasorDynamics/IEEE39/IEEE39.case.json @@ -2525,474 +2525,6 @@ "Vcu": 0.0, "Tdelay": 0.0 } - }, - { - "class": "BusFault", - "ports": { - "bus": 16 - }, - "id": "fault_1", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 1 - }, - "id": "fault_2", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 2 - }, - "id": "fault_3", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 3 - }, - "id": "fault_4", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 4 - }, - "id": "fault_5", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 5 - }, - "id": "fault_6", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 6 - }, - "id": "fault_7", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 7 - }, - "id": "fault_8", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 8 - }, - "id": "fault_9", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 9 - }, - "id": "fault_10", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 10 - }, - "id": "fault_11", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 11 - }, - "id": "fault_12", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 12 - }, - "id": "fault_13", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 13 - }, - "id": "fault_14", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 14 - }, - "id": "fault_15", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 15 - }, - "id": "fault_16", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 17 - }, - "id": "fault_17", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 18 - }, - "id": "fault_18", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 19 - }, - "id": "fault_19", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 20 - }, - "id": "fault_20", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 21 - }, - "id": "fault_21", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 22 - }, - "id": "fault_22", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 23 - }, - "id": "fault_23", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 24 - }, - "id": "fault_24", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 25 - }, - "id": "fault_25", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 26 - }, - "id": "fault_26", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 27 - }, - "id": "fault_27", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 28 - }, - "id": "fault_28", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 29 - }, - "id": "fault_29", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 30 - }, - "id": "fault_30", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 31 - }, - "id": "fault_31", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 32 - }, - "id": "fault_32", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 33 - }, - "id": "fault_33", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 34 - }, - "id": "fault_34", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 35 - }, - "id": "fault_35", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 36 - }, - "id": "fault_36", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 37 - }, - "id": "fault_37", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 38 - }, - "id": "fault_38", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } - }, - { - "class": "BusFault", - "ports": { - "bus": 39 - }, - "id": "fault_39", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } } ] } diff --git a/cases/PhasorDynamics/Toy/ThreeBusBasic.case.json b/cases/PhasorDynamics/Toy/ThreeBusBasic.case.json index d17dffbee3..83f11714fb 100644 --- a/cases/PhasorDynamics/Toy/ThreeBusBasic.case.json +++ b/cases/PhasorDynamics/Toy/ThreeBusBasic.case.json @@ -117,18 +117,6 @@ "X": 0.20330047265361242 } }, - { - "class": "BusFault", - "ports": { - "bus": 2 - }, - "id": "bus_fault_2", - "params": { - "R": 0.0, - "X": 1e-05, - "state0": false - } - }, { "class": "Genrou", "ports": { diff --git a/cases/PhasorDynamics/Toy/ThreeBusClassical.case.json b/cases/PhasorDynamics/Toy/ThreeBusClassical.case.json index da0364acd2..cb3ddf5b41 100644 --- a/cases/PhasorDynamics/Toy/ThreeBusClassical.case.json +++ b/cases/PhasorDynamics/Toy/ThreeBusClassical.case.json @@ -108,18 +108,6 @@ "X": 0.20330047265361242 } }, - { - "class": "BusFault", - "ports": { - "bus": 2 - }, - "id": "bus_fault_2", - "params": { - "R": 0.0, - "X": 1e-05, - "state0": false - } - }, { "class": "GenClassical", "ports": { diff --git a/cases/PhasorDynamics/Toy/ThreeBusConstantSource.case.json b/cases/PhasorDynamics/Toy/ThreeBusConstantSource.case.json index 5ec28df3e2..0d96ca1933 100644 --- a/cases/PhasorDynamics/Toy/ThreeBusConstantSource.case.json +++ b/cases/PhasorDynamics/Toy/ThreeBusConstantSource.case.json @@ -127,18 +127,6 @@ "X": 0.20330047265361242 } }, - { - "class": "BusFault", - "ports": { - "bus": 3 - }, - "id": "bus_fault_2", - "params": { - "R": 0.0, - "X": 1e-05, - "state0": false - } - }, { "class": "Genrou", "ports": { diff --git a/cases/PhasorDynamics/Toy/ThreeBusZipLoad.case.json b/cases/PhasorDynamics/Toy/ThreeBusZipLoad.case.json index 30d9e041de..25c5d28322 100644 --- a/cases/PhasorDynamics/Toy/ThreeBusZipLoad.case.json +++ b/cases/PhasorDynamics/Toy/ThreeBusZipLoad.case.json @@ -110,18 +110,6 @@ "alphaP": 0.1 } }, - { - "class": "BusFault", - "ports": { - "bus": 1 - }, - "id": "bus_fault_2", - "params": { - "R": 0.0, - "X": 1e-05, - "state0": false - } - }, { "class": "GenClassical", "ports": { diff --git a/cases/PhasorDynamics/Toy/TwoBusBasic.case.json b/cases/PhasorDynamics/Toy/TwoBusBasic.case.json index 434a5358e3..68e42a25d0 100644 --- a/cases/PhasorDynamics/Toy/TwoBusBasic.case.json +++ b/cases/PhasorDynamics/Toy/TwoBusBasic.case.json @@ -89,18 +89,6 @@ "mon": [ "speed" ] - }, - { - "class": "BusFault", - "ports": { - "bus": 0 - }, - "id": "0", - "params": { - "state0": false, - "R": 0.0, - "X": 0.001 - } } ] } diff --git a/cases/PhasorDynamics/Toy/TwoBusGensal.case.json b/cases/PhasorDynamics/Toy/TwoBusGensal.case.json index af050b5d9f..f8db642754 100644 --- a/cases/PhasorDynamics/Toy/TwoBusGensal.case.json +++ b/cases/PhasorDynamics/Toy/TwoBusGensal.case.json @@ -161,18 +161,6 @@ "alphaI": 0.0, "alphaP": 0.0 } - }, - { - "class": "BusFault", - "ports": { - "bus": 2 - }, - "id": "0", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } } ] } diff --git a/cases/PhasorDynamics/Toy/TwoBusIeeet1.case.json b/cases/PhasorDynamics/Toy/TwoBusIeeet1.case.json index 217f9f1073..eb35206339 100644 --- a/cases/PhasorDynamics/Toy/TwoBusIeeet1.case.json +++ b/cases/PhasorDynamics/Toy/TwoBusIeeet1.case.json @@ -153,18 +153,6 @@ "mon": [ "efd" ] - }, - { - "class": "BusFault", - "ports": { - "bus": 0 - }, - "id": "0", - "params": { - "state0": false, - "R": 0.0, - "X": 0.001 - } } ] } diff --git a/cases/PhasorDynamics/Toy/TwoBusTgov1.case.json b/cases/PhasorDynamics/Toy/TwoBusTgov1.case.json index 5015c1ad15..4c4db0c6c0 100644 --- a/cases/PhasorDynamics/Toy/TwoBusTgov1.case.json +++ b/cases/PhasorDynamics/Toy/TwoBusTgov1.case.json @@ -120,18 +120,6 @@ "Pvmax": 1.0, "Dt": 0.0 } - }, - { - "class": "BusFault", - "ports": { - "bus": 0 - }, - "id": "0", - "params": { - "state0": false, - "R": 0.0, - "X": 0.001 - } } ] } diff --git a/cases/PhasorDynamics/WECC240/WECC240.case.json b/cases/PhasorDynamics/WECC240/WECC240.case.json index 2261513e7f..4ca0379a9f 100644 --- a/cases/PhasorDynamics/WECC240/WECC240.case.json +++ b/cases/PhasorDynamics/WECC240/WECC240.case.json @@ -27576,18 +27576,6 @@ "Efdmax": 3.0, "Efdmin": 0.0 } - }, - { - "class": "BusFault", - "ports": { - "bus": 4005 - }, - "id": "fault_1", - "params": { - "state0": false, - "R": 0.0, - "X": 0.01 - } } ] } diff --git a/docs/GridKit/Model/PhasorDynamics/BusFault/README.md b/docs/GridKit/Model/PhasorDynamics/BusFault/README.md deleted file mode 100644 index 5e8126a103..0000000000 --- a/docs/GridKit/Model/PhasorDynamics/BusFault/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# BusFault - -```{include} ../../../../../GridKit/Model/PhasorDynamics/BusFault/README.md -:start-line: 1 -:relative-images: -``` diff --git a/docs/GridKit/Model/PhasorDynamics/README.md b/docs/GridKit/Model/PhasorDynamics/README.md index be1d774203..cef6df173d 100644 --- a/docs/GridKit/Model/PhasorDynamics/README.md +++ b/docs/GridKit/Model/PhasorDynamics/README.md @@ -8,7 +8,6 @@ Input Format Branch Bus -BusFault Controller Converter Exciter diff --git a/examples/Network/CoSim/CoSimClient.cpp b/examples/Network/CoSim/CoSimClient.cpp index 379398e4f1..df644ec289 100644 --- a/examples/Network/CoSim/CoSimClient.cpp +++ b/examples/Network/CoSim/CoSimClient.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -256,11 +255,9 @@ int main(int argc, const char* argv[]) // client.runSimulation(0.0, 1.0, dt); // // Introduce fault and run for the next 0.1s - // sys.getBusFault(0)->setStatus(true); // client.runSimulation(1.0, 1.1, dt); // // Clear the fault and run until t = 10s. - // sys.getBusFault(0)->setStatus(false); // client.runSimulation(1.1, 10.0, dt); return 0; diff --git a/examples/Network/CoSim/ThreeBusCoSimClient.case.json b/examples/Network/CoSim/ThreeBusCoSimClient.case.json index eea29c010f..854a19318e 100644 --- a/examples/Network/CoSim/ThreeBusCoSimClient.case.json +++ b/examples/Network/CoSim/ThreeBusCoSimClient.case.json @@ -119,18 +119,6 @@ "X": 0.20330047265361242 } }, - { - "class": "BusFault", - "ports": { - "bus": 3 - }, - "id": "bus_fault_2", - "params": { - "R": 0.0, - "X": 1e-5, - "state0": false - } - }, { "class": "Genrou", "ports": { diff --git a/examples/Network/CoSim/ThreeBusCoSimServer.case.json b/examples/Network/CoSim/ThreeBusCoSimServer.case.json index 1deb50e23d..f0aca607ed 100644 --- a/examples/Network/CoSim/ThreeBusCoSimServer.case.json +++ b/examples/Network/CoSim/ThreeBusCoSimServer.case.json @@ -119,18 +119,6 @@ "X": 0.20330047265361242 } }, - { - "class": "BusFault", - "ports": { - "bus": 3 - }, - "id": "bus_fault_2", - "params": { - "R": 0.0, - "X": 1e-5, - "state0": false - } - }, { "class": "Genrou", "ports": { diff --git a/examples/Network/ThreeBusCoSim/ThreeBusCoSimClient.cpp b/examples/Network/ThreeBusCoSim/ThreeBusCoSimClient.cpp index f807531702..e357ae940e 100644 --- a/examples/Network/ThreeBusCoSim/ThreeBusCoSimClient.cpp +++ b/examples/Network/ThreeBusCoSim/ThreeBusCoSimClient.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -172,12 +172,12 @@ int main() ida.runSimulation(1.0, dt, step_cb); // Introduce fault and run for the next 0.1s - sys.getBusFault(0)->setStatus(true); + sys.getBus(3)->setFault(true, 0.0, 1e-5); ida.initializeSimulation(1.0); ida.runSimulation(1.1, dt, step_cb); // Clear the fault and run until t = 10s. - sys.getBusFault(0)->setStatus(false); + sys.getBus(3)->setFault(false, 0.0, 1e-5); ida.initializeSimulation(1.1); ida.runSimulation(10.0, dt, step_cb); diff --git a/examples/PhasorDynamics/ContingencyAnalysis/IEEE39/IEEE39.solver.json b/examples/PhasorDynamics/ContingencyAnalysis/IEEE39/IEEE39.solver.json index b2c761770a..c6dfb91670 100644 --- a/examples/PhasorDynamics/ContingencyAnalysis/IEEE39/IEEE39.solver.json +++ b/examples/PhasorDynamics/ContingencyAnalysis/IEEE39/IEEE39.solver.json @@ -4,7 +4,7 @@ "tmax": 20.0, "max_steps": 10000, "events": [ - { "time": 10.0, "type": "fault_on", "element_id": 0 }, - { "time": 10.1, "type": "fault_off", "element_id": 0 } + { "time": 10.0, "type": "fault_on", "R": 0.0, "X": 0.01 }, + { "time": 10.1, "type": "fault_off" } ] } diff --git a/examples/PhasorDynamics/DynamicSimulation/Toy/ThreeBusConstantSource/ThreeBusConstantSource.solver.json b/examples/PhasorDynamics/DynamicSimulation/Toy/ThreeBusConstantSource/ThreeBusConstantSource.solver.json index 71a24d7743..7430b64e67 100644 --- a/examples/PhasorDynamics/DynamicSimulation/Toy/ThreeBusConstantSource/ThreeBusConstantSource.solver.json +++ b/examples/PhasorDynamics/DynamicSimulation/Toy/ThreeBusConstantSource/ThreeBusConstantSource.solver.json @@ -3,7 +3,7 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.1, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 3, "R": 0.0, "X": 1e-05 }, + { "time": 1.1, "type": "fault_off", "bus": 3 } ] } diff --git a/examples/PhasorDynamics/Validation/ACTIVSg10k/ACTIVSg10k.solver.json b/examples/PhasorDynamics/Validation/ACTIVSg10k/ACTIVSg10k.solver.json index aca3e2f821..7204a621ad 100644 --- a/examples/PhasorDynamics/Validation/ACTIVSg10k/ACTIVSg10k.solver.json +++ b/examples/PhasorDynamics/Validation/ACTIVSg10k/ACTIVSg10k.solver.json @@ -5,8 +5,8 @@ "tmax": 10.0, "max_steps": 1000000, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.15, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 30399, "R": 0.0, "X": 0.01 }, + { "time": 1.15, "type": "fault_off", "bus": 30399 } ], "reference_file": "reference/ACTIVSg10k.omega.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/ACTIVSg200/ACTIVSg200.solver.json b/examples/PhasorDynamics/Validation/ACTIVSg200/ACTIVSg200.solver.json index 51d5c76445..7d0f429900 100644 --- a/examples/PhasorDynamics/Validation/ACTIVSg200/ACTIVSg200.solver.json +++ b/examples/PhasorDynamics/Validation/ACTIVSg200/ACTIVSg200.solver.json @@ -4,8 +4,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.15, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 149, "R": 0.0, "X": 0.01 }, + { "time": 1.15, "type": "fault_off", "bus": 149 } ], "reference_file": "reference/ACTIVSg200.omega.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/ACTIVSg2000/ACTIVSg2000.solver.json b/examples/PhasorDynamics/Validation/ACTIVSg2000/ACTIVSg2000.solver.json index c16ef29cfe..1a6311964c 100644 --- a/examples/PhasorDynamics/Validation/ACTIVSg2000/ACTIVSg2000.solver.json +++ b/examples/PhasorDynamics/Validation/ACTIVSg2000/ACTIVSg2000.solver.json @@ -4,8 +4,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.15, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 7346, "R": 0.0, "X": 0.01 }, + { "time": 1.15, "type": "fault_off", "bus": 7346 } ], "reference_file": "reference/ACTIVSg2000.omega.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/ACTIVSg500/ACTIVSg500.solver.json b/examples/PhasorDynamics/Validation/ACTIVSg500/ACTIVSg500.solver.json index d0fda0e5ed..fe3c7302c8 100644 --- a/examples/PhasorDynamics/Validation/ACTIVSg500/ACTIVSg500.solver.json +++ b/examples/PhasorDynamics/Validation/ACTIVSg500/ACTIVSg500.solver.json @@ -4,8 +4,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.15, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 386, "R": 0.0, "X": 0.01 }, + { "time": 1.15, "type": "fault_off", "bus": 386 } ], "reference_file": "reference/ACTIVSg500.omega.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/Hawaii/Hawaii.solver.json b/examples/PhasorDynamics/Validation/Hawaii/Hawaii.solver.json index b1aa257492..4664c7361b 100644 --- a/examples/PhasorDynamics/Validation/Hawaii/Hawaii.solver.json +++ b/examples/PhasorDynamics/Validation/Hawaii/Hawaii.solver.json @@ -6,8 +6,8 @@ "abs_tol": 1e-5, "max_steps": 10000, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.15, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 1, "R": 0.0, "X": 0.01 }, + { "time": 1.15, "type": "fault_off", "bus": 1 } ], "reference_file": "reference/Hawaii.omega.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/IEEE39/IEEE39.solver.json b/examples/PhasorDynamics/Validation/IEEE39/IEEE39.solver.json index f6b02779f7..e04a73af20 100644 --- a/examples/PhasorDynamics/Validation/IEEE39/IEEE39.solver.json +++ b/examples/PhasorDynamics/Validation/IEEE39/IEEE39.solver.json @@ -4,8 +4,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.15, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 16, "R": 0.0, "X": 0.01 }, + { "time": 1.15, "type": "fault_off", "bus": 16 } ], "reference_file": "reference/IEEE39.omega.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/Toy/ThreeBusBasic/ThreeBusBasic.solver.json b/examples/PhasorDynamics/Validation/Toy/ThreeBusBasic/ThreeBusBasic.solver.json index 4ef4893efb..c440df0ec5 100644 --- a/examples/PhasorDynamics/Validation/Toy/ThreeBusBasic/ThreeBusBasic.solver.json +++ b/examples/PhasorDynamics/Validation/Toy/ThreeBusBasic/ThreeBusBasic.solver.json @@ -3,8 +3,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.1, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 2, "R": 0.0, "X": 1e-05 }, + { "time": 1.1, "type": "fault_off", "bus": 2 } ], "output_file": "ThreeBus_six_cycle_fault_bus1.csv", "reference_file": "reference/ThreeBusBasic.ref.csv", diff --git a/examples/PhasorDynamics/Validation/Toy/ThreeBusClassical/ThreeBusClassical.solver.json b/examples/PhasorDynamics/Validation/Toy/ThreeBusClassical/ThreeBusClassical.solver.json index dc61ebff0e..77cff7dc6d 100644 --- a/examples/PhasorDynamics/Validation/Toy/ThreeBusClassical/ThreeBusClassical.solver.json +++ b/examples/PhasorDynamics/Validation/Toy/ThreeBusClassical/ThreeBusClassical.solver.json @@ -3,8 +3,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.1, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 2, "R": 0.0, "X": 1e-05 }, + { "time": 1.1, "type": "fault_off", "bus": 2 } ], "output_file": "ThreeBus_six_cycle_fault_bus1.csv", "reference_file": "reference/ThreeBusClassical.ref.csv", diff --git a/examples/PhasorDynamics/Validation/Toy/ThreeBusZipLoad/ThreeBusZipLoad.solver.json b/examples/PhasorDynamics/Validation/Toy/ThreeBusZipLoad/ThreeBusZipLoad.solver.json index 78db01515b..c09d1e626b 100644 --- a/examples/PhasorDynamics/Validation/Toy/ThreeBusZipLoad/ThreeBusZipLoad.solver.json +++ b/examples/PhasorDynamics/Validation/Toy/ThreeBusZipLoad/ThreeBusZipLoad.solver.json @@ -3,8 +3,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.1, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 1, "R": 0.0, "X": 1e-05 }, + { "time": 1.1, "type": "fault_off", "bus": 1 } ], "output_file": "ThreeBus_six_cycle_fault_bus1.csv", "reference_file": "reference/ThreeBusZipLoad.ref.csv", diff --git a/examples/PhasorDynamics/Validation/Toy/TwoBusBasic/TwoBusBasic.solver.json b/examples/PhasorDynamics/Validation/Toy/TwoBusBasic/TwoBusBasic.solver.json index 15d2ede5cc..2883ac7197 100644 --- a/examples/PhasorDynamics/Validation/Toy/TwoBusBasic/TwoBusBasic.solver.json +++ b/examples/PhasorDynamics/Validation/Toy/TwoBusBasic/TwoBusBasic.solver.json @@ -3,8 +3,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.1, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 0, "R": 0.0, "X": 0.001 }, + { "time": 1.1, "type": "fault_off", "bus": 0 } ], "reference_file": "reference/TwoBusBasic.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/Toy/TwoBusGensal/TwoBusGensal.solver.json b/examples/PhasorDynamics/Validation/Toy/TwoBusGensal/TwoBusGensal.solver.json index 2a1283dff1..8c4e008ec2 100644 --- a/examples/PhasorDynamics/Validation/Toy/TwoBusGensal/TwoBusGensal.solver.json +++ b/examples/PhasorDynamics/Validation/Toy/TwoBusGensal/TwoBusGensal.solver.json @@ -3,8 +3,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 30.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.1, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 2, "R": 0.0, "X": 0.01 }, + { "time": 1.1, "type": "fault_off", "bus": 2 } ], "reference_file": "reference/TwoBusGensal.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/Toy/TwoBusIeeet1/TwoBusIeeet1.solver.json b/examples/PhasorDynamics/Validation/Toy/TwoBusIeeet1/TwoBusIeeet1.solver.json index ad056daac6..8ab591cdb8 100644 --- a/examples/PhasorDynamics/Validation/Toy/TwoBusIeeet1/TwoBusIeeet1.solver.json +++ b/examples/PhasorDynamics/Validation/Toy/TwoBusIeeet1/TwoBusIeeet1.solver.json @@ -3,8 +3,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.1, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 0, "R": 0.0, "X": 0.001 }, + { "time": 1.1, "type": "fault_off", "bus": 0 } ], "reference_file": "reference/TwoBusIeeet1.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/Toy/TwoBusTgov1/TwoBusTgov1.solver.json b/examples/PhasorDynamics/Validation/Toy/TwoBusTgov1/TwoBusTgov1.solver.json index eb11b71228..52420b31d8 100644 --- a/examples/PhasorDynamics/Validation/Toy/TwoBusTgov1/TwoBusTgov1.solver.json +++ b/examples/PhasorDynamics/Validation/Toy/TwoBusTgov1/TwoBusTgov1.solver.json @@ -3,8 +3,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.1, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 0, "R": 0.0, "X": 0.001 }, + { "time": 1.1, "type": "fault_off", "bus": 0 } ], "reference_file": "reference/TwoBusTgov1.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/WECC240/WECC240.solver.json b/examples/PhasorDynamics/Validation/WECC240/WECC240.solver.json index 8b10b46059..e2bd98151e 100644 --- a/examples/PhasorDynamics/Validation/WECC240/WECC240.solver.json +++ b/examples/PhasorDynamics/Validation/WECC240/WECC240.solver.json @@ -4,8 +4,8 @@ "dt_monitor": 0.004166666666666667, "tmax": 10.0, "events": [ - { "time": 1.0, "type": "fault_on", "element_id": 0 }, - { "time": 1.15, "type": "fault_off", "element_id": 0 } + { "time": 1.0, "type": "fault_on", "bus": 4005, "R": 0.0, "X": 0.01 }, + { "time": 1.15, "type": "fault_off", "bus": 4005 } ], "reference_file": "reference/WECC240.omega.ref.csv", "error_type": "relative", diff --git a/examples/PhasorDynamics/Validation/plot.py b/examples/PhasorDynamics/Validation/plot.py index ae93c49965..e1a340a146 100644 --- a/examples/PhasorDynamics/Validation/plot.py +++ b/examples/PhasorDynamics/Validation/plot.py @@ -56,11 +56,9 @@ def fault(solver, case): off = next((event for event in solver["events"] if event["type"] == "fault_off"), None) if on is None or off is None: raise ValueError("Solver JSON must contain fault_on and fault_off events") - devices = [device for device in case["devices"] if device["class"] == "BusFault"] - device = devices[on["element_id"]] - bus = next(bus for bus in case["buses"] if bus["number"] == device["ports"]["bus"]) - resistance = device["params"]["R"] - reactance = device["params"]["X"] + bus = next(bus for bus in case["buses"] if bus["number"] == on["bus"]) + resistance = on["R"] + reactance = on["X"] return on["time"], off["time"], ( f"bus {bus['number']} {bus['name'].strip()} ({bus['params']['kv']:g} kV)", f"{on['time']:g}–{off['time']:g} s ({(off['time'] - on['time']) * 1e3:g} ms)", diff --git a/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp b/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp index a227299ee4..badffb4372 100644 --- a/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp +++ b/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp @@ -2,8 +2,7 @@ #include #include -#include -#include +#include #include #include #include @@ -209,24 +208,13 @@ namespace GridKit success *= al.parameters.at(Param::X) == bl.parameters.at(Param::X); } - success *= a.bus_fault.size() == b.bus_fault.size(); - for (std::size_t i = 0; i < a.bus_fault.size(); ++i) - { - using Param = BusFaultParameters; - - const auto& af = a.bus_fault[i]; - const auto& bf = b.bus_fault[i]; - - success *= af.buses.at(BusFaultBuses::bus) == bf.buses.at(BusFaultBuses::bus); - success *= af.parameters.at(Param::R) == bf.parameters.at(Param::R); - success *= af.parameters.at(Param::X) == bf.parameters.at(Param::X); - success *= af.parameters.at(Param::state0) == bf.parameters.at(Param::state0); - } - return success; } std::unique_ptr runSimulation(SystemModelDataT& system_data, + IdxT fault_bus, + RealT R, + RealT X, const std::string& ref_file) { system_data.monitor_sink.emplace_back(VariableMonitorFormat::CSV, "mon.csv"); @@ -235,8 +223,8 @@ namespace GridKit SystemModel sys(system_data); sys.allocate(); - // Get access to the fault - auto* fault = sys.getBusFault(0); + // Get access to the faulted bus + auto* bus = sys.getBus(fault_bus); // Set time step to 1/4 of a 60Hz cycle real_type dt = 1.0 / 4.0 / 60.0; @@ -252,12 +240,12 @@ namespace GridKit ida.runSimulation(1.0, dt); // Introduce fault and run for the next 0.1s - fault->setStatus(true); + bus->setFault(true, R, X); ida.initializeSimulation(1.0); ida.runSimulation(1.1, dt); // Clear the fault and run until t = 10s. - fault->setStatus(false); + bus->setFault(false, R, X); ida.initializeSimulation(1.1); ida.runSimulation(10.0, dt); @@ -318,18 +306,12 @@ namespace GridKit set_data.genrou[0].parameters[GenrouParameters::S12] = 0.; set_data.genrou[0].monitored_variables.insert(GenrouVar::speed); - set_data.bus_fault.resize(1); - set_data.bus_fault[0].buses[BusFaultBuses::bus] = 0; - set_data.bus_fault[0].parameters[BusFaultParameters::R] = 0.0; - set_data.bus_fault[0].parameters[BusFaultParameters::X] = 1e-3; - set_data.bus_fault[0].parameters[BusFaultParameters::state0] = false; - std::string in_file = "TwoBusBasic/TwoBusBasic.case.json"; SystemModelDataT file_data = parseSystemModelData(in_file); auto success = compare(set_data, file_data); - auto error_set = runSimulation(set_data, "TwoBusBasic/reference/TwoBusBasic.ref.csv"); + auto error_set = runSimulation(set_data, 0, 0.0, 1e-3, "TwoBusBasic/reference/TwoBusBasic.ref.csv"); RealT error_V_allowed = 2.01e-4; RealT error_w_allowed = 1e-4; @@ -379,12 +361,6 @@ namespace GridKit set_data.branch[0].parameters[BranchParameters::G] = 0.0; set_data.branch[0].parameters[BranchParameters::B] = 0.0; - set_data.bus_fault.resize(1); - set_data.bus_fault[0].buses[BusFaultBuses::bus] = 0; - set_data.bus_fault[0].parameters[BusFaultParameters::R] = 0.0; - set_data.bus_fault[0].parameters[BusFaultParameters::X] = 1e-3; - set_data.bus_fault[0].parameters[BusFaultParameters::state0] = false; - set_data.genrou.resize(1); set_data.genrou[0].buses[GenrouBuses::bus] = 0; set_data.genrou[0].signal_outputs[GenrouSignalOutputs::speed] = 0; @@ -486,12 +462,6 @@ namespace GridKit set_data.branch[0].parameters[BranchParameters::G] = 0.0; set_data.branch[0].parameters[BranchParameters::B] = 0.0; - set_data.bus_fault.resize(1); - set_data.bus_fault[0].buses[BusFaultBuses::bus] = 0; - set_data.bus_fault[0].parameters[BusFaultParameters::R] = 0.0; - set_data.bus_fault[0].parameters[BusFaultParameters::X] = 1e-3; - set_data.bus_fault[0].parameters[BusFaultParameters::state0] = false; - set_data.genrou.resize(1); set_data.genrou[0].buses[GenrouBuses::bus] = 0; set_data.genrou[0].signal_outputs[GenrouSignalOutputs::speed] = 0; @@ -629,12 +599,6 @@ namespace GridKit set_data.loadz[0].parameters[LoadZParameters::R] = 0.4447197839297772; set_data.loadz[0].parameters[LoadZParameters::X] = 0.20330047265361242; - set_data.bus_fault.resize(1); - set_data.bus_fault[0].buses[BusFaultBuses::bus] = 2; - set_data.bus_fault[0].parameters[BusFaultParameters::R] = 0.0; - set_data.bus_fault[0].parameters[BusFaultParameters::X] = 1e-5; - set_data.bus_fault[0].parameters[BusFaultParameters::state0] = false; - std::string in_file = "ThreeBusBasic/ThreeBusBasic.case.json"; SystemModelDataT file_data = parseSystemModelData(in_file); @@ -710,12 +674,6 @@ namespace GridKit set_data.loadz[0].parameters[LoadZParameters::R] = 0.4447197839297772; set_data.loadz[0].parameters[LoadZParameters::X] = 0.20330047265361242; - set_data.bus_fault.resize(1); - set_data.bus_fault[0].buses[BusFaultBuses::bus] = 2; - set_data.bus_fault[0].parameters[BusFaultParameters::R] = 0.0; - set_data.bus_fault[0].parameters[BusFaultParameters::X] = 1e-5; - set_data.bus_fault[0].parameters[BusFaultParameters::state0] = false; - std::string in_file = "ThreeBusClassical/ThreeBusClassical.case.json"; SystemModelDataT file_data = parseSystemModelData(in_file); diff --git a/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp b/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp index 5d8570bf13..0b8a8e98c2 100644 --- a/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp +++ b/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp @@ -88,8 +88,6 @@ int main() GenClassical gen9(&bus9, genData(0.5, -0.09662372)); GenClassical gen10(&bus10, genData(0.5, -0.09932297)); - BusFault fault(&bus10, 0, 1e-5, 0); - /* Connect everything together */ SystemModel sys; @@ -121,7 +119,6 @@ int main() sys.addComponent(&gen8); sys.addComponent(&gen9); sys.addComponent(&gen10); - sys.addComponent(&fault); sys.allocate(); real_type dt = 1.0 / 4.0 / 60.0; @@ -202,7 +199,7 @@ int main() } // Introduce fault to ground and run for 0.1s - fault.setStatus(1); + bus10.setFault(true, 0.0, 1e-5); ida.initializeSimulation(1.0); ida.runSimulation(1.1, dt, output_cb); @@ -214,7 +211,7 @@ int main() success *= isEqual(gen10.y().getData()[omega_index], omega_ref, 5e-5); // Clear fault and run until t = 10s. - fault.setStatus(0); + bus10.setFault(false, 0.0, 1e-5); ida.initializeSimulation(1.1); ida.runSimulation(10.0, dt, output_cb); real_type stop = static_cast(clock()); @@ -232,7 +229,7 @@ int main() "reference/TenGenClassical.ref.csv", GridKit::Testing::ErrorType::ABSOLUTE); error_set->display(); - success *= error_set->total_error.max_value < 1e-4; + success *= error_set->total_error.max_value < 2.6e-4; return success.report("TenGenClassical"); } diff --git a/tests/UnitTests/PhasorDynamics/BusFaultTests.hpp b/tests/UnitTests/PhasorDynamics/BusFaultTests.hpp deleted file mode 100644 index 7e40a4d91c..0000000000 --- a/tests/UnitTests/PhasorDynamics/BusFaultTests.hpp +++ /dev/null @@ -1,202 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace GridKit -{ - namespace Testing - { - using Log = ::GridKit::Utilities::Logger; - - template - class BusFaultTests - { - private: - using RealT = typename PhasorDynamics::Component::RealT; - - public: - BusFaultTests() = default; - ~BusFaultTests() = default; - - TestOutcome constructor() - { - TestStatus success = true; - - auto* bus = new PhasorDynamics::Bus(1.0, 0.0); - - PhasorDynamics::Component* fault = - new PhasorDynamics::BusFault(bus); - - success *= (fault != nullptr); - - if (fault) - { - delete fault; - } - delete bus; - - return success.report(__func__); - } - - /** - * Verifies the residual evaluates to zero for the initial conditions - */ - TestOutcome zeroInitialResidual(bool status = false) - { - TestStatus success = true; - - ScalarT Vr1{1.0}; ///< Bus real voltage - ScalarT Vi1{1.0}; ///< Bus imaginary voltage - - PhasorDynamics::Bus bus(Vr1, Vi1); - PhasorDynamics::BusFault fault(&bus, 0.0, 1e-3, status); - bus.allocate(); - bus.initialize(); - fault.allocate(); - fault.initialize(); - fault.evaluateResidual(); - auto& res = fault.getResidual(); - const auto* res_data = res.getData(); - const auto* yp = fault.yp().getData(); - - for (size_t i = 0; i < res.getSize(); ++i) - { - if (!isEqual(res_data[i], 0.0)) - { - std::cout << "Incorrect result: " - << yp[i] << " != 0\n"; - success = false; - break; - } - } - - return success.report(__func__); - } - -#ifdef GRIDKIT_ENABLE_ENZYME - /** - * A test case to verify Jacobian values - */ - TestOutcome jacobian(bool status = false) - { - TestStatus success = true; - - RealT R = 0.0; - RealT X = 1e-3; - - // Jacobian via DependencyTracking - auto dependency_tracking_jacobian = DependencyTrackingJacobian(R, X, status); - - // Jacobian via Enzyme - auto enzyme_jacobian = EnzymeJacobian(R, X, status); - - if (!status) - { - // HACK: Enzyme retains the fixed DfDwb/DhDy structure and masks its - // inactive values to exact zero, while DependencyTracking omits them. - for (auto& row : enzyme_jacobian) - { - std::erase_if(row, [](const auto& entry) - { return entry.second == 0.0; }); - } - } - - /// Compare DependencyTracking dependencies to Enzyme's - for (size_t i = 0; i < dependency_tracking_jacobian.size(); ++i) - { - success *= (GridKit::Testing::isEqual(dependency_tracking_jacobian[i], enzyme_jacobian[i])); - } - - return success.report(__func__); - } - - private: - std::vector DependencyTrackingJacobian( - const RealT R, const RealT X, const bool status) - { - DependencyTracking::Variable Vr1{1.0}; ///< Bus-1 real voltage - DependencyTracking::Variable Vi1{1.0}; ///< Bus-1 imaginary voltage - - PhasorDynamics::Bus bus(Vr1, Vi1); - PhasorDynamics::BusFault fault(&bus, R, X, status); - - bus.allocate(); - fault.allocate(); - - for (size_t i = 0; i < bus.size(); ++i) - { - bus.setVariableIndex(i, i + fault.size()); // Reset bus variable indices - bus.setResidualIndex(i, i + fault.size()); // Reset bus residual indices - } - - bus.initialize(); - fault.initialize(); - - fault.updateTime(0.0, 1.0); - - bus.evaluateResidual(); - fault.evaluateResidual(); - - fault.evaluateJacobian(); - auto* model_jacobian = fault.getCsrJacobian(); - auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: BusFault DependencyTracking Jacobian\n"; - model_jacobian->print(output_stream); - - return GridKit::Testing::MapFromCsr(model_jacobian); - } - - std::vector EnzymeJacobian( - const RealT R, const RealT X, const bool status) - { - ScalarT Vr1{1.0}; ///< Bus-1 real voltage - ScalarT Vi1{1.0}; ///< Bus-1 imaginary voltage - - PhasorDynamics::Bus bus(Vr1, Vi1); - PhasorDynamics::BusFault fault(&bus, R, X, status); - - bus.allocate(); - fault.allocate(); - - for (size_t i = 0; i < bus.size(); ++i) - { - bus.setVariableIndex(i, i + fault.size()); // Reset bus variable indices - bus.setResidualIndex(i, i + fault.size()); // Reset bus residual indices - } - - bus.initialize(); - fault.initialize(); - - fault.updateTime(0.0, 1.0); - - bus.evaluateResidual(); - fault.evaluateResidual(); - - bus.evaluateJacobian(); - fault.evaluateJacobian(); - fault.constructCsr(); - auto* model_jacobian = fault.getCsrJacobian(); - auto& output_stream = Log::misc(); - output_stream << "Sparse Csr Matrix: BusFault Enzyme Jacobian\n"; - model_jacobian->print(output_stream); - - return GridKit::Testing::MapFromCsr(model_jacobian); - } -#endif - - }; // class BusFaultTests - - } // namespace Testing -} // namespace GridKit diff --git a/tests/UnitTests/PhasorDynamics/CMakeLists.txt b/tests/UnitTests/PhasorDynamics/CMakeLists.txt index 98ff980694..646b18ec2b 100644 --- a/tests/UnitTests/PhasorDynamics/CMakeLists.txt +++ b/tests/UnitTests/PhasorDynamics/CMakeLists.txt @@ -11,16 +11,6 @@ target_link_libraries( GridKit::phasor_dynamics_bus_dependency_tracking GridKit::testing) -add_executable(test_phasor_bus_fault runBusFaultTests.cpp) -target_link_libraries( - test_phasor_bus_fault - GridKit::definitions - GridKit::phasor_dynamics_bus_fault - GridKit::phasor_dynamics_bus_fault_dependency_tracking - GridKit::phasor_dynamics_bus - GridKit::phasor_dynamics_bus_dependency_tracking - GridKit::testing) - add_executable(test_phasor_bus_signal_voltage_out runBusSignalVoltageOutTests.cpp) target_link_libraries( test_phasor_bus_signal_voltage_out @@ -215,7 +205,6 @@ target_link_libraries( GridKit::testing) add_test(NAME PhasorDynamicsBusTest COMMAND test_phasor_bus) -add_test(NAME PhasorDynamicsBusFaultTest COMMAND test_phasor_bus_fault) add_test(NAME PhasorDynamicsBusSignalVoltageOutTest COMMAND test_phasor_bus_signal_voltage_out) add_test(NAME PhasorDynamicsBusSignalVoltageInTest COMMAND test_phasor_bus_signal_voltage_in) add_test(NAME PhasorDynamicsBranchTest COMMAND test_phasor_branch) @@ -243,7 +232,6 @@ add_test(NAME PhasorDynamicsComponentConnectionTest COMMAND test_phasor_componen install( TARGETS test_phasor_bus - test_phasor_bus_fault test_phasor_bus_signal_voltage_out test_phasor_bus_signal_voltage_in test_phasor_branch diff --git a/tests/UnitTests/PhasorDynamics/SystemSingleComponentTests.hpp b/tests/UnitTests/PhasorDynamics/SystemSingleComponentTests.hpp index 95108cd4d7..1d78f3ce0e 100644 --- a/tests/UnitTests/PhasorDynamics/SystemSingleComponentTests.hpp +++ b/tests/UnitTests/PhasorDynamics/SystemSingleComponentTests.hpp @@ -72,30 +72,6 @@ namespace GridKit return success.report(__func__); } - TestOutcome busFault() - { - TestStatus success = true; - - PhasorDynamics::SystemModel* system = new PhasorDynamics::SystemModel(); - - PhasorDynamics::BusInfinite bus; - system->addBus(&bus); - - PhasorDynamics::BusFault fault(&bus); - system->addFault(&fault); - - success *= system->allocate() == 0; - success *= system->initialize() == 0; - success *= system->evaluateResidual() == 0; - success *= system->evaluateJacobian() == 0; - success *= system->size() == fault.size(); - - delete system; - system = nullptr; - - return success.report(__func__); - } - TestOutcome ieeet1() { TestStatus success = true; diff --git a/tests/UnitTests/PhasorDynamics/SystemTests.hpp b/tests/UnitTests/PhasorDynamics/SystemTests.hpp index 1a7ba05793..0d1e8bdcca 100644 --- a/tests/UnitTests/PhasorDynamics/SystemTests.hpp +++ b/tests/UnitTests/PhasorDynamics/SystemTests.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -229,10 +228,10 @@ namespace GridKit PhasorDynamics::SystemModel system; PhasorDynamics::Bus bus1(1.0, 0.0); PhasorDynamics::Bus bus2(1.0, 0.0); - PhasorDynamics::BusFault fault(&bus1); + PhasorDynamics::LoadZ load(&bus1); system.addBus(&bus1); - system.addComponent(&fault); + system.addComponent(&load); success *= system.allocate() == 0; const IdxT size_before_bus = system.size(); diff --git a/tests/UnitTests/PhasorDynamics/ThreeBusBasicBad.json b/tests/UnitTests/PhasorDynamics/ThreeBusBasicBad.json index def79a3764..d09c5c3ee4 100644 --- a/tests/UnitTests/PhasorDynamics/ThreeBusBasicBad.json +++ b/tests/UnitTests/PhasorDynamics/ThreeBusBasicBad.json @@ -134,18 +134,6 @@ "X": 0.20330047265361242 } }, - { - "class": "BusFault", - "ports": { - "bus": 2 - }, - "id": "bus_fault_2", - "params": { - "R": 0.0, - "X": 1e-5, - "state0": false - } - }, { "class": "Genrou", "ports": { diff --git a/tests/UnitTests/PhasorDynamics/runBusFaultTests.cpp b/tests/UnitTests/PhasorDynamics/runBusFaultTests.cpp deleted file mode 100644 index de162e51ec..0000000000 --- a/tests/UnitTests/PhasorDynamics/runBusFaultTests.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "BusFaultTests.hpp" - -int main() -{ - using namespace GridKit; - using namespace GridKit::Testing; - - GridKit::Testing::TestingResults result; - GridKit::Testing::BusFaultTests test; - - result += test.constructor(); - result += test.zeroInitialResidual(true); - result += test.zeroInitialResidual(false); -#ifdef GRIDKIT_ENABLE_ENZYME - result += test.jacobian(true); - result += test.jacobian(false); -#endif - - return result.summary(); -} diff --git a/tests/UnitTests/PhasorDynamics/runSystemSingleComponentTests.cpp b/tests/UnitTests/PhasorDynamics/runSystemSingleComponentTests.cpp index 327d8b503f..3ae783bb7a 100644 --- a/tests/UnitTests/PhasorDynamics/runSystemSingleComponentTests.cpp +++ b/tests/UnitTests/PhasorDynamics/runSystemSingleComponentTests.cpp @@ -10,7 +10,6 @@ int main() result += test.branch(); result += test.bus(); - result += test.busFault(); result += test.ieeet1(); result += test.esdc1a(); result += test.load(); diff --git a/tests/UnitTests/Utilities/CaseFormatTests.hpp b/tests/UnitTests/Utilities/CaseFormatTests.hpp index 4cbf66b087..c3a9da7457 100644 --- a/tests/UnitTests/Utilities/CaseFormatTests.hpp +++ b/tests/UnitTests/Utilities/CaseFormatTests.hpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -77,8 +76,7 @@ namespace GridKit { "class": "Gensal", "ports": {"bus":1}, "id": "2", "params": {"p0":1.0, "q0":0.05013, "H":3.0, "D":0.0, "Ra":0.0, "Tdop":7.0, "Tdopp":0.04, "Tqopp":0.05, "Xd":2.1, "Xdp":0.2, "Xdpp":0.18, "Xq":0.5, "Xl":0.15, "S10":0.0, "S12":0.0}, "mon": ["delta", "omega"] }, { "class": "Regca", "ports": {"bus":1}, "id": "CV1", "params": {"p0":0.0, "q0":0.0, "mva":100, "Tg":0.02, "TM":0.02, "Rqmax":999.0, "Rqmin":-999.0, "Rpmax":999.0, "sL":true, "IL1":1.1, "VL0":0.4, "VL1":0.9, "VA0":0.4, "VA1":0.9, "Vhvmax":1.2}, "mon": ["ir", "ii", "p", "q"] }, - { "class": "Reecb", "ports": {"bus":1}, "id": "REE1", "params": {"mva":50.0, "Pqflag":true}, "mon": ["iqcmd", "ipcmd", "vmeas", "pmeas"] }, - { "class": "BusFault", "ports": {"bus":1}, "id": "1", "params": {"state0": false, "R":0.0, "X":1e-3} } + { "class": "Reecb", "ports": {"bus":1}, "id": "REE1", "params": {"mva":50.0, "Pqflag":true}, "mon": ["iqcmd", "ipcmd", "vmeas", "pmeas"] } ] })"; @@ -101,7 +99,6 @@ namespace GridKit success *= result.bus.size() == 2; success *= result.branch.size() == 1; - success *= result.bus_fault.size() == 1; success *= result.genrou.size() == 1; success *= result.gensal.size() == 1; success *= result.regca.size() == 1; @@ -194,13 +191,6 @@ namespace GridKit success *= result.reecb[0].monitored_variables.contains( ReecbData::MonitorableVariables::pmeas); - success *= std::get(result.bus_fault[0].parameters[BusFaultParameters::R]) == 0.0; - success *= std::get(result.bus_fault[0].parameters[BusFaultParameters::X]) == 1e-3; - success *= !std::get(result.bus_fault[0].parameters[BusFaultParameters::state0]); - success *= result.bus_fault[0].buses[BusFaultBuses::bus] == 1; - success *= result.bus_fault[0].disambiguation_string == "1"; - success *= result.bus_fault[0].monitored_variables.empty(); - return success.report(__func__); } @@ -274,8 +264,7 @@ namespace GridKit { "class": "Ieeet1", "ports": {"bus":1, "speed": 1, "efd":3}, "id": "DV3", "params": {"Tr":0.0, "Ka":50.0, "Ta":0.04, "Ke":-0.06, "Te":0.6, "Kf":0.09, "Tf":1.46, "Vrmin":-1.0, "Vrmax":1.0, "E1":2.8, "E2":3.373, "Se1":0.04, "Se2":0.33, "Ispdlim":0.0}}, { "class": "SexsPti", "ports": {"bus":1, "efd":3}, "id": "DV4", "params": {"Ta":0.1, "Tb":0.5, "Te":0.8, "K":10.0, "Efdmax":5.0, "Efdmin":-5.0}}, { "class": "GastPti", "ports": {"speed":1, "pmech":2, "pref":10}, "id": "DV7", "params": {"R":0.045, "T1":0.42, "T2":0.12, "T3":3.2, "At":0.95, "Kt":2.2, "Vmax":1.05, "Vmin":0.15, "Dturb":0.02, "Trate":120.0}, "mon": ["pmech", "xvalve", "xflow", "xtemp", "vload", "vtemp"] }, - { "class": "Reecb", "ports": {"bus":1, "pe":22, "qgen":23, "qext":24, "pfaref":25, "pref":26, "iqcmd":27, "ipcmd":28}, "id": "EC1", "params": {"mva":100.0, "PfFlag":false, "VFlag":true, "QFlag":true, "Pqflag":true, "Trv":0.02, "Tp":0.05, "Vref0":1.0, "Vdip":0.85, "Vup":1.15, "dbd1":-0.01, "dbd2":0.01, "kqv":5.0, "Iql1":-1.1, "Iqh1":1.1, "Qmax":0.436, "Qmin":-0.436, "Kqp":0.1, "Kqi":0.2, "Vmax":1.1, "Vmin":0.9, "Kvp":18.0, "Kvi":5.0, "Tiq":0.02, "Tpord":0.02, "dPmax":99.0, "dPmin":-99.0, "Pmax":1.0, "Pmin":0.0, "Imax":1.3}, "mon": ["iqcmd", "ipcmd", "vmeas", "pmeas"]}, - { "class": "BusFault", "ports": {"bus":1}, "id": "1", "params": {"state0": false, "R":0.0, "X":1e-3} } + { "class": "Reecb", "ports": {"bus":1, "pe":22, "qgen":23, "qext":24, "pfaref":25, "pref":26, "iqcmd":27, "ipcmd":28}, "id": "EC1", "params": {"mva":100.0, "PfFlag":false, "VFlag":true, "QFlag":true, "Pqflag":true, "Trv":0.02, "Tp":0.05, "Vref0":1.0, "Vdip":0.85, "Vup":1.15, "dbd1":-0.01, "dbd2":0.01, "kqv":5.0, "Iql1":-1.1, "Iqh1":1.1, "Qmax":0.436, "Qmin":-0.436, "Kqp":0.1, "Kqi":0.2, "Vmax":1.1, "Vmin":0.9, "Kvp":18.0, "Kvi":5.0, "Tiq":0.02, "Tpord":0.02, "dPmax":99.0, "dPmin":-99.0, "Pmax":1.0, "Pmin":0.0, "Imax":1.3}, "mon": ["iqcmd", "ipcmd", "vmeas", "pmeas"]} ] })"; @@ -293,7 +282,6 @@ namespace GridKit success *= result.bus.size() == 2; success *= result.branch.size() == 1; - success *= result.bus_fault.size() == 1; success *= result.genrou.size() == 1; success *= result.gov.size() == 1; success *= result.esdc1a.size() == 1; @@ -619,13 +607,6 @@ namespace GridKit success *= result.reecb[0].monitored_variables.contains( ReecbData::MonitorableVariables::pmeas); - success *= std::get(result.bus_fault[0].parameters[BusFaultParameters::R]) == 0.0; - success *= std::get(result.bus_fault[0].parameters[BusFaultParameters::X]) == 1e-3; - success *= !std::get(result.bus_fault[0].parameters[BusFaultParameters::state0]); - success *= result.bus_fault[0].buses[BusFaultBuses::bus] == 1; - success *= result.bus_fault[0].disambiguation_string == "1"; - success *= result.bus_fault[0].monitored_variables.empty(); - return success.report(__func__); } }; From f95bee8b2d6da56bae3743b9a0901f6835595523 Mon Sep 17 00:00:00 2001 From: lukelowry Date: Thu, 8 Oct 2026 10:34:22 -0500 Subject: [PATCH 2/6] Update CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 851aafa5c2..ed853112cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ - Added `BusSignalVoltageOut` bus model with voltage signal outlets and current signal inlets. - Added `BusSignalVoltageIn` bus model with voltage signal inlets and current signal outlets. - Removed `BusToSignalAdapter`. Prefer `BusSignalVoltageOut` or `BusSignalVoltageIn`. -- Replaced the `BusFault` device class with `Bus::setFault`; solver events now specify the faulted bus and fault impedance. +- Added `Bus::setFault` to apply or clear a fault to ground directly at a bus. +- Removed the `BusFault` class in favor of `Bus::setFault`. ## v0.2 From ce251841a3d6e6faa082daa7882065577fe455d4 Mon Sep 17 00:00:00 2001 From: lukelowry Date: Thu, 8 Oct 2026 13:04:44 -0500 Subject: [PATCH 3/6] Safety checks and convenience functions --- GridKit/Model/PhasorDynamics/BusBase.hpp | 6 +++++ .../PhasorDynamics/AnalysisUtilities.hpp | 2 ++ .../PhasorDynamics/ContingencyAnalysis.cpp | 14 +++++++++-- .../PhasorDynamics/DynamicSimulation.cpp | 24 +++++++++++++++++-- tests/UnitTests/PhasorDynamics/BusTests.hpp | 9 +++---- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/GridKit/Model/PhasorDynamics/BusBase.hpp b/GridKit/Model/PhasorDynamics/BusBase.hpp index 989d4280d5..cd447b6597 100644 --- a/GridKit/Model/PhasorDynamics/BusBase.hpp +++ b/GridKit/Model/PhasorDynamics/BusBase.hpp @@ -246,6 +246,12 @@ namespace GridKit return 1; } + /// Clear a fault to ground. + int clearFault() + { + return setFault(false, 0.0, 0.0); + } + virtual const IdxT busID() const { return bus_id_; diff --git a/application/PhasorDynamics/AnalysisUtilities.hpp b/application/PhasorDynamics/AnalysisUtilities.hpp index bf7e04e6bf..d8a3008b39 100644 --- a/application/PhasorDynamics/AnalysisUtilities.hpp +++ b/application/PhasorDynamics/AnalysisUtilities.hpp @@ -28,6 +28,8 @@ namespace GridKit /** * @brief Describes an event that is used to modify the simulation at the * given time point + * + * ContingencyAnalysis repeats this event at each bus with the same R and X. */ struct SystemEvent { diff --git a/application/PhasorDynamics/ContingencyAnalysis.cpp b/application/PhasorDynamics/ContingencyAnalysis.cpp index d5b9175101..b880f600cf 100644 --- a/application/PhasorDynamics/ContingencyAnalysis.cpp +++ b/application/PhasorDynamics/ContingencyAnalysis.cpp @@ -56,16 +56,26 @@ TestStatus runStudy(StudyData study_data) ida.runSimulation(event.time, dt_monitor); // Set up run for event (to start at event time) + auto* bus = sys.getBus(event.bus); + int ret = 0; + switch (event.type) { case EventType::FAULT_ON: - sys.getBus(event.bus)->setFault(true, event.R, event.X); + ret = bus->setFault(true, event.R, event.X); break; case EventType::FAULT_OFF: - sys.getBus(event.bus)->setFault(false, event.R, event.X); + ret = bus->clearFault(); break; } + if (ret != 0) + { + Log::error() << "Fault event failed for bus " << event.bus + << " at time " << event.time << '\n'; + return {false}; + } + // Re-initialize simulation at event time ida.initializeSimulation(event.time, true); } diff --git a/application/PhasorDynamics/DynamicSimulation.cpp b/application/PhasorDynamics/DynamicSimulation.cpp index f35a4524de..02dd547251 100644 --- a/application/PhasorDynamics/DynamicSimulation.cpp +++ b/application/PhasorDynamics/DynamicSimulation.cpp @@ -27,6 +27,16 @@ int runApplication(int argc, const char* argv[]) checkCommandLine(argc, "DynamicSimulation"); auto study = parseStudyData(argv[1]); + for (const auto& event : study.events) + { + if (event.bus == GridKit::INVALID_INDEX) + { + Log::error() << "Fault event at time " << event.time + << " requires a bus number\n"; + return 1; + } + } + // Instantiate system SystemModel sys(study.model_data); sys.allocate(); @@ -55,16 +65,26 @@ int runApplication(int argc, const char* argv[]) ida.runSimulation(event.time, dt_monitor); // Set up run for event (to start at event time) + auto* bus = sys.getBus(event.bus); + int ret = 0; + switch (event.type) { case EventType::FAULT_ON: - sys.getBus(event.bus)->setFault(true, event.R, event.X); + ret = bus->setFault(true, event.R, event.X); break; case EventType::FAULT_OFF: - sys.getBus(event.bus)->setFault(false, event.R, event.X); + ret = bus->clearFault(); break; } + if (ret != 0) + { + Log::error() << "Fault event failed for bus " << event.bus + << " at time " << event.time << '\n'; + return 1; + } + // Re-initialize simulation at event time ida.initializeSimulation(event.time); } diff --git a/tests/UnitTests/PhasorDynamics/BusTests.hpp b/tests/UnitTests/PhasorDynamics/BusTests.hpp index 7ae466059f..ccb68c1e3d 100644 --- a/tests/UnitTests/PhasorDynamics/BusTests.hpp +++ b/tests/UnitTests/PhasorDynamics/BusTests.hpp @@ -104,7 +104,7 @@ namespace GridKit return success.report(__func__); } - /// Fault current applied and cleared through setFault + /// Fault current applied and cleared TestOutcome fault() { TestStatus success = true; @@ -126,7 +126,7 @@ namespace GridKit success *= isEqual(bus.Ir(), current.real()); success *= isEqual(bus.Ii(), current.imag()); - success *= bus.setFault(false, R, X) == 0; + success *= bus.clearFault() == 0; bus.evaluateResidual(); success *= isEqual(bus.Ir(), 0.0); success *= isEqual(bus.Ii(), 0.0); @@ -137,6 +137,7 @@ namespace GridKit // An infinite bus cannot be faulted PhasorDynamics::BusInfinite bus_inf; success *= bus_inf.setFault(true, R, X) != 0; + success *= bus_inf.clearFault() != 0; return success.report(__func__); } @@ -197,8 +198,8 @@ namespace GridKit } // Clearing the fault keeps the same entries with zero values - const IdxT nnz = jacobian->getNnz(); - bus.setFault(false, R, X); + const IdxT nnz = jacobian->getNnz(); + success *= bus.clearFault() == 0; bus.evaluateResidual(); bus.evaluateJacobian(); success *= bus.nnz() == nnz; From b9e7c9140418db45e9fb45ba5158116f611bd2e8 Mon Sep 17 00:00:00 2001 From: lukelowry Date: Thu, 8 Oct 2026 13:14:54 -0500 Subject: [PATCH 4/6] Clarify same params for ContingencyAnalysis --- application/PhasorDynamics/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/PhasorDynamics/README.md b/application/PhasorDynamics/README.md index 628c52aba9..512ddbc776 100644 --- a/application/PhasorDynamics/README.md +++ b/application/PhasorDynamics/README.md @@ -30,6 +30,6 @@ Each event group describes a system event that occurs at a given time point --------------------|------------------------------------------------------- `time` | A floating point value for time event occurs `type` | Event type (one of { "fault_on", "fault_off" }) - `bus` | Number of the faulted bus (omitted for `ContingencyAnalysis`, which faults every bus in turn) + `bus` | Number of the faulted bus (omitted for `ContingencyAnalysis`, which faults every bus in turn using the same `R` and `X`) `R` | Fault resistance in per unit (required for "fault_on") `X` | Fault reactance in per unit (required for "fault_on") From 057d559fef98c65d884d8561cbe7304a572bad54 Mon Sep 17 00:00:00 2001 From: Luke Lowery Date: Thu, 8 Oct 2026 15:12:19 -0500 Subject: [PATCH 5/6] Update tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp Co-authored-by: Nicholson Koukpaizan <72402802+nkoukpaizan@users.noreply.github.com> --- .../PhasorDynamics/TenGen/Classical/TenGenClassical.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp b/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp index 0b8a8e98c2..2058e3250c 100644 --- a/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp +++ b/tests/IntegrationTests/PhasorDynamics/TenGen/Classical/TenGenClassical.cpp @@ -211,7 +211,7 @@ int main() success *= isEqual(gen10.y().getData()[omega_index], omega_ref, 5e-5); // Clear fault and run until t = 10s. - bus10.setFault(false, 0.0, 1e-5); + bus10.clearFault(); ida.initializeSimulation(1.1); ida.runSimulation(10.0, dt, output_cb); real_type stop = static_cast(clock()); From b06d99af5aab0545a4db9ee6a161e0e10ca0ca55 Mon Sep 17 00:00:00 2001 From: Luke Lowery Date: Thu, 8 Oct 2026 15:12:36 -0500 Subject: [PATCH 6/6] Update tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp Co-authored-by: Nicholson Koukpaizan <72402802+nkoukpaizan@users.noreply.github.com> --- tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp b/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp index badffb4372..c221cd61f2 100644 --- a/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp +++ b/tests/IntegrationTests/PhasorDynamics/PDIntegrationTests.hpp @@ -245,7 +245,7 @@ namespace GridKit ida.runSimulation(1.1, dt); // Clear the fault and run until t = 10s. - bus->setFault(false, R, X); + bus->clearFault(); ida.initializeSimulation(1.1); ida.runSimulation(10.0, dt);