From b64553247e5b442143b586dfb04bbef17d9771f1 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Fri, 20 Dec 2024 10:20:58 -0500 Subject: [PATCH 1/6] First stab at phasor dynamics models: Add bus component model. --- ComponentLib/CMakeLists.txt | 1 + ComponentLib/PhasorDynamics/Bus/Bus.cpp | 227 ++++++++++++++++++ ComponentLib/PhasorDynamics/Bus/Bus.hpp | 208 ++++++++++++++++ .../PhasorDynamics/Bus/CMakeLists.txt | 68 ++++++ ComponentLib/PhasorDynamics/Bus/README.md | 29 +++ ComponentLib/PhasorDynamics/CMakeLists.txt | 63 +++++ .../Exciter/README.md | 0 .../Governor/README.md | 0 .../Stabilizer/README.md | 0 .../SynchronousMachine/GENROUwS/README.md | 0 .../SynchronousMachine/GENSALwS/README.md | 0 .../SynchronousMachine/README.md | 0 12 files changed, 596 insertions(+) create mode 100644 ComponentLib/PhasorDynamics/Bus/Bus.cpp create mode 100644 ComponentLib/PhasorDynamics/Bus/Bus.hpp create mode 100644 ComponentLib/PhasorDynamics/Bus/CMakeLists.txt create mode 100644 ComponentLib/PhasorDynamics/Bus/README.md create mode 100644 ComponentLib/PhasorDynamics/CMakeLists.txt rename ComponentLib/{DynamicPhasor => PhasorDynamics}/Exciter/README.md (100%) rename ComponentLib/{DynamicPhasor => PhasorDynamics}/Governor/README.md (100%) rename ComponentLib/{DynamicPhasor => PhasorDynamics}/Stabilizer/README.md (100%) rename ComponentLib/{DynamicPhasor => PhasorDynamics}/SynchronousMachine/GENROUwS/README.md (100%) rename ComponentLib/{DynamicPhasor => PhasorDynamics}/SynchronousMachine/GENSALwS/README.md (100%) rename ComponentLib/{DynamicPhasor => PhasorDynamics}/SynchronousMachine/README.md (100%) diff --git a/ComponentLib/CMakeLists.txt b/ComponentLib/CMakeLists.txt index a97c973..1d14a5e 100644 --- a/ComponentLib/CMakeLists.txt +++ b/ComponentLib/CMakeLists.txt @@ -60,6 +60,7 @@ # - Cameron Rutherford #]] +add_subdirectory(PhasorDynamics) add_subdirectory(PowerFlow) add_subdirectory(PowerElectronics) diff --git a/ComponentLib/PhasorDynamics/Bus/Bus.cpp b/ComponentLib/PhasorDynamics/Bus/Bus.cpp new file mode 100644 index 0000000..bdb7224 --- /dev/null +++ b/ComponentLib/PhasorDynamics/Bus/Bus.cpp @@ -0,0 +1,227 @@ +/* + * + * Copyright (c) 2017, Lawrence Livermore National Security, LLC. + * Produced at the Lawrence Livermore National Laboratory. + * Written by Slaven Peles . + * LLNL-CODE-718378. + * All rights reserved. + * + * This file is part of GridKit™. For details, see github.com/LLNL/GridKit + * Please also read the LICENSE file. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the disclaimer (as noted below) in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the LLNS/LLNL nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL + * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * Lawrence Livermore National Laboratory is operated by Lawrence Livermore + * National Security, LLC, for the U.S. Department of Energy, National + * Nuclear Security Administration under Contract DE-AC52-07NA27344. + * + * This document was prepared as an account of work sponsored by an agency + * of the United States government. Neither the United States government nor + * Lawrence Livermore National Security, LLC, nor any of their employees + * makes any warranty, expressed or implied, or assumes any legal liability + * or responsibility for the accuracy, completeness, or usefulness of any + * information, apparatus, product, or process disclosed, or represents that + * its use would not infringe privately owned rights. Reference herein to + * any specific commercial product, process, or service by trade name, + * trademark, manufacturer, or otherwise does not necessarily constitute or + * imply its endorsement, recommendation, or favoring by the United States + * government or Lawrence Livermore National Security, LLC. The views and + * opinions of authors expressed herein do not necessarily state or reflect + * those of the United States government or Lawrence Livermore National + * Security, LLC, and shall not be used for advertising or product + * endorsement purposes. + * + */ + +#include +#include + +#include +#include "Bus.hpp" + +namespace ModelLib // change to GridKit +{ +namespace PhasorDynamics +{ + +/*! + * @brief Constructor for a phasor dynamics bus. + * + * The model is using current balance in Cartesian coordinates. + * + * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: + * - Number of equations = 2 (size_) + * - Number of variables = 2 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ +template +Bus::Bus() + : Va0_(0.0), Vr0_(0.0) +{ + //std::cout << "Create Bus..." << std::endl; + //std::cout << "Number of equations is " << size_ << std::endl; + + size_ = 2; +} + +/*! + * @brief Bus constructor. + * + * This constructor sets initial values for active and reactive voltage. + * + * @todo Arguments that should be passed to ModelEvaluatorImpl constructor: + * - Number of equations = 2 (size_) + * - Number of variables = 2 (size_) + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ +template +Bus::Bus(ScalarT Va, ScalarT Vr) + : Va0_(Va), Vr0_(Vr) +{ + //std::cout << "Create Bus..." << std::endl; + //std::cout << "Number of equations is " << size_ << std::endl; + + size_ = 2; +} + +/** + * @brief Construct a new Bus + * + * @tparam ScalarT - type of scalar variables + * @tparam IdxT - type for vector/matrix indices + * @param[in] data - structure with bus data + */ +template +Bus::Bus(BusData& data) + : Va0_(data.Vm * cos(data.Va)), Vr0_(data.Vm * sin(data.Va)) +{ + //std::cout << "Create Bus..." << std::endl; + //std::cout << "Number of equations is " << size_ << std::endl; + + size_ = 2; +} + +template +Bus::~Bus() +{ + //std::cout << "Destroy PQ bus ..." << std::endl; +} + +/*! + * @brief allocate method resizes local solution and residual vectors. + */ +template +int Bus::allocate() +{ + //std::cout << "Allocate PQ bus ..." << std::endl; + f_.resize(size_); + y_.resize(size_); + yp_.resize(size_); + tag_.resize(size_); + + fB_.resize(size_); + yB_.resize(size_); + ypB_.resize(size_); + + return 0; +} + + +template +int Bus::tagDifferentiable() +{ + tag_[0] = false; + tag_[1] = false; + return 0; +} + + +/*! + * @brief initialize method sets bus variables to stored initial values. + */ +template +int Bus::initialize() +{ + // std::cout << "Initialize Bus..." << std::endl; + y_[0] = Va0_; + y_[1] = Vr0_; + yp_[0] = 0.0; + yp_[1] = 0.0; + + return 0; +} + +/*! + * @brief PQ bus does not compute residuals, so here we just reset residual values. + * + * @warning This implementation assumes bus residuals are always evaluated + * _before_ component model residuals. + * + */ +template +int Bus::evaluateResidual() +{ + // std::cout << "Evaluating residual of a PQ bus ...\n"; + f_[0] = 0.0; + f_[1] = 0.0; + return 0; +} + + +/*! + * @brief initialize method sets bus variables to stored initial values. + */ +template +int Bus::initializeAdjoint() +{ + // std::cout << "Initialize Bus..." << std::endl; + yB_[0] = 0.0; + yB_[1] = 0.0; + ypB_[0] = 0.0; + ypB_[1] = 0.0; + + return 0; +} + +template +int Bus::evaluateAdjointResidual() +{ + fB_[0] = 0.0; + fB_[1] = 0.0; + + return 0; +} + +// Available template instantiations +template class Bus; +template class Bus; + +} // namespace PhasorDynamic +} // namespace ModelLib + diff --git a/ComponentLib/PhasorDynamics/Bus/Bus.hpp b/ComponentLib/PhasorDynamics/Bus/Bus.hpp new file mode 100644 index 0000000..a5b808b --- /dev/null +++ b/ComponentLib/PhasorDynamics/Bus/Bus.hpp @@ -0,0 +1,208 @@ +/* + * + * Copyright (c) 2017, Lawrence Livermore National Security, LLC. + * Produced at the Lawrence Livermore National Laboratory. + * Written by Slaven Peles . + * LLNL-CODE-718378. + * All rights reserved. + * + * This file is part of GridKit™. For details, see github.com/LLNL/GridKit + * Please also read the LICENSE file. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the disclaimer (as noted below) in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the LLNS/LLNL nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL + * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * Lawrence Livermore National Laboratory is operated by Lawrence Livermore + * National Security, LLC, for the U.S. Department of Energy, National + * Nuclear Security Administration under Contract DE-AC52-07NA27344. + * + * This document was prepared as an account of work sponsored by an agency + * of the United States government. Neither the United States government nor + * Lawrence Livermore National Security, LLC, nor any of their employees + * makes any warranty, expressed or implied, or assumes any legal liability + * or responsibility for the accuracy, completeness, or usefulness of any + * information, apparatus, product, or process disclosed, or represents that + * its use would not infringe privately owned rights. Reference herein to + * any specific commercial product, process, or service by trade name, + * trademark, manufacturer, or otherwise does not necessarily constitute or + * imply its endorsement, recommendation, or favoring by the United States + * government or Lawrence Livermore National Security, LLC. The views and + * opinions of authors expressed herein do not necessarily state or reflect + * those of the United States government or Lawrence Livermore National + * Security, LLC, and shall not be used for advertising or product + * endorsement purposes. + * + */ + +#pragma once + +#include + + +// Forward declaration of BusData structure +namespace GridKit +{ +namespace PowerSystemData +{ + template + struct BusData; +} +} + +namespace ModelLib // change to GridKit +{ +namespace PhasorDynamics +{ + /*! + * @brief Implementation of a PQ bus. + * + * Voltage _V_ and phase _theta_ are variables in PQ bus model. + * Active and reactive power, _P_ and _Q_, are residual components. + * + * + */ + template + class Bus : public ModelEvaluatorImpl + { + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + using ModelEvaluatorImpl::yB_; + using ModelEvaluatorImpl::ypB_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::fB_; + using ModelEvaluatorImpl::tag_; + + public: + using real_type = typename ModelEvaluatorImpl::real_type; + using BusData = GridKit::PowerSystemData::BusData; + + Bus(); + Bus(ScalarT Va, ScalarT Vr); + Bus(BusData& data); + virtual ~Bus(); + + virtual int allocate(); + virtual int tagDifferentiable(); + virtual int initialize(); + virtual int evaluateResidual(); + virtual int initializeAdjoint(); + virtual int evaluateAdjointResidual(); + + virtual ScalarT& Va() + { + return y_[0]; + } + + virtual const ScalarT& Va() const + { + return y_[0]; + } + + virtual ScalarT& Vr() + { + return y_[1]; + } + + virtual const ScalarT& Vr() const + { + return y_[1]; + } + + virtual ScalarT& Ia() + { + return f_[0]; + } + + virtual const ScalarT& Ia() const + { + return f_[0]; + } + + virtual ScalarT& Ir() + { + return f_[1]; + } + + virtual const ScalarT& Ir() const + { + return f_[1]; + } + + virtual ScalarT& lambdaIa() + { + return yB_[0]; + } + + virtual const ScalarT& lambdaIa() const + { + return yB_[0]; + } + + virtual ScalarT& lambdaIr() + { + return yB_[1]; + } + + virtual const ScalarT& lambdaIr() const + { + return yB_[1]; + } + + virtual ScalarT& IaB() + { + return fB_[0]; + } + + virtual const ScalarT& IaB() const + { + return fB_[0]; + } + + virtual ScalarT& IrB() + { + return fB_[1]; + } + + virtual const ScalarT& IrB() const + { + return fB_[1]; + } + + // virtual const int BusType() const + // { + // return BaseBus::BusType::PQ; + // } + + private: + // Default initial values for voltage and phase on PQ bus + ScalarT Va0_{0.0}; + ScalarT Vr0_{0.0}; + + }; + +} // PhasorDynamics +} // namespace GridKit diff --git a/ComponentLib/PhasorDynamics/Bus/CMakeLists.txt b/ComponentLib/PhasorDynamics/Bus/CMakeLists.txt new file mode 100644 index 0000000..356b7f5 --- /dev/null +++ b/ComponentLib/PhasorDynamics/Bus/CMakeLists.txt @@ -0,0 +1,68 @@ +# +# Copyright (c) 2017, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# Written by Slaven Peles . +# LLNL-CODE-718378. +# All rights reserved. +# +# This file is part of GridKit™. For details, see github.com/LLNL/GridKit +# Please also read the LICENSE file. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# - Redistributions of source code must retain the above copyright notice, +# this list of conditions and the disclaimer below. +# - Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the disclaimer (as noted below) in the +# documentation and/or other materials provided with the distribution. +# - Neither the name of the LLNS/LLNL nor the names of its contributors may +# be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL +# SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY +# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# Lawrence Livermore National Laboratory is operated by Lawrence Livermore +# National Security, LLC, for the U.S. Department of Energy, National +# Nuclear Security Administration under Contract DE-AC52-07NA27344. +# +# This document was prepared as an account of work sponsored by an agency +# of the United States government. Neither the United States government nor +# Lawrence Livermore National Security, LLC, nor any of their employees +# makes any warranty, expressed or implied, or assumes any legal liability +# or responsibility for the accuracy, completeness, or usefulness of any +# information, apparatus, product, or process disclosed, or represents that +# its use would not infringe privately owned rights. Reference herein to +# any specific commercial product, process, or service by trade name, +# trademark, manufacturer, or otherwise does not necessarily constitute or +# imply its endorsement, recommendation, or favoring by the United States +# government or Lawrence Livermore National Security, LLC. The views and +# opinions of authors expressed herein do not necessarily state or reflect +# those of the United States government or Lawrence Livermore National +# Security, LLC, and shall not be used for advertising or product +# endorsement purposes. +# + +# [[ +# Author(s): +# - Cameron Rutherford +#]] + +gridkit_add_library(phasor_dynamics_bus + SOURCES + Bus.cpp + OUTPUT_NAME + gridkit_phasor_dynamics_bus) + diff --git a/ComponentLib/PhasorDynamics/Bus/README.md b/ComponentLib/PhasorDynamics/Bus/README.md new file mode 100644 index 0000000..d000f08 --- /dev/null +++ b/ComponentLib/PhasorDynamics/Bus/README.md @@ -0,0 +1,29 @@ +# Bus Model + +A bus is a point of interconnection of electrical devices. Bus component model +also plays a key role in coupling system components. Each bus $`i`$ owns two +variables -- active and reactive voltage $`V_{ai}`$ and $`V_{ri}`$, +respectively. The bus also owns current balance residual equations for active +and reactive currents coming into the bus $`I_{ai}`$ and $`I_{ri}`$, +respectively. While th bus model owns current residuals, it _does not compute_ +them. Instead each component connected to the bus is adding its contribution +to the residual. The bus will merely initialize the residual to zero each time +numerical integrator requests residual evaluation. + +**Sign Convention** + +Current entering the bus has positive and current exiting the bus negative +sign. + +
+ + + Figure 1: Needs to be changed to represent current balance instead of power + balance. +
+ + + + +**Other Parameters** +Buses are uniquely defined by their ID (number or name). Besides, each bus should have associated Nominal Voltage value. \ No newline at end of file diff --git a/ComponentLib/PhasorDynamics/CMakeLists.txt b/ComponentLib/PhasorDynamics/CMakeLists.txt new file mode 100644 index 0000000..45c9350 --- /dev/null +++ b/ComponentLib/PhasorDynamics/CMakeLists.txt @@ -0,0 +1,63 @@ +# +# Copyright (c) 2017, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# Written by Slaven Peles . +# LLNL-CODE-718378. +# All rights reserved. +# +# This file is part of GridKit™. For details, see github.com/LLNL/GridKit +# Please also read the LICENSE file. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# - Redistributions of source code must retain the above copyright notice, +# this list of conditions and the disclaimer below. +# - Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the disclaimer (as noted below) in the +# documentation and/or other materials provided with the distribution. +# - Neither the name of the LLNS/LLNL nor the names of its contributors may +# be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL +# SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY +# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# Lawrence Livermore National Laboratory is operated by Lawrence Livermore +# National Security, LLC, for the U.S. Department of Energy, National +# Nuclear Security Administration under Contract DE-AC52-07NA27344. +# +# This document was prepared as an account of work sponsored by an agency +# of the United States government. Neither the United States government nor +# Lawrence Livermore National Security, LLC, nor any of their employees +# makes any warranty, expressed or implied, or assumes any legal liability +# or responsibility for the accuracy, completeness, or usefulness of any +# information, apparatus, product, or process disclosed, or represents that +# its use would not infringe privately owned rights. Reference herein to +# any specific commercial product, process, or service by trade name, +# trademark, manufacturer, or otherwise does not necessarily constitute or +# imply its endorsement, recommendation, or favoring by the United States +# government or Lawrence Livermore National Security, LLC. The views and +# opinions of authors expressed herein do not necessarily state or reflect +# those of the United States government or Lawrence Livermore National +# Security, LLC, and shall not be used for advertising or product +# endorsement purposes. +# + +# [[ +# Author(s): +# - Cameron Rutherford +#]] + +add_subdirectory(Bus) diff --git a/ComponentLib/DynamicPhasor/Exciter/README.md b/ComponentLib/PhasorDynamics/Exciter/README.md similarity index 100% rename from ComponentLib/DynamicPhasor/Exciter/README.md rename to ComponentLib/PhasorDynamics/Exciter/README.md diff --git a/ComponentLib/DynamicPhasor/Governor/README.md b/ComponentLib/PhasorDynamics/Governor/README.md similarity index 100% rename from ComponentLib/DynamicPhasor/Governor/README.md rename to ComponentLib/PhasorDynamics/Governor/README.md diff --git a/ComponentLib/DynamicPhasor/Stabilizer/README.md b/ComponentLib/PhasorDynamics/Stabilizer/README.md similarity index 100% rename from ComponentLib/DynamicPhasor/Stabilizer/README.md rename to ComponentLib/PhasorDynamics/Stabilizer/README.md diff --git a/ComponentLib/DynamicPhasor/SynchronousMachine/GENROUwS/README.md b/ComponentLib/PhasorDynamics/SynchronousMachine/GENROUwS/README.md similarity index 100% rename from ComponentLib/DynamicPhasor/SynchronousMachine/GENROUwS/README.md rename to ComponentLib/PhasorDynamics/SynchronousMachine/GENROUwS/README.md diff --git a/ComponentLib/DynamicPhasor/SynchronousMachine/GENSALwS/README.md b/ComponentLib/PhasorDynamics/SynchronousMachine/GENSALwS/README.md similarity index 100% rename from ComponentLib/DynamicPhasor/SynchronousMachine/GENSALwS/README.md rename to ComponentLib/PhasorDynamics/SynchronousMachine/GENSALwS/README.md diff --git a/ComponentLib/DynamicPhasor/SynchronousMachine/README.md b/ComponentLib/PhasorDynamics/SynchronousMachine/README.md similarity index 100% rename from ComponentLib/DynamicPhasor/SynchronousMachine/README.md rename to ComponentLib/PhasorDynamics/SynchronousMachine/README.md From b17e129b941f5d9715156bf8eb5dde7afbae5cc0 Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Fri, 20 Dec 2024 10:29:20 -0500 Subject: [PATCH 2/6] Fix paths for the figures. Corrected paths to figures in README files for phasor dynamics component models. --- ComponentLib/PhasorDynamics/Exciter/README.md | 2 +- ComponentLib/PhasorDynamics/Governor/README.md | 2 +- ComponentLib/PhasorDynamics/Stabilizer/README.md | 2 +- .../PhasorDynamics/SynchronousMachine/GENROUwS/README.md | 2 +- .../PhasorDynamics/SynchronousMachine/GENSALwS/README.md | 2 +- ComponentLib/PhasorDynamics/SynchronousMachine/README.md | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ComponentLib/PhasorDynamics/Exciter/README.md b/ComponentLib/PhasorDynamics/Exciter/README.md index e32003d..de04b75 100644 --- a/ComponentLib/PhasorDynamics/Exciter/README.md +++ b/ComponentLib/PhasorDynamics/Exciter/README.md @@ -4,7 +4,7 @@ **Note: Exciter model not yet implemented**
- + Figure 1: Exciter EXDC1 model. Fifure courtesy of [PoweWorld](https://www.powerworld.com/WebHelp/). diff --git a/ComponentLib/PhasorDynamics/Governor/README.md b/ComponentLib/PhasorDynamics/Governor/README.md index be6be49..0447ca4 100644 --- a/ComponentLib/PhasorDynamics/Governor/README.md +++ b/ComponentLib/PhasorDynamics/Governor/README.md @@ -8,7 +8,7 @@ Standard model of the stream turbine
- + Figure 1: Governor TGOV1 model. Figure courtesy of [PowerWorld](https://www.powerworld.com/WebHelp/) diff --git a/ComponentLib/PhasorDynamics/Stabilizer/README.md b/ComponentLib/PhasorDynamics/Stabilizer/README.md index 722741d..39c5084 100644 --- a/ComponentLib/PhasorDynamics/Stabilizer/README.md +++ b/ComponentLib/PhasorDynamics/Stabilizer/README.md @@ -4,7 +4,7 @@
- + Figure 1: Power system stabilizer PSS1A model. Figure courtesy of [PowerWorld](https://www.powerworld.com/WebHelp/) diff --git a/ComponentLib/PhasorDynamics/SynchronousMachine/GENROUwS/README.md b/ComponentLib/PhasorDynamics/SynchronousMachine/GENROUwS/README.md index ea9a20d..b24b5a2 100644 --- a/ComponentLib/PhasorDynamics/SynchronousMachine/GENROUwS/README.md +++ b/ComponentLib/PhasorDynamics/SynchronousMachine/GENROUwS/README.md @@ -6,7 +6,7 @@ - same relative amount of saturation occurs on both $`d`$ and $`q`$ axis
- + Figure 2: GENROU. Figure courtesy of [PowerWorld](https://www.powerworld.com/WebHelp/) diff --git a/ComponentLib/PhasorDynamics/SynchronousMachine/GENSALwS/README.md b/ComponentLib/PhasorDynamics/SynchronousMachine/GENSALwS/README.md index 9c5b897..159377d 100644 --- a/ComponentLib/PhasorDynamics/SynchronousMachine/GENSALwS/README.md +++ b/ComponentLib/PhasorDynamics/SynchronousMachine/GENSALwS/README.md @@ -8,7 +8,7 @@ - $`T'_{q0}`$ is neglected
- + Figure 2: GENSAL. Figure courtesy of [PowerWorld](https://www.powerworld.com/WebHelp/) diff --git a/ComponentLib/PhasorDynamics/SynchronousMachine/README.md b/ComponentLib/PhasorDynamics/SynchronousMachine/README.md index 66c5ccb..037e630 100644 --- a/ComponentLib/PhasorDynamics/SynchronousMachine/README.md +++ b/ComponentLib/PhasorDynamics/SynchronousMachine/README.md @@ -9,7 +9,7 @@
- + Figure 1: Synchronous Machine. Figure courtesy of [PowerWorld](https://www.powerworld.com/files/Synchronous-Machines.pdf) @@ -107,7 +107,7 @@ T'_{q0}\dfrac{dE'_{d}}{dt}= -E'_{d}+(X_{q}-X'_{q})(I_{q}-\dfrac{X'_{q}-X''_{q}}{ ``` Previos equations can be used to model any machine, however ***SATURATION*** is missing. -Saturation means increasingly large amounts of current are needed to increase the flux density. There are various methods to include the saturation (it is not standardized yet). We are going to use the approach implemented in PTI PSSS/E and PowerWorld Simulator (scaled quadratic). +Saturation means increasingly large amounts of current are needed to increase the flux density. There are various methods to include the saturation (it is not standardized yet). We are going to use the approach implemented in PTI PSS/E and PowerWorld Simulator (scaled quadratic). ```math Sat(x) = \begin{cases} @@ -117,6 +117,6 @@ Sat(x) = \begin{cases} ``` There are two solutions, and one where $`A<1`$ should be chosen. -Hint! +#### Hint Negative values are not allowed. From 3245a472e7cd9679aabf30c45b6ee020d3fa7c2a Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Fri, 20 Dec 2024 10:58:43 -0500 Subject: [PATCH 3/6] Add template for phasor dynamics branch model. --- ComponentLib/PhasorDynamics/Branch/Branch.cpp | 220 ++++++++++++++++++ ComponentLib/PhasorDynamics/Branch/Branch.hpp | 208 +++++++++++++++++ .../PhasorDynamics/Branch/CMakeLists.txt | 68 ++++++ ComponentLib/PhasorDynamics/Branch/README.md | 130 +++++++++++ 4 files changed, 626 insertions(+) create mode 100644 ComponentLib/PhasorDynamics/Branch/Branch.cpp create mode 100644 ComponentLib/PhasorDynamics/Branch/Branch.hpp create mode 100644 ComponentLib/PhasorDynamics/Branch/CMakeLists.txt create mode 100644 ComponentLib/PhasorDynamics/Branch/README.md diff --git a/ComponentLib/PhasorDynamics/Branch/Branch.cpp b/ComponentLib/PhasorDynamics/Branch/Branch.cpp new file mode 100644 index 0000000..63fae72 --- /dev/null +++ b/ComponentLib/PhasorDynamics/Branch/Branch.cpp @@ -0,0 +1,220 @@ +/* + * + * Copyright (c) 2017, Lawrence Livermore National Security, LLC. + * Produced at the Lawrence Livermore National Laboratory. + * Written by Slaven Peles and Duan Nan . + * LLNL-CODE-718378. + * All rights reserved. + * + * This file is part of GridKit™. For details, see github.com/LLNL/GridKit + * Please also read the LICENSE file. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the disclaimer (as noted below) in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the LLNS/LLNL nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL + * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * Lawrence Livermore National Laboratory is operated by Lawrence Livermore + * National Security, LLC, for the U.S. Department of Energy, National + * Nuclear Security Administration under Contract DE-AC52-07NA27344. + * + * This document was prepared as an account of work sponsored by an agency + * of the United States government. Neither the United States government nor + * Lawrence Livermore National Security, LLC, nor any of their employees + * makes any warranty, expressed or implied, or assumes any legal liability + * or responsibility for the accuracy, completeness, or usefulness of any + * information, apparatus, product, or process disclosed, or represents that + * its use would not infringe privately owned rights. Reference herein to + * any specific commercial product, process, or service by trade name, + * trademark, manufacturer, or otherwise does not necessarily constitute or + * imply its endorsement, recommendation, or favoring by the United States + * government or Lawrence Livermore National Security, LLC. The views and + * opinions of authors expressed herein do not necessarily state or reflect + * those of the United States government or Lawrence Livermore National + * Security, LLC, and shall not be used for advertising or product + * endorsement purposes. + * + */ + +#include +#include +#include +#include + +#include "Branch.hpp" + +namespace ModelLib { // change to GridKit +namespace PhasorDynamics { + +/*! + * @brief Constructor for a pi-model branch + * + * Arguments passed to ModelEvaluatorImpl: + * - Number of equations = 0 + * - Number of independent variables = 0 + * - Number of quadratures = 0 + * - Number of optimization parameters = 0 + */ + +template +Branch::Branch(bus_type* bus1, bus_type* bus2) + : R_(0.0), + X_(0.01), + G_(0.0), + B_(0.0), + fbusID_(0), + tbusID_(0), + bus1_(bus1), + bus2_(bus2) +{ + size_ = 0; +} + +template +Branch::Branch(real_type R, real_type X, real_type G, real_type B, bus_type* bus1, bus_type* bus2) + : R_(R), + X_(X), + G_(G), + B_(B), + fbusID_(0), + tbusID_(0), + bus1_(bus1), + bus2_(bus2) +{ +} + +template +Branch::Branch(bus_type* bus1, bus_type* bus2, BranchData& data) + : R_(data.r), + X_(data.x), + G_(0.0), + B_(data.b), + fbusID_(data.fbus), + tbusID_(data.tbus), + bus1_(bus1), + bus2_(bus2) +{ + size_ = 0; +} + + +template +Branch::~Branch() +{ + //std::cout << "Destroy Branch..." << std::endl; +} + +/*! + * @brief allocate method computes sparsity pattern of the Jacobian. + */ +template +int Branch::allocate() +{ + //std::cout << "Allocate Branch..." << std::endl; + return 0; +} + +/** + * Initialization of the branch model + * + */ +template +int Branch::initialize() +{ + return 0; +} + +/** + * \brief Identify differential variables. + */ +template +int Branch::tagDifferentiable() +{ + return 0; +} + +/** + * \brief Residual contribution of the branch is pushed to the + * two terminal buses. + * + * @todo Add and verify conductance to ground (B and G) + */ +template +int Branch::evaluateResidual() +{ + // std::cout << "Evaluating branch residual ...\n"; + real_type b = -X_/(R_*R_ + X_*X_); + real_type g = R_/(R_*R_ + X_*X_); + ScalarT dtheta = theta1() - theta2(); + + P1() -= ( g + 0.5*G_)*V1()*V1() + V1()*V2()*(-g*cos(dtheta) - b*sin(dtheta)); + Q1() -= (-b - 0.5*B_)*V1()*V1() + V1()*V2()*(-g*sin(dtheta) + b*cos(dtheta)); + P2() -= ( g + 0.5*G_)*V2()*V2() + V1()*V2()*(-g*cos(dtheta) + b*sin(dtheta)); + Q2() -= (-b - 0.5*B_)*V2()*V2() + V1()*V2()*( g*sin(dtheta) + b*cos(dtheta)); + + return 0; +} + +template +int Branch::evaluateJacobian() +{ + std::cout << "Evaluate Jacobian for Branch..." << std::endl; + std::cout << "Jacobian evaluation not implemented!" << std::endl; + return 0; +} + +template +int Branch::evaluateIntegrand() +{ + // std::cout << "Evaluate Integrand for Branch..." << std::endl; + return 0; +} + +template +int Branch::initializeAdjoint() +{ + //std::cout << "Initialize adjoint for Branch..." << std::endl; + return 0; +} + +template +int Branch::evaluateAdjointResidual() +{ + // std::cout << "Evaluate adjoint residual for Branch..." << std::endl; + return 0; +} + +template +int Branch::evaluateAdjointIntegrand() +{ + // std::cout << "Evaluate adjoint Integrand for Branch..." << std::endl; + return 0; +} + +// Available template instantiations +template class Branch; +template class Branch; + +} //namespace PhasorDynamics +} //namespace GridKit diff --git a/ComponentLib/PhasorDynamics/Branch/Branch.hpp b/ComponentLib/PhasorDynamics/Branch/Branch.hpp new file mode 100644 index 0000000..0aca748 --- /dev/null +++ b/ComponentLib/PhasorDynamics/Branch/Branch.hpp @@ -0,0 +1,208 @@ +/* + * + * Copyright (c) 2017, Lawrence Livermore National Security, LLC. + * Produced at the Lawrence Livermore National Laboratory. + * Written by Slaven Peles and Duan Nan . + * LLNL-CODE-718378. + * All rights reserved. + * + * This file is part of GridKit™. For details, see github.com/LLNL/GridKit + * Please also read the LICENSE file. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the disclaimer (as noted below) in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the LLNS/LLNL nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL + * SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * Lawrence Livermore National Laboratory is operated by Lawrence Livermore + * National Security, LLC, for the U.S. Department of Energy, National + * Nuclear Security Administration under Contract DE-AC52-07NA27344. + * + * This document was prepared as an account of work sponsored by an agency + * of the United States government. Neither the United States government nor + * Lawrence Livermore National Security, LLC, nor any of their employees + * makes any warranty, expressed or implied, or assumes any legal liability + * or responsibility for the accuracy, completeness, or usefulness of any + * information, apparatus, product, or process disclosed, or represents that + * its use would not infringe privately owned rights. Reference herein to + * any specific commercial product, process, or service by trade name, + * trademark, manufacturer, or otherwise does not necessarily constitute or + * imply its endorsement, recommendation, or favoring by the United States + * government or Lawrence Livermore National Security, LLC. The views and + * opinions of authors expressed herein do not necessarily state or reflect + * those of the United States government or Lawrence Livermore National + * Security, LLC, and shall not be used for advertising or product + * endorsement purposes. + * + */ + +#pragma once + +#include + +// Forward declarations. +namespace GridKit +{ +namespace PowerSystemData +{ + template struct BranchData; +} +} + +namespace ModelLib +{ +namespace PhasorDynamics +{ + template class Bus; +} +} + +namespace ModelLib +{ +namespace PhasorDynamics +{ + /*! + * @brief Implementation of a pi-model branch between two buses. + * + */ + template + class Branch : public ModelEvaluatorImpl + { + using ModelEvaluatorImpl::size_; + using ModelEvaluatorImpl::nnz_; + using ModelEvaluatorImpl::time_; + using ModelEvaluatorImpl::alpha_; + using ModelEvaluatorImpl::y_; + using ModelEvaluatorImpl::yp_; + using ModelEvaluatorImpl::tag_; + using ModelEvaluatorImpl::f_; + using ModelEvaluatorImpl::g_; + using ModelEvaluatorImpl::yB_; + using ModelEvaluatorImpl::ypB_; + using ModelEvaluatorImpl::fB_; + using ModelEvaluatorImpl::gB_; + using ModelEvaluatorImpl::param_; + + using bus_type = Bus; + using real_type = typename ModelEvaluatorImpl::real_type; + using BranchData = GridKit::PowerSystemData::BranchData; + + public: + Branch(bus_type* bus1, bus_type* bus2); + Branch(real_type R, real_type X, real_type G, real_type B, bus_type* bus1, bus_type* bus2); + Branch(bus_type* bus1, bus_type* bus2, BranchData& data); + virtual ~Branch(); + + int allocate(); + int initialize(); + int tagDifferentiable(); + int evaluateResidual(); + int evaluateJacobian(); + int evaluateIntegrand(); + + int initializeAdjoint(); + int evaluateAdjointResidual(); + //int evaluateAdjointJacobian(); + int evaluateAdjointIntegrand(); + + void updateTime(real_type t, real_type a) + { + } + + public: + void setR(real_type R) + { + R_ = R; + } + + void setX(real_type X) + { + // std::cout << "Setting X ...\n"; + X_ = X; + } + + void setG(real_type G) + { + G_ = G; + } + + void setB(real_type B) + { + B_ = B; + } + + private: + ScalarT& V1() + { + return bus1_->V(); + } + + ScalarT& theta1() + { + return bus1_->theta(); + } + + ScalarT& P1() + { + return bus1_->P(); + } + + ScalarT& Q1() + { + return bus1_->Q(); + } + + ScalarT& V2() + { + return bus2_->V(); + } + + ScalarT& theta2() + { + return bus2_->theta(); + } + + ScalarT& P2() + { + return bus2_->P(); + } + + ScalarT& Q2() + { + return bus2_->Q(); + } + + private: + real_type R_; + real_type X_; + real_type G_; + real_type B_; + const IdxT fbusID_; + const IdxT tbusID_; + bus_type* bus1_; + bus_type* bus2_; + }; + +} // namespace PhasorDynamics +} // namespace GridKit diff --git a/ComponentLib/PhasorDynamics/Branch/CMakeLists.txt b/ComponentLib/PhasorDynamics/Branch/CMakeLists.txt new file mode 100644 index 0000000..bd4ff42 --- /dev/null +++ b/ComponentLib/PhasorDynamics/Branch/CMakeLists.txt @@ -0,0 +1,68 @@ +# +# Copyright (c) 2017, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# Written by Slaven Peles . +# LLNL-CODE-718378. +# All rights reserved. +# +# This file is part of GridKit™. For details, see github.com/LLNL/GridKit +# Please also read the LICENSE file. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# - Redistributions of source code must retain the above copyright notice, +# this list of conditions and the disclaimer below. +# - Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the disclaimer (as noted below) in the +# documentation and/or other materials provided with the distribution. +# - Neither the name of the LLNS/LLNL nor the names of its contributors may +# be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL +# SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY +# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# Lawrence Livermore National Laboratory is operated by Lawrence Livermore +# National Security, LLC, for the U.S. Department of Energy, National +# Nuclear Security Administration under Contract DE-AC52-07NA27344. +# +# This document was prepared as an account of work sponsored by an agency +# of the United States government. Neither the United States government nor +# Lawrence Livermore National Security, LLC, nor any of their employees +# makes any warranty, expressed or implied, or assumes any legal liability +# or responsibility for the accuracy, completeness, or usefulness of any +# information, apparatus, product, or process disclosed, or represents that +# its use would not infringe privately owned rights. Reference herein to +# any specific commercial product, process, or service by trade name, +# trademark, manufacturer, or otherwise does not necessarily constitute or +# imply its endorsement, recommendation, or favoring by the United States +# government or Lawrence Livermore National Security, LLC. The views and +# opinions of authors expressed herein do not necessarily state or reflect +# those of the United States government or Lawrence Livermore National +# Security, LLC, and shall not be used for advertising or product +# endorsement purposes. +# + +# [[ +# Author(s): +# - Cameron Rutherford +#]] + +gridkit_add_library(branch + SOURCES + Branch.cpp + OUTPUT_NAME + gridkit_branch) + diff --git a/ComponentLib/PhasorDynamics/Branch/README.md b/ComponentLib/PhasorDynamics/Branch/README.md new file mode 100644 index 0000000..ed8724b --- /dev/null +++ b/ComponentLib/PhasorDynamics/Branch/README.md @@ -0,0 +1,130 @@ +# Branch Model + +Transmission lines and different types of transformers (traditional, Load Tap-Changing transformers (LTC) and Phase Angle Regulators (PARs)) can be modeled with a common branch model. + +## Transmission Line Model + +The most common circuit that is used to represent the transmission line model is $`\pi`$ circuit as shown in Figure 1. The nominal flow direction is from sending bus _s_ to receiving bus _r_. + +
+ + + + Figure 1: Transmission line $`\pi`$ equivalent circuit +
+ +Here +``` math +Z'=R+jX +``` +and +``` math +Y'=G+jB, +``` +where $`R`$ is line series resistance, $`X`$ is line series reactance, $`B`$ is line shunt charging, and $`G`$ is line shunt conductance. As can be seen from Figure 1 total $`B`$ and $`G`$ are separated between two buses. +The current leaving the sending bus can be obtained from Kirchhoff's current law as +```math +I_s = y(V_s - V_r) + \frac{Y'}{2} V_s, +``` +where $`V_s`$ and $`V_r`$ are voltages on sending and receiving bus, respectively, and +```math +y = \frac{1}{Z'} = \frac{R}{R^2+X^2} + j\frac{-X}{R^2+X^2} = g + jb. +``` +Similarly, current leaving receiving bus is given as +```math +-I_R = y(V_r - V_s) + \frac{Y'}{2} V_r. +``` +These equations can be written in a compact form as: +```math +\begin{bmatrix} +I_{s}\\ +-I_{r} +\end{bmatrix} += \mathbf{Y}_{TL} +\begin{bmatrix} +V_{s}\\ +V_{r} +\end{bmatrix} +``` +where: +```math +\mathbf{Y}_{TL}=\begin{bmatrix} + g + jb + \dfrac{G+jB}{2} & -(g + jb) \\ +-(g + jb) & g + jb + \dfrac{G+jB}{2} +\end{bmatrix} +``` + +### Branch contributions to residuals for sending and receiving bus + +Complex power leaving sending and receiving bus is computed as +```math +\begin{bmatrix} +S_{s}\\ +S_{r} +\end{bmatrix} += +\begin{bmatrix} +V_{s}\\ +V_{r} +\end{bmatrix} +\begin{bmatrix} +I_{s}\\ +-I_{r} +\end{bmatrix}^* += +\begin{bmatrix} +V_{s}\\ +V_{r} +\end{bmatrix} +\mathbf{Y}_{TL}^* +\begin{bmatrix} +V_{s}\\ +V_{r} +\end{bmatrix}^* +``` +After some algebra, one obtains expressions for active and reactive power that the branch takes from adjacent buses: +```math +P_{s} = \left(g + \frac{G}{2}\right) |V_{s}|^2 + [-g \cos(\theta_s - \theta_r) - b \sin(\theta_s - \theta_r)] |V_{s}| |V_{r}| +``` + +```math +Q_{s} = -\left(b + \frac{B}{2}\right) |V_{s}|^2 + [-g \sin(\theta_s - \theta_r) + b \cos(\theta_s - \theta_r)] |V_{s}| |V_{r}| +``` + +```math +P_{r} = \left(g + \frac{G}{2}\right) |V_{r}|^2 + [-g \cos(\theta_s - \theta_r) + b \sin(\theta_s - \theta_r)] |V_{s}| |V_{r}| +``` + +```math +Q_{r} = -\left(b + \frac{B}{2}\right) |V_{r}|^2 + [ g \sin(\theta_s - \theta_r) + b \cos(\theta_s - \theta_r)] |V_{s}| |V_{r}| +``` + +These quantities are treated as _loads_ and are substracted from $`P`$ and $`Q`$ residuals computed on the respective buses. + +## Branch Model + +**Note: Transformer model not yet implemented** + +The branch model can be created by adding the ideal transformer in series with the $`\pi`$ circuit as shown in Figure 2 where $`\tau`$ is a tap ratio magnitude and $`\theta_{shift}`$is the phase shift angle. + +
+ + + + Figure 2: Branch equivalent circuit +
+ + +The branch admitance matrix is then: + +```math +\mathbf{Y}_{BR}= +\begin{bmatrix} + \left(g + jb + \dfrac{G+jB}{2} \right)\dfrac{1}{\tau^2} & -(g + jb)\dfrac{1}{\tau e^{-j\theta_{shift}}}\\ + &\\ + -(g + jb)\dfrac{1}{\tau e^{j\theta_{shift}}}. & g + jb + \dfrac{G+jB}{2} +\end{bmatrix} +``` +### Branch contribution to residuals for sending and receiving bus + +The power flow contribution for the transformer model are obtained in a similar manner as for the $`\pi`$-model. From 5e541eef1db424c3b64be5a4bfc84be7c7bfe4fc Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 23 Dec 2024 16:43:07 -0500 Subject: [PATCH 4/6] Add branch model. --- .gitignore | 1 + ComponentLib/PhasorDynamics/Branch/Branch.cpp | 28 +++-- ComponentLib/PhasorDynamics/Branch/Branch.hpp | 36 +++--- .../PhasorDynamics/Branch/CMakeLists.txt | 6 +- ComponentLib/PhasorDynamics/Branch/README.md | 114 ++++++++---------- ComponentLib/PhasorDynamics/Bus/Bus.hpp | 32 ++--- ComponentLib/PhasorDynamics/CMakeLists.txt | 1 + .../Figures/branch_phasor_dynamics.png | Bin 0 -> 6146 bytes Documentation/Figures/transformer-branch.png | Bin 0 -> 9852 bytes 9 files changed, 107 insertions(+), 111 deletions(-) create mode 100644 Documentation/Figures/branch_phasor_dynamics.png create mode 100644 Documentation/Figures/transformer-branch.png diff --git a/.gitignore b/.gitignore index 304aea9..7e7605b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ .vscode/ build/ +*.DS_Store \ No newline at end of file diff --git a/ComponentLib/PhasorDynamics/Branch/Branch.cpp b/ComponentLib/PhasorDynamics/Branch/Branch.cpp index 63fae72..b6005d4 100644 --- a/ComponentLib/PhasorDynamics/Branch/Branch.cpp +++ b/ComponentLib/PhasorDynamics/Branch/Branch.cpp @@ -83,8 +83,8 @@ Branch::Branch(bus_type* bus1, bus_type* bus2) X_(0.01), G_(0.0), B_(0.0), - fbusID_(0), - tbusID_(0), + bus1ID_(0), + bus2ID_(0), bus1_(bus1), bus2_(bus2) { @@ -92,13 +92,18 @@ Branch::Branch(bus_type* bus1, bus_type* bus2) } template -Branch::Branch(real_type R, real_type X, real_type G, real_type B, bus_type* bus1, bus_type* bus2) +Branch::Branch(real_type R, + real_type X, + real_type G, + real_type B, + bus_type* bus1, + bus_type* bus2) : R_(R), X_(X), G_(G), B_(B), - fbusID_(0), - tbusID_(0), + bus1ID_(0), + bus2ID_(0), bus1_(bus1), bus2_(bus2) { @@ -110,8 +115,8 @@ Branch::Branch(bus_type* bus1, bus_type* bus2, BranchData& data) X_(data.x), G_(0.0), B_(data.b), - fbusID_(data.fbus), - tbusID_(data.tbus), + bus1ID_(data.fbus), + bus2ID_(data.tbus), bus1_(bus1), bus2_(bus2) { @@ -166,12 +171,11 @@ int Branch::evaluateResidual() // std::cout << "Evaluating branch residual ...\n"; real_type b = -X_/(R_*R_ + X_*X_); real_type g = R_/(R_*R_ + X_*X_); - ScalarT dtheta = theta1() - theta2(); - P1() -= ( g + 0.5*G_)*V1()*V1() + V1()*V2()*(-g*cos(dtheta) - b*sin(dtheta)); - Q1() -= (-b - 0.5*B_)*V1()*V1() + V1()*V2()*(-g*sin(dtheta) + b*cos(dtheta)); - P2() -= ( g + 0.5*G_)*V2()*V2() + V1()*V2()*(-g*cos(dtheta) + b*sin(dtheta)); - Q2() -= (-b - 0.5*B_)*V2()*V2() + V1()*V2()*( g*sin(dtheta) + b*cos(dtheta)); + Ir1() += -(g + 0.5*G_)*Vr1() + (b + 0.5*B_)*Vi1() + g*Vr2() - b*Vi2(); + Ii1() += -(b + 0.5*B_)*Vr1() - (g + 0.5*G_)*Vi1() + b*Vr2() + g*Vi2(); + Ir2() += g*Vr1() - b*Vi1() - (g + 0.5*G_)*Vr2() + (b + 0.5*B_)*Vi2(); + Ii2() += b*Vr1() + g*Vi1() - (b + 0.5*B_)*Vr2() - (g + 0.5*G_)*Vi2(); return 0; } diff --git a/ComponentLib/PhasorDynamics/Branch/Branch.hpp b/ComponentLib/PhasorDynamics/Branch/Branch.hpp index 0aca748..e8aa3df 100644 --- a/ComponentLib/PhasorDynamics/Branch/Branch.hpp +++ b/ComponentLib/PhasorDynamics/Branch/Branch.hpp @@ -153,44 +153,44 @@ namespace PhasorDynamics } private: - ScalarT& V1() + ScalarT& Vr1() { - return bus1_->V(); + return bus1_->Vr(); } - ScalarT& theta1() + ScalarT& Vi1() { - return bus1_->theta(); + return bus1_->Vi(); } - ScalarT& P1() + ScalarT& Ir1() { - return bus1_->P(); + return bus1_->Ir(); } - ScalarT& Q1() + ScalarT& Ii1() { - return bus1_->Q(); + return bus1_->Ii(); } - ScalarT& V2() + ScalarT& Vr2() { - return bus2_->V(); + return bus2_->Vr(); } - ScalarT& theta2() + ScalarT& Vi2() { - return bus2_->theta(); + return bus2_->Vi(); } - ScalarT& P2() + ScalarT& Ir2() { - return bus2_->P(); + return bus2_->Ir(); } - ScalarT& Q2() + ScalarT& Ii2() { - return bus2_->Q(); + return bus2_->Ii(); } private: @@ -198,8 +198,8 @@ namespace PhasorDynamics real_type X_; real_type G_; real_type B_; - const IdxT fbusID_; - const IdxT tbusID_; + const IdxT bus1ID_; + const IdxT bus2ID_; bus_type* bus1_; bus_type* bus2_; }; diff --git a/ComponentLib/PhasorDynamics/Branch/CMakeLists.txt b/ComponentLib/PhasorDynamics/Branch/CMakeLists.txt index bd4ff42..ba05a10 100644 --- a/ComponentLib/PhasorDynamics/Branch/CMakeLists.txt +++ b/ComponentLib/PhasorDynamics/Branch/CMakeLists.txt @@ -58,11 +58,11 @@ # [[ # Author(s): # - Cameron Rutherford -#]] +# ]] -gridkit_add_library(branch +gridkit_add_library(phasor_dynamics_branch SOURCES Branch.cpp OUTPUT_NAME - gridkit_branch) + gridkit_phasor_dynamics_branch) diff --git a/ComponentLib/PhasorDynamics/Branch/README.md b/ComponentLib/PhasorDynamics/Branch/README.md index ed8724b..364bb6a 100644 --- a/ComponentLib/PhasorDynamics/Branch/README.md +++ b/ComponentLib/PhasorDynamics/Branch/README.md @@ -1,114 +1,102 @@ # Branch Model -Transmission lines and different types of transformers (traditional, Load Tap-Changing transformers (LTC) and Phase Angle Regulators (PARs)) can be modeled with a common branch model. +Transmission lines and different types of transformers (traditional, Load +Tap-Changing transformers (LTC) and Phase Angle Regulators (PARs)) can be +modeled with a common branch model. ## Transmission Line Model -The most common circuit that is used to represent the transmission line model is $`\pi`$ circuit as shown in Figure 1. The nominal flow direction is from sending bus _s_ to receiving bus _r_. +The most common circuit that is used to represent the transmission line model +is $`\pi`$ circuit as shown in Figure 1. The positive flow direction is into +buses. Commonly used convention is to define positive direction to be from +sending to receiving bus. We decide to use this symmetric convention because it +provides more flexibility for modeling.
- - - + + Figure 1: Transmission line $`\pi`$ equivalent circuit
Here ``` math -Z'=R+jX +Z = R + jX ``` and ``` math -Y'=G+jB, +Y = G + jB, ``` -where $`R`$ is line series resistance, $`X`$ is line series reactance, $`B`$ is line shunt charging, and $`G`$ is line shunt conductance. As can be seen from Figure 1 total $`B`$ and $`G`$ are separated between two buses. -The current leaving the sending bus can be obtained from Kirchhoff's current law as +where $`R`$ is line series resistance, $`X`$ is line series reactance, $`B`$ is +line shunt charging, and $`G`$ is line shunt conductance. As can be seen from +Figure 1 total $`B`$ and $`G`$ are separated between two buses. The current +entering bus 1 can be obtained from Kirchhoff's current law as ```math -I_s = y(V_s - V_r) + \frac{Y'}{2} V_s, +I_1 = y(V_2 - V_1) - \frac{Y}{2} V_1, ``` -where $`V_s`$ and $`V_r`$ are voltages on sending and receiving bus, respectively, and +where $`V_1`$ and $`V_2`$ are respective bus voltages and ```math -y = \frac{1}{Z'} = \frac{R}{R^2+X^2} + j\frac{-X}{R^2+X^2} = g + jb. +y = \frac{1}{Z} = \frac{R}{R^2+X^2} + j\frac{-X}{R^2+X^2} = g + jb. ``` -Similarly, current leaving receiving bus is given as +Similarly, current entering bus 2 is given as ```math --I_R = y(V_r - V_s) + \frac{Y'}{2} V_r. +I_2 = y(V_1 - V_2) + \frac{Y}{2} V_2. ``` These equations can be written in a compact form as: ```math \begin{bmatrix} -I_{s}\\ --I_{r} +I_{1}\\ +I_{2} \end{bmatrix} -= \mathbf{Y}_{TL} += \mathbf{Y} \begin{bmatrix} -V_{s}\\ -V_{r} +V_{1}\\ +V_{2} \end{bmatrix} ``` where: ```math \mathbf{Y}_{TL}=\begin{bmatrix} - g + jb + \dfrac{G+jB}{2} & -(g + jb) \\ --(g + jb) & g + jb + \dfrac{G+jB}{2} +-(g + jb) - \dfrac{G+jB}{2} & g + jb \\ + g + jb & -(g + jb) - \dfrac{G+jB}{2} \end{bmatrix} ``` -### Branch contributions to residuals for sending and receiving bus +### Branch contributions to residuals at adjacent buses -Complex power leaving sending and receiving bus is computed as -```math -\begin{bmatrix} -S_{s}\\ -S_{r} -\end{bmatrix} -= -\begin{bmatrix} -V_{s}\\ -V_{r} -\end{bmatrix} -\begin{bmatrix} -I_{s}\\ --I_{r} -\end{bmatrix}^* -= -\begin{bmatrix} -V_{s}\\ -V_{r} -\end{bmatrix} -\mathbf{Y}_{TL}^* -\begin{bmatrix} -V_{s}\\ -V_{r} -\end{bmatrix}^* -``` -After some algebra, one obtains expressions for active and reactive power that the branch takes from adjacent buses: +After some algebra, one obtains expressions for real and imaginary components +for the currents entering adjacent buses: ```math -P_{s} = \left(g + \frac{G}{2}\right) |V_{s}|^2 + [-g \cos(\theta_s - \theta_r) - b \sin(\theta_s - \theta_r)] |V_{s}| |V_{r}| +I_{r1} = -\left(g + \frac{G}{2}\right) V_{r1} + \left(b + \frac{B}{2} \right) V_{i1} + + g V_{r2} - b V_{i2} ``` ```math -Q_{s} = -\left(b + \frac{B}{2}\right) |V_{s}|^2 + [-g \sin(\theta_s - \theta_r) + b \cos(\theta_s - \theta_r)] |V_{s}| |V_{r}| +I_{i1} = -\left(b + \frac{B}{2} \right) V_{r1} - \left(g + \frac{G}{2}\right) V_{i1} + + b V_{r2} + g V_{i2} ``` ```math -P_{r} = \left(g + \frac{G}{2}\right) |V_{r}|^2 + [-g \cos(\theta_s - \theta_r) + b \sin(\theta_s - \theta_r)] |V_{s}| |V_{r}| +I_{r2} = g V_{r1} - b V_{i1} + - \left(g + \frac{G}{2}\right) V_{r2} + \left(b + \frac{B}{2} \right) V_{i2} ``` ```math -Q_{r} = -\left(b + \frac{B}{2}\right) |V_{r}|^2 + [ g \sin(\theta_s - \theta_r) + b \cos(\theta_s - \theta_r)] |V_{s}| |V_{r}| +I_{i1} = b V_{r1} + g V_{i1} + - \left(b + \frac{B}{2} \right) V_{r2} - \left(g + \frac{G}{2}\right) V_{i2} ``` -These quantities are treated as _loads_ and are substracted from $`P`$ and $`Q`$ residuals computed on the respective buses. -## Branch Model +## Transformer Branch Model **Note: Transformer model not yet implemented** -The branch model can be created by adding the ideal transformer in series with the $`\pi`$ circuit as shown in Figure 2 where $`\tau`$ is a tap ratio magnitude and $`\theta_{shift}`$is the phase shift angle. +The branch model can be created by adding the ideal transformer in series with +the $`\pi`$ circuit as shown in Figure 2 where $`\tau`$ is a tap ratio +magnitude and $`\theta`$ is the phase shift angle and +$`N = \tau e^{j \theta}`$.
- + Figure 2: Branch equivalent circuit @@ -120,11 +108,13 @@ The branch admitance matrix is then: ```math \mathbf{Y}_{BR}= \begin{bmatrix} - \left(g + jb + \dfrac{G+jB}{2} \right)\dfrac{1}{\tau^2} & -(g + jb)\dfrac{1}{\tau e^{-j\theta_{shift}}}\\ - &\\ - -(g + jb)\dfrac{1}{\tau e^{j\theta_{shift}}}. & g + jb + \dfrac{G+jB}{2} + -\left(g + jb + \dfrac{G+jB}{2} \right) \dfrac{1}{\tau^2} & (g + jb)\dfrac{1}{\tau e^{-j\theta}}\\ + & \\ + (g + jb)\dfrac{1}{\tau e^{j\theta}} & -\left(g + jb + \dfrac{G+jB}{2}\right) \end{bmatrix} ``` -### Branch contribution to residuals for sending and receiving bus -The power flow contribution for the transformer model are obtained in a similar manner as for the $`\pi`$-model. +### Branch contribution to residuals at adjacent busses + +The currents entering adjacent buses are obtained in a similar manner as for +the $`\pi`$-model. diff --git a/ComponentLib/PhasorDynamics/Bus/Bus.hpp b/ComponentLib/PhasorDynamics/Bus/Bus.hpp index a5b808b..b68e387 100644 --- a/ComponentLib/PhasorDynamics/Bus/Bus.hpp +++ b/ComponentLib/PhasorDynamics/Bus/Bus.hpp @@ -112,82 +112,82 @@ namespace PhasorDynamics virtual int initializeAdjoint(); virtual int evaluateAdjointResidual(); - virtual ScalarT& Va() + virtual ScalarT& Vr() { return y_[0]; } - virtual const ScalarT& Va() const + virtual const ScalarT& Vr() const { return y_[0]; } - virtual ScalarT& Vr() + virtual ScalarT& Vi() { return y_[1]; } - virtual const ScalarT& Vr() const + virtual const ScalarT& Vi() const { return y_[1]; } - virtual ScalarT& Ia() + virtual ScalarT& Ir() { return f_[0]; } - virtual const ScalarT& Ia() const + virtual const ScalarT& Ir() const { return f_[0]; } - virtual ScalarT& Ir() + virtual ScalarT& Ii() { return f_[1]; } - virtual const ScalarT& Ir() const + virtual const ScalarT& Ii() const { return f_[1]; } - virtual ScalarT& lambdaIa() + virtual ScalarT& lambdaIr() { return yB_[0]; } - virtual const ScalarT& lambdaIa() const + virtual const ScalarT& lambdaIr() const { return yB_[0]; } - virtual ScalarT& lambdaIr() + virtual ScalarT& lambdaIi() { return yB_[1]; } - virtual const ScalarT& lambdaIr() const + virtual const ScalarT& lambdaIi() const { return yB_[1]; } - virtual ScalarT& IaB() + virtual ScalarT& IrB() { return fB_[0]; } - virtual const ScalarT& IaB() const + virtual const ScalarT& IrB() const { return fB_[0]; } - virtual ScalarT& IrB() + virtual ScalarT& IiB() { return fB_[1]; } - virtual const ScalarT& IrB() const + virtual const ScalarT& IiB() const { return fB_[1]; } diff --git a/ComponentLib/PhasorDynamics/CMakeLists.txt b/ComponentLib/PhasorDynamics/CMakeLists.txt index 45c9350..d882331 100644 --- a/ComponentLib/PhasorDynamics/CMakeLists.txt +++ b/ComponentLib/PhasorDynamics/CMakeLists.txt @@ -60,4 +60,5 @@ # - Cameron Rutherford #]] +add_subdirectory(Branch) add_subdirectory(Bus) diff --git a/Documentation/Figures/branch_phasor_dynamics.png b/Documentation/Figures/branch_phasor_dynamics.png new file mode 100644 index 0000000000000000000000000000000000000000..2d13c9ab23f5876c35d8a62e656c479e0ad1b7dc GIT binary patch literal 6146 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

%t~)R<&9u?cf!h8{CDi# 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 Date: Mon, 13 Jan 2025 14:38:36 -0500 Subject: [PATCH 5/6] Corrected docs and notation to real and imaginary voltage/current. --- ComponentLib/PhasorDynamics/Bus/Bus.cpp | 12 ++++++------ ComponentLib/PhasorDynamics/Bus/Bus.hpp | 4 ++-- ComponentLib/PhasorDynamics/Bus/README.md | 13 +++++++------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/ComponentLib/PhasorDynamics/Bus/Bus.cpp b/ComponentLib/PhasorDynamics/Bus/Bus.cpp index bdb7224..e7e4e14 100644 --- a/ComponentLib/PhasorDynamics/Bus/Bus.cpp +++ b/ComponentLib/PhasorDynamics/Bus/Bus.cpp @@ -81,7 +81,7 @@ namespace PhasorDynamics */ template Bus::Bus() - : Va0_(0.0), Vr0_(0.0) + : Vr0_(0.0), Vi0_(0.0) { //std::cout << "Create Bus..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; @@ -101,8 +101,8 @@ Bus::Bus() * - Number of optimization parameters = 0 */ template -Bus::Bus(ScalarT Va, ScalarT Vr) - : Va0_(Va), Vr0_(Vr) +Bus::Bus(ScalarT Vr, ScalarT Vi) + : Vr0_(Vr), Vi0_(Vi) { //std::cout << "Create Bus..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; @@ -119,7 +119,7 @@ Bus::Bus(ScalarT Va, ScalarT Vr) */ template Bus::Bus(BusData& data) - : Va0_(data.Vm * cos(data.Va)), Vr0_(data.Vm * sin(data.Va)) + : Vr0_(data.Vm * cos(data.Va)), Vi0_(data.Vm * sin(data.Va)) { //std::cout << "Create Bus..." << std::endl; //std::cout << "Number of equations is " << size_ << std::endl; @@ -169,8 +169,8 @@ template int Bus::initialize() { // std::cout << "Initialize Bus..." << std::endl; - y_[0] = Va0_; - y_[1] = Vr0_; + y_[0] = Vr0_; + y_[1] = Vi0_; yp_[0] = 0.0; yp_[1] = 0.0; diff --git a/ComponentLib/PhasorDynamics/Bus/Bus.hpp b/ComponentLib/PhasorDynamics/Bus/Bus.hpp index b68e387..f3a9e5c 100644 --- a/ComponentLib/PhasorDynamics/Bus/Bus.hpp +++ b/ComponentLib/PhasorDynamics/Bus/Bus.hpp @@ -101,7 +101,7 @@ namespace PhasorDynamics using BusData = GridKit::PowerSystemData::BusData; Bus(); - Bus(ScalarT Va, ScalarT Vr); + Bus(ScalarT Vr, ScalarT Vi); Bus(BusData& data); virtual ~Bus(); @@ -199,8 +199,8 @@ namespace PhasorDynamics private: // Default initial values for voltage and phase on PQ bus - ScalarT Va0_{0.0}; ScalarT Vr0_{0.0}; + ScalarT Vi0_{0.0}; }; diff --git a/ComponentLib/PhasorDynamics/Bus/README.md b/ComponentLib/PhasorDynamics/Bus/README.md index d000f08..4a9df7d 100644 --- a/ComponentLib/PhasorDynamics/Bus/README.md +++ b/ComponentLib/PhasorDynamics/Bus/README.md @@ -1,12 +1,12 @@ # Bus Model A bus is a point of interconnection of electrical devices. Bus component model -also plays a key role in coupling system components. Each bus $`i`$ owns two -variables -- active and reactive voltage $`V_{ai}`$ and $`V_{ri}`$, -respectively. The bus also owns current balance residual equations for active -and reactive currents coming into the bus $`I_{ai}`$ and $`I_{ri}`$, +also plays a key role in coupling system components. Each bus $`k`$ owns two +variables -- real and imaginary voltage $`V_{rk}`$ and $`V_{ik}`$, +respectively. The bus also owns current balance residual equations for real +and imaginary currents coming into the bus $`I_{rk}`$ and $`I_{ik}`$, respectively. While th bus model owns current residuals, it _does not compute_ -them. Instead each component connected to the bus is adding its contribution +them. Instead, each component connected to the bus is adding its contribution to the residual. The bus will merely initialize the residual to zero each time numerical integrator requests residual evaluation. @@ -26,4 +26,5 @@ sign. **Other Parameters** -Buses are uniquely defined by their ID (number or name). Besides, each bus should have associated Nominal Voltage value. \ No newline at end of file +Buses are uniquely defined by their ID (number or name). Besides, each bus +should have associated Nominal Voltage value. \ No newline at end of file From a6986b7227547b54ab22d888e601895c5b6f094e Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Mon, 13 Jan 2025 16:04:40 -0500 Subject: [PATCH 6/6] Fix broken links to figures in README files. --- ComponentLib/PowerFlow/Branch/README.md | 4 ++-- ComponentLib/PowerFlow/Bus/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ComponentLib/PowerFlow/Branch/README.md b/ComponentLib/PowerFlow/Branch/README.md index ecfc61a..ed8724b 100644 --- a/ComponentLib/PowerFlow/Branch/README.md +++ b/ComponentLib/PowerFlow/Branch/README.md @@ -7,7 +7,7 @@ Transmission lines and different types of transformers (traditional, Load Tap-Ch The most common circuit that is used to represent the transmission line model is $`\pi`$ circuit as shown in Figure 1. The nominal flow direction is from sending bus _s_ to receiving bus _r_.

- + Figure 1: Transmission line $`\pi`$ equivalent circuit @@ -108,7 +108,7 @@ These quantities are treated as _loads_ and are substracted from $`P`$ and $`Q`$ The branch model can be created by adding the ideal transformer in series with the $`\pi`$ circuit as shown in Figure 2 where $`\tau`$ is a tap ratio magnitude and $`\theta_{shift}`$is the phase shift angle.
- + Figure 2: Branch equivalent circuit diff --git a/ComponentLib/PowerFlow/Bus/README.md b/ComponentLib/PowerFlow/Bus/README.md index 0e48e51..9daf786 100644 --- a/ComponentLib/PowerFlow/Bus/README.md +++ b/ComponentLib/PowerFlow/Bus/README.md @@ -28,7 +28,7 @@ There exist two:
- + Figure 1: Sign convention for the power flow at the bus $`i`$