Skip to content

Commit cb12683

Browse files
peleshabirchfield
andauthored
Unit test and example for Genrou class. (#85)
* Unit test for Genrou residual * Working 3-bus example, bug in Load * Fix linking of Genrou examples. * Accounted for load bug in docs and test * Clean up example 1. * Minimal documentation for tests and examples. --------- Co-authored-by: abirchfield <[email protected]> Co-authored-by: pelesh <[email protected]> Co-authored-by: abirchfield <[email protected]>
1 parent 77c973e commit cb12683

File tree

21 files changed

+2665
-46
lines changed

21 files changed

+2665
-46
lines changed

examples/DistributedGeneratorTest/DGTest.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
2+
#define _USE_MATH_DEFINES
33
#include <cmath>
44
#include <filesystem>
55
#include <fstream>

examples/Grid3Bus/Grid3BusSys.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*
1010
*/
1111

12+
#define _USE_MATH_DEFINES
1213
#include <cmath>
1314
#include <filesystem>
1415
#include <fstream>

examples/Microgrid/Microgrid.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22

3+
#define _USE_MATH_DEFINES
34
#include <cmath>
45
#include <filesystem>
56
#include <fstream>
+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
add_subdirectory(Example1)
2+
add_subdirectory(Example2)

examples/PhasorDynamics/Example1/CMakeLists.txt

+2-6
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ target_link_libraries(phasordynamics_example1
44
GRIDKIT::phasor_dynamics_bus_fault
55
GRIDKIT::phasor_dynamics_branch
66
GRIDKIT::phasor_dynamics_genrou
7-
SUNDIALS::sunlinsolklu
8-
SUNDIALS::core
9-
SUNDIALS::ida
10-
SUNDIALS::idas
11-
SUNDIALS::sunmatrixdense)
7+
GRIDKIT::solvers_dyn)
128
install(TARGETS phasordynamics_example1 RUNTIME DESTINATION bin)
139

14-
add_test(NAME GenrouTest COMMAND $<TARGET_FILE:phasordynamics_example1>)
10+
add_test(NAME GenrouTest1 COMMAND $<TARGET_FILE:phasordynamics_example1>)

examples/PhasorDynamics/Example1/example1.cpp

+24-32
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,33 @@
1-
#include <stdio.h>
2-
#define _USE_MATH_DEFINES
3-
#include <math.h>
4-
#include <time.h>
5-
6-
// #include <sundials_core.h>
7-
#include <idas/idas.h>
8-
#include <nvector/nvector_serial.h>
9-
#include <sunlinsol/sunlinsol_dense.h>
10-
#include <sunlinsol/sunlinsol_klu.h>
11-
#include <sunmatrix/sunmatrix_sparse.h>
12-
13-
#include "Example1_Powerworld_Reference.hpp"
14-
#include "Model/PhasorDynamics/Branch/Branch.cpp"
15-
#include "Model/PhasorDynamics/Branch/Branch.hpp"
16-
#include "Model/PhasorDynamics/Bus/Bus.cpp"
17-
#include "Model/PhasorDynamics/Bus/Bus.hpp"
18-
#include "Model/PhasorDynamics/Bus/BusInfinite.cpp"
19-
#include "Model/PhasorDynamics/Bus/BusInfinite.hpp"
20-
#include "Model/PhasorDynamics/BusFault/BusFault.hpp"
21-
#include "Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp"
22-
#include "Model/PhasorDynamics/SystemModel.hpp"
23-
#include "Solver/Dynamic/Ida.cpp"
24-
#include "Solver/Dynamic/Ida.hpp"
1+
/**
2+
* @file example1.cpp
3+
* @author Adam Birchfield ([email protected])
4+
* @author Slaven Peles ([email protected])
5+
* @brief Example running a 2-bus system
6+
*
7+
* Simulates a 2-bus system with Genrou 6th order generator model and
8+
* compares results with data generated for the same system by Poweworld.
9+
*
10+
*/
11+
#include "example1.hpp"
12+
13+
#include <ctime>
14+
#include <iostream>
15+
16+
#include <Model/PhasorDynamics/Branch/Branch.hpp>
17+
#include <Model/PhasorDynamics/Bus/Bus.hpp>
18+
#include <Model/PhasorDynamics/Bus/BusInfinite.hpp>
19+
#include <Model/PhasorDynamics/BusFault/BusFault.hpp>
20+
#include <Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp>
21+
#include <Model/PhasorDynamics/SystemModel.hpp>
22+
#include <Solver/Dynamic/Ida.hpp>
2523
#include <Utilities/Testing.hpp>
2624

27-
#define _CRT_SECURE_NO_WARNINGS
28-
2925
int main()
3026
{
3127
using namespace GridKit::PhasorDynamics;
3228
using namespace AnalysisManager::Sundials;
3329

34-
printf("Example 1 version 2\n");
30+
std::cout << "Example 1 version 2\n";
3531

3632
/* Create model parts */
3733
SystemModel<double, size_t> sys;
@@ -115,7 +111,6 @@ int main()
115111
/ (1.0 + std::abs(reference_solution[i / 48][2]));
116112
if (err > error_V)
117113
error_V = err;
118-
// std::cout << "t = " << ti << ": Vr = " << Vr << ", Vi = " << Vi << ", dw = " << dw;
119114
std::cout << "GridKit: t = " << ti
120115
<< ", |V| = " << std::sqrt(Vr * Vr + Vi * Vi)
121116
<< ", w = " << (1.0 + dw) << "\n";
@@ -149,11 +144,8 @@ int main()
149144
}
150145
++j;
151146
++i;
152-
// if (i > 500)
153-
// break;
154147
}
155148

156-
// std::cout << buffer.str();
157149
int status = 0;
158150
std::cout << "Max error in |V| = " << error_V << "\n";
159151
if (error_V > 2e-4)
@@ -164,5 +156,5 @@ int main()
164156

165157
std::cout << "\n\nComplete in " << (stop - start) / CLOCKS_PER_SEC << " seconds\n";
166158

167-
return 0;
159+
return status;
168160
}

examples/PhasorDynamics/Example1/Example1_Powerworld_Reference.hpp renamed to examples/PhasorDynamics/Example1/example1.hpp

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
/**
2+
* @file example1.hpp
3+
* @author Adam Birchfield ([email protected])
4+
* @author Slaven Peles ([email protected])
5+
* @brief Reference solution for the 2-bus system obtained with Powerworld
6+
*
7+
*/
18
#include <vector>
29

310
// Columns:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
add_executable(phasordynamics_example2 example2.cpp)
2+
target_link_libraries(phasordynamics_example2
3+
GRIDKIT::phasor_dynamics_bus
4+
GRIDKIT::phasor_dynamics_bus_fault
5+
GRIDKIT::phasor_dynamics_branch
6+
GRIDKIT::phasor_dynamics_genrou
7+
GRIDKIT::phasor_dynamics_load
8+
GRIDKIT::solvers_dyn)
9+
install(TARGETS phasordynamics_example2 RUNTIME DESTINATION bin)
10+
11+
add_test(NAME GenrouTest2 COMMAND $<TARGET_FILE:phasordynamics_example2>)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/**
2+
* @file example2.cpp
3+
* @author Adam Birchfield ([email protected])
4+
* @author Slaven Peles ([email protected])
5+
* @brief Example running a 3-bus system
6+
*
7+
* Simulates a 3-bus system with two Genrou 6th order generator models and
8+
* compares results with data generated for the same system by Poweworld.
9+
*
10+
*/
11+
#include "example2.hpp"
12+
13+
#include <cstdio>
14+
#include <ctime>
15+
#include <fstream>
16+
#include <vector>
17+
18+
#include <Model/PhasorDynamics/Branch/Branch.hpp>
19+
#include <Model/PhasorDynamics/Bus/Bus.hpp>
20+
#include <Model/PhasorDynamics/Bus/BusInfinite.hpp>
21+
#include <Model/PhasorDynamics/BusFault/BusFault.hpp>
22+
#include <Model/PhasorDynamics/Load/Load.hpp>
23+
#include <Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp>
24+
#include <Model/PhasorDynamics/SystemModel.hpp>
25+
#include <Solver/Dynamic/Ida.hpp>
26+
#include <Utilities/Testing.hpp>
27+
28+
int main()
29+
{
30+
using namespace GridKit::PhasorDynamics;
31+
using namespace AnalysisManager::Sundials;
32+
using scalar_type = double;
33+
using real_type = double;
34+
using index_type = size_t;
35+
36+
auto error_allowed = static_cast<real_type>(1e-4);
37+
38+
std::cout << "Example 2 version 1\n";
39+
40+
/* Create model parts */
41+
SystemModel<scalar_type, index_type> sys;
42+
BusInfinite<scalar_type, index_type> bus1(1.06, 0.0);
43+
Bus<scalar_type, index_type> bus2(1.0599558398065716, -0.009675621941024773);
44+
Bus<scalar_type, index_type> bus3(0.9610827543495831, -0.13122476630506485);
45+
Branch<scalar_type, index_type> branch12(&bus1, &bus2, 0.05, 0.21, 0, 0.1);
46+
Branch<scalar_type, index_type> branch13(&bus1, &bus3, 0.06, 0.15, 0, 0.12);
47+
Branch<scalar_type, index_type> branch23(&bus2, &bus3, 0.08, 0.27, 0, 0.45);
48+
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.);
49+
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.);
50+
Load<scalar_type, index_type> load3(&bus3, 0.4447197839297772, 0.20330047265361242);
51+
BusFault<scalar_type, index_type> fault(&bus3, 0, 1e-5, 0);
52+
53+
/* Connect everything together */
54+
sys.addBus(&bus1);
55+
sys.addBus(&bus2);
56+
sys.addBus(&bus3);
57+
sys.addComponent(&branch12);
58+
sys.addComponent(&branch13);
59+
sys.addComponent(&branch23);
60+
sys.addComponent(&fault);
61+
sys.addComponent(&load3);
62+
sys.addComponent(&gen2);
63+
sys.addComponent(&gen3);
64+
sys.allocate();
65+
66+
real_type dt = 1.0 / 4.0 / 60.0;
67+
68+
std::stringstream buffer;
69+
70+
/* Set up simulation */
71+
Ida<scalar_type, index_type> ida(&sys);
72+
ida.configureSimulation();
73+
74+
/* Run simulation */
75+
scalar_type start = static_cast<scalar_type>(clock());
76+
ida.initializeSimulation(0.0, false);
77+
ida.runSimulationFixed(0.0, dt, 1.0, buffer);
78+
fault.setStatus(1);
79+
ida.initializeSimulation(1.0, false);
80+
ida.runSimulationFixed(1.0, dt, 1.1, buffer);
81+
fault.setStatus(0);
82+
ida.initializeSimulation(1.1, false);
83+
ida.runSimulationFixed(1.1, dt, 10.0, buffer);
84+
double stop = static_cast<double>(clock());
85+
86+
/* Check worst-case error */
87+
real_type worst_error = 0;
88+
real_type worst_error_time = 0;
89+
90+
const index_type stride = 94;
91+
const index_type nt = 2401;
92+
scalar_type results[stride];
93+
buffer.seekg(0, std::ios::beg);
94+
95+
std::ostream nullout(nullptr);
96+
std::ostream& out = nullout;
97+
98+
// // Uncomment code below to print output to a file:
99+
// std::ofstream fileout;
100+
// fileout.open("example2_results.csv");
101+
// std::ostream& out = fileout;
102+
103+
out << "Time,gen2speed,gen3speed,v2mag,v3mag\n";
104+
out << 0. << "," << 1. << "," << 1. << "," << 1. << "," << 1. << "\n";
105+
106+
for (index_type i = 0; i < nt - 1; ++i)
107+
{
108+
for (index_type j = 0; j < stride; ++j)
109+
{
110+
buffer >> results[j];
111+
}
112+
real_type t = results[0];
113+
scalar_type gen2speed = 1 + results[7];
114+
scalar_type gen2speed_ref = reference_solution[i + 1][1];
115+
scalar_type gen3speed = 1 + results[28];
116+
scalar_type gen3speed_ref = reference_solution[i + 1][2];
117+
scalar_type v2mag = sqrt(results[2] * results[2] + results[3] * results[3]);
118+
scalar_type v2mag_ref = reference_solution[i + 1][4];
119+
scalar_type v3mag = sqrt(results[4] * results[4] + results[5] * results[5]);
120+
scalar_type v3mag_ref = reference_solution[i + 1][5];
121+
122+
out << t << "," << gen2speed << "," << gen3speed << "," << v2mag << "," << v3mag << "\n";
123+
124+
real_type err = std::max({std::abs(gen2speed - gen2speed_ref),
125+
std::abs(gen3speed - gen3speed_ref),
126+
std::abs(v2mag - v2mag_ref),
127+
std::abs(v3mag - v3mag_ref)});
128+
if (err > worst_error)
129+
{
130+
worst_error = err;
131+
worst_error_time = t;
132+
}
133+
}
134+
// fileout.close();
135+
136+
std::cout << "Worst error " << worst_error
137+
<< " at time t = " << worst_error_time << "\n";
138+
std::cout << "\n\nComplete in " << (stop - start) / CLOCKS_PER_SEC << " seconds\n";
139+
140+
return worst_error < error_allowed ? 0 : 1;
141+
}

0 commit comments

Comments
 (0)