Skip to content

Add component data structures #133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 10, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 80 additions & 43 deletions examples/PhasorDynamics/Example1/example1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@
#include <iostream>

#include <Model/PhasorDynamics/Branch/Branch.hpp>
#include <Model/PhasorDynamics/Branch/BranchData.hpp>
#include <Model/PhasorDynamics/Bus/Bus.hpp>
#include <Model/PhasorDynamics/Bus/BusData.hpp>
#include <Model/PhasorDynamics/Bus/BusInfinite.hpp>
#include <Model/PhasorDynamics/BusFault/BusFault.hpp>
#include <Model/PhasorDynamics/BusFault/BusFaultData.hpp>
#include <Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp>
#include <Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouData.hpp>
#include <Model/PhasorDynamics/SystemModel.hpp>
#include <Solver/Dynamic/Ida.hpp>
#include <Utilities/Testing.hpp>
Expand All @@ -27,45 +31,78 @@ int main()
using namespace GridKit::PhasorDynamics;
using namespace AnalysisManager::Sundials;

using scalar_type = double;
using real_type = double;
using index_type = size_t;

std::cout << "Example 1 version 2\n";

/* Create model parts */
SystemModel<double, size_t> sys;
Bus<double, size_t> bus1(0.9949877346411762, 0.09999703952427966);
BusInfinite<double, size_t> bus2(1.0, 0.0);
Branch<double, size_t> branch(&bus1, &bus2, 0, 0.1, 0, 0);
BusFault<double, size_t> fault(&bus1, 0, 1e-3, 0);

Genrou<double, size_t> gen(&bus1,
1,
1.,
0.05013,
3.,
0.,
0.,
7.,
.04,
.05,
.75,
2.1,
0.2,
0.18,
0.5,
0.5,
0.18,
0.15,
0.,
0.);

/* Connect everything together */
//
// Create model data
//
BusData<real_type, index_type> bus_data_1;
bus_data_1.Vr0 = 0.9949877346411762;
bus_data_1.Vi0 = 0.09999703952427966;

BusData<real_type, index_type> bus_data_2;
bus_data_2.Vr0 = 1.0;
bus_data_2.Vi0 = 0.0;

BranchData<real_type, index_type> branch_data_1_2;
branch_data_1_2.R = 0.0;
branch_data_1_2.X = 0.1;
branch_data_1_2.G = 0.0;
branch_data_1_2.B = 0.0;

GenrouData<real_type, index_type> gen_data_1;
gen_data_1.unit_id = 1;
gen_data_1.p0 = 1.;
gen_data_1.q0 = 0.05013;
gen_data_1.H = 3.;
gen_data_1.D = 0.;
gen_data_1.Ra = 0.;
gen_data_1.Tdop = 7.;
gen_data_1.Tdopp = .04;
gen_data_1.Tqopp = .05;
gen_data_1.Tqop = .75;
gen_data_1.Xd = 2.1;
gen_data_1.Xdp = 0.2;
gen_data_1.Xdpp = 0.18;
gen_data_1.Xq = 0.5;
gen_data_1.Xqp = 0.5;
gen_data_1.Xqpp = 0.18;
gen_data_1.Xl = 0.15;
gen_data_1.S10 = 0.;
gen_data_1.S12 = 0.;

BusFaultData<real_type, index_type> bus_fault_data_1;
bus_fault_data_1.R = 0.0;
bus_fault_data_1.X = 1e-3;
bus_fault_data_1.status = 0;

//
// Instantiate model components
//

Bus<scalar_type, size_t> bus1(bus_data_1);
BusInfinite<scalar_type, size_t> bus2(bus_data_2);
Branch<scalar_type, size_t> branch(&bus1, &bus2, branch_data_1_2);
BusFault<scalar_type, size_t> fault(&bus1, bus_fault_data_1);
Genrou<scalar_type, size_t> gen(&bus1, gen_data_1);

//
// Create the 2-bus system
//

SystemModel<scalar_type, size_t> sys;
sys.addBus(&bus1);
sys.addBus(&bus2);
sys.addComponent(&branch);
sys.addComponent(&fault);
sys.addComponent(&gen);
sys.allocate();

double dt = 1.0 / 4.0 / 60.0;
real_type dt = 1.0 / 4.0 / 60.0;

// A data structure to keep track of the data we want to
// compare to the reference solution. Rather than keeping
Expand All @@ -77,7 +114,7 @@ int main()
// (plain ol' data), which have some benefits in C++.
struct OutputData
{
double ti, Vr, Vi, dw;
real_type ti, Vr, Vi, dw;
};

// A list of output for each time step.
Expand All @@ -93,19 +130,19 @@ int main()
// reference to that variable inside the callback). We select
// the subset of the output we're interested in recording and
// push it into output, which is updated outside the callback.
auto output_cb = [&](double t)
auto output_cb = [&](real_type t)
{
std::vector<double>& yval = sys.y();
std::vector<scalar_type>& yval = sys.y();

output.push_back(OutputData{t, yval[0], yval[1], yval[3]});
};

// Set up simulation
Ida<double, size_t> ida(&sys);
Ida<scalar_type, size_t> ida(&sys);
ida.configureSimulation();

// Run simulation - making sure to pass the callback to record output
double start = static_cast<double>(clock());
real_type start = static_cast<real_type>(clock());

// Run for 1s
ida.initializeSimulation(0.0, false);
Expand All @@ -123,20 +160,20 @@ int main()
ida.initializeSimulation(1.1, false);
nout = static_cast<int>(std::round((10.0 - 1.1) / dt));
ida.runSimulation(10.0, nout, output_cb);
double stop = static_cast<double>(clock());
real_type stop = static_cast<real_type>(clock());

double error_V = 0.0; // error in |V|
double error_w = 0.0; // error in rotor speed
real_type error_V = 0.0; // error in |V|
real_type error_w = 0.0; // error in rotor speed

// Read through the simulation data stored in the buffer.
// Since we captured by reference, output should be available
// for us to read here, outside the callback.
for (size_t i = 0; i < output.size(); i++)
{
OutputData data = output[i];
std::vector<double>& ref_sol = Example1::reference_solution[i + 1];
OutputData data = output[i];
std::vector<real_type>& ref_sol = Example1::reference_solution[i + 1];

double err =
real_type err =
std::abs(std::sqrt(data.Vr * data.Vr + data.Vi * data.Vi) - ref_sol[2])
/ (1.0 + std::abs(ref_sol[2]));
if (err > error_V)
Expand All @@ -160,8 +197,8 @@ int main()
// std::cout << "\n";
}

double error_V_allowed = 2e-4;
double error_w_allowed = 1e-4;
real_type error_V_allowed = 2e-4;
real_type error_w_allowed = 1e-4;

// Tolerances based on Powerworld reference accuracy
int status = 0;
Expand Down
129 changes: 117 additions & 12 deletions examples/PhasorDynamics/Example2/example2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@
#include <vector>

#include <Model/PhasorDynamics/Branch/Branch.hpp>
#include <Model/PhasorDynamics/Branch/BranchData.hpp>
#include <Model/PhasorDynamics/Bus/Bus.hpp>
#include <Model/PhasorDynamics/Bus/BusData.hpp>
#include <Model/PhasorDynamics/Bus/BusInfinite.hpp>
#include <Model/PhasorDynamics/BusFault/BusFault.hpp>
#include <Model/PhasorDynamics/BusFault/BusFaultData.hpp>
#include <Model/PhasorDynamics/Load/Load.hpp>
#include <Model/PhasorDynamics/Load/LoadData.hpp>
#include <Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp>
#include <Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouData.hpp>
#include <Model/PhasorDynamics/SystemModel.hpp>
#include <Solver/Dynamic/Ida.hpp>
#include <Utilities/Testing.hpp>
Expand Down Expand Up @@ -82,20 +87,120 @@ int main()

std::cout << "Example 2 version 1\n";

/* Create model parts */
SystemModel<scalar_type, index_type> sys;
BusInfinite<scalar_type, index_type> bus1(1.06, 0.0);
Bus<scalar_type, index_type> bus2(1.0599558398065716, -0.009675621941024773);
Bus<scalar_type, index_type> bus3(0.9610827543495831, -0.13122476630506485);
Branch<scalar_type, index_type> branch12(&bus1, &bus2, 0.05, 0.21, 0, 0.1);
Branch<scalar_type, index_type> branch13(&bus1, &bus3, 0.06, 0.15, 0, 0.12);
Branch<scalar_type, index_type> branch23(&bus2, &bus3, 0.08, 0.27, 0, 0.45);
Genrou<scalar_type, index_type> gen2(&bus2, 1, 0.5, -0.07588, 2.7, 0., 0., 7., .04, .05, .75, 1.9, 0.17, 0.15, 0.4, 0.35, 0.15, 0.14999, 0., 0.);
Genrou<scalar_type, index_type> gen3(&bus3, 1, 0.25, 0.26587, 1.6, 0., 0., 7.5, .04, .05, .75, 2.3, 0.2, 0.18, 0.5, 0.5, 0.18, 0.15, 0., 0.);
Load<scalar_type, index_type> load3(&bus3, 0.4447197839297772, 0.20330047265361242);
BusFault<scalar_type, index_type> fault(&bus3, 0, 1e-5, 0);
//
// Create (load) model data
//

// Bus 1
BusData<real_type, index_type> bus_data_1;
bus_data_1.Vr0 = 1.06;
bus_data_1.Vi0 = 0.0;

// Bus 2
BusData<real_type, index_type> bus_data_2;
bus_data_2.Vr0 = 1.0599558398065716;
bus_data_2.Vi0 = -0.009675621941024773;

// Bus 3
BusData<real_type, index_type> bus_data_3;
bus_data_3.Vr0 = 0.9610827543495831;
bus_data_3.Vi0 = -0.13122476630506485;

// Branch 1-2
BranchData<real_type, index_type> branch_data_1_2;
branch_data_1_2.R = 0.05;
branch_data_1_2.X = 0.21;
branch_data_1_2.G = 0;
branch_data_1_2.B = 0.1;

// Branch 1-3
BranchData<real_type, index_type> branch_data_1_3;
branch_data_1_3.R = 0.06;
branch_data_1_3.X = 0.15;
branch_data_1_3.G = 0;
branch_data_1_3.B = 0.12;

// Branch 2-3
BranchData<real_type, index_type> branch_data_2_3;
branch_data_2_3.R = 0.08;
branch_data_2_3.X = 0.27;
branch_data_2_3.G = 0;
branch_data_2_3.B = 0.45;

// Generator on bus 2
GenrouData<real_type, index_type> gen_data_2;
gen_data_2.unit_id = 1;
gen_data_2.p0 = 0.5;
gen_data_2.q0 = -0.07588;
gen_data_2.H = 2.7;
gen_data_2.D = 0.;
gen_data_2.Ra = 0.;
gen_data_2.Tdop = 7.;
gen_data_2.Tdopp = .04;
gen_data_2.Tqopp = .05;
gen_data_2.Tqop = .75;
gen_data_2.Xd = 1.9;
gen_data_2.Xdp = 0.17;
gen_data_2.Xdpp = 0.15;
gen_data_2.Xq = 0.4;
gen_data_2.Xqp = 0.35;
gen_data_2.Xqpp = 0.15;
gen_data_2.Xl = 0.14999;
gen_data_2.S10 = 0.;
gen_data_2.S12 = 0.;

// Generator on bus 3
GenrouData<real_type, index_type> gen_data_3;
gen_data_3.unit_id = 1;
gen_data_3.p0 = 0.25;
gen_data_3.q0 = 0.26587;
gen_data_3.H = 1.6;
gen_data_3.D = 0.;
gen_data_3.Ra = 0.;
gen_data_3.Tdop = 7.5;
gen_data_3.Tdopp = .04;
gen_data_3.Tqopp = .05;
gen_data_3.Tqop = .75;
gen_data_3.Xd = 2.3;
gen_data_3.Xdp = 0.2;
gen_data_3.Xdpp = 0.18;
gen_data_3.Xq = 0.5;
gen_data_3.Xqp = 0.5;
gen_data_3.Xqpp = 0.18;
gen_data_3.Xl = 0.15;
gen_data_3.S10 = 0.;
gen_data_3.S12 = 0.;

// Load on bus 3
LoadData<real_type, index_type> load_data_3;
load_data_3.R = 0.4447197839297772;
load_data_3.X = 0.20330047265361242;
load_data_3.bus_id = 3;

BusFaultData<real_type, index_type> bus_fault_data_3;
bus_fault_data_3.R = 0.0;
bus_fault_data_3.X = 1e-5;
bus_fault_data_3.status = 0;

//
// Instantiate model components
//

BusInfinite<scalar_type, index_type> bus1(bus_data_1);
Bus<scalar_type, index_type> bus2(bus_data_2);
Bus<scalar_type, index_type> bus3(bus_data_3);

Branch<scalar_type, index_type> branch12(&bus1, &bus2, branch_data_1_2);
Branch<scalar_type, index_type> branch13(&bus1, &bus3, branch_data_1_3);
Branch<scalar_type, index_type> branch23(&bus2, &bus3, branch_data_2_3);

Genrou<scalar_type, index_type> gen2(&bus2, gen_data_2);
Genrou<scalar_type, index_type> gen3(&bus3, gen_data_3);
Load<scalar_type, index_type> load3(&bus3, load_data_3);
BusFault<scalar_type, index_type> fault(&bus3, bus_fault_data_3);

/* Connect everything together */
SystemModel<scalar_type, index_type> sys;
sys.addBus(&bus1);
sys.addBus(&bus2);
sys.addBus(&bus3);
Expand Down
20 changes: 20 additions & 0 deletions src/Model/PhasorDynamics/BusFault/BusFault.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <iostream>

#include <Model/PhasorDynamics/Bus/Bus.hpp>
#include <Model/PhasorDynamics/BusFault/BusFaultData.hpp>

namespace GridKit
{
Expand Down Expand Up @@ -54,6 +55,25 @@ namespace GridKit
size_ = 0;
}

/**
* @brief Construct a new BusFault
*
* @tparam ScalarT - scalar type
* @tparam IdxT - matrix/vector index type
* @param bus1 - pointer to bus-1
* @param bus2 - pointer to bus-2
*/
template <class ScalarT, typename IdxT>
BusFault<ScalarT, IdxT>::BusFault(bus_type* bus, DataT& data)
: bus_(bus),
R_(data.R),
X_(data.X),
status_(data.status),
busID_(data.bus_id)
{
size_ = 0;
}

/*!
* @brief allocate method computes sparsity pattern of the Jacobian.
*/
Expand Down
Loading