Skip to content
Snippets Groups Projects
Commit 6bc09643 authored by Jan Dinkelbach's avatar Jan Dinkelbach
Browse files

Merge branch 'master' of...

parents 689fbcbc 1b0d9ec3
Branches
No related tags found
No related merge requests found
%% Cell type:markdown id:cf1f4a01-23c9-483d-9bf3-0a80ed440ae0 tags:
%% Cell type:markdown id: tags:
<div>
<img src="figures/slew_logo.png" style="float: right;height: 15em;">
</div>
# SLEW Case 2 - Electromechanical Dynamics: Small-signal Stability
## Theoretical background
### The Linearized Swing Equation
The swing equation is the fundamental equation that determines the rotor dynamics of a synchoronous machine.
$$M\frac{d^{2}\delta}{dt^{2}} = P_{m} - P_{e}(\delta) - D\frac{d\delta}{dt}$$
For small signal stability analysis, the swing equation can be linearized in the vicinity of the operating point $\delta = \delta_{0}$:
$$M\frac{d^{2}\Delta\delta}{dt^{2}} + D\frac{d\Delta\delta}{dt} + K_{e^{'}}\Delta\delta = 0 $$
where $K_{e^{'}}$ is the transient synchoronizing power coefficient at $\delta = \delta_{0}$:
$$K_{e^{'}} = \frac{\partial P_{e^{'}}}{\partial \delta^{'}}\mid_{\delta = \delta_{0}}$$
The characteristic equation and the roots of the linearized swing equation are as follows:
$$\lambda^{2} + \frac{D}{M}\lambda + \frac{K_{e^{'}}}{M} = 0 $$
$$\lambda_{1,2} = -\frac{D}{2M} \pm \sqrt{\left(\frac{D}{2M}\right)^{2} - \frac{K_{e^{'}}}{M}} $$
%% Cell type:markdown id:a620deac-bea3-4f34-841a-b9d7e41fe1ae tags:
%% Cell type:markdown id: tags:
***
## Case description
%% Cell type:markdown id:40672b8b-585f-4448-9dac-523d4f33287c tags:
%% Cell type:markdown id: tags:
A $200 MVA$ round-rotor generator is connected to an infinite bus system of nominal frequency of $50 Hz$ through a step-up transformer with reactance of $0.13 p.u.$ and a transmission line with reactance of $0.17 p.u.$ . The generator’s transient reactance is $x'_{d} = 0.23 p.u.$ and the inertia constant is $H = 4 s$. The synchoronous generator mechanical power is set to $0.6 p.u.$ and the steady-state emf $E = 1.1 p.u.$
%% Cell type:markdown id:ab2be9d0-04eb-47cd-988d-3af3cde391bd tags:
%% Cell type:markdown id: tags:
***
## Case tasks
%% Cell type:markdown id:4947469f-3514-4edc-a9d9-4d3157f36513 tags:
%% Cell type:markdown id: tags:
1. If at the given operating point the system eigen-values are as follows:
$$\lambda_{1,2} = -0.06254 \pm 8.8318j $$
a.) Determine whether the system response following a small disturbance is overdamped, critically damped or underdamped.<br>
b.) Verify you findings by calculating the damping coefficient of the synchronous generator and then applying the damping value in VILLASweb and generating the corresponding power and angle plots.<br>
<br>
2. If the system response following a small disturbance is critically damped. <br>
a.) Determine the synchoronous generator damping coefficient.<br>
b.) Apply the calculated damping value in VILLASweb and generate the corresponding power and angle plots.<br>
c.) Increase the damping coefficient value and observe the impact of such increase.<br>
%% Cell type:markdown id:68a26943-3791-4b08-a38e-a4a1454d24b7 tags:
%% Cell type:markdown id: tags:
**You can process the results from VILLASweb (as required in 1 and 2) using the prepared notebook cells below.**
%% Cell type:markdown id:8b454ae8-71a1-4017-9c5a-cf3efc494e40 tags:
%% Cell type:markdown id: tags:
***
## Case solutions
%% Cell type:markdown id:fa5f07a4-23a0-4846-8fc2-d9a3eeae3b8a tags:
%% Cell type:markdown id: tags:
#### First Setup your Python for post-processing
%% Cell type:markdown id:032049e7-1108-4fb1-9057-3b6c522a81bd tags:
%% Cell type:markdown id: tags:
Import relevant Python packages by executing the following cell:
%% Cell type:code id:fa7d426a-0908-454d-8b0d-0dc64eb785ca tags:
%% Cell type:code id: tags:
``` python
from IPython.display import display
from villas.web.result import Result
from pprint import pprint
import tempfile
import os
from villas.dataprocessing.readtools import *
from villas.dataprocessing.timeseries import *
import matplotlib.pyplot as plt
import scipy.io as sio
outputs = sio.loadmat('outputs/case2_output.mat', simplify_cells=True)
%matplotlib widget
```
%% Cell type:markdown id:9be353cf-624a-4e88-a427-f94091c651bb tags:
%% Cell type:markdown id: tags:
### Subtask 1.b
To check your results, enter your solution for $D$ rounded to 4 digits behind the comma:
%% Cell type:code id:cd8c51d0-ca49-426b-8b86-af774b6717b7 tags:
%% Cell type:code id: tags:
``` python
D=input('D in Subtask 1.b:')
print('Your result is', 'correct!' if round(float(D),4)==round(outputs['D_T1b'],4) else 'incorrect. You should double-check your calculations.')
```
%% Cell type:markdown id:ab551c32-ef6f-47d3-b839-57e2ce506863 tags:
%% Cell type:markdown id: tags:
#### Download simulation results from VILLASweb
%% Cell type:markdown id:e70b8ccc-8d97-4827-ba45-251be9c6ac82 tags:
%% Cell type:markdown id: tags:
Enter VILLASweb under https://slew.rwth-aachen.de/.
Adjust the parameter $D$ and run a corresponding simulation.
Then, enter your code snippet for result download in the following cell:
%% Cell type:code id:5c6f4d63-2c1c-49aa-acde-073f1cffd7d5 tags:
%% Cell type:code id: tags:
``` python
# Access result using token
r = Result(1, 'xyz', endpoint='https://slew.rwth-aachen.de')
```
%% Cell type:markdown id:85d62e17-9df8-421c-8b99-aac7be09bf09 tags:
%% Cell type:markdown id: tags:
#### Plot the results
%% Cell type:code id:ec357284-6407-41bb-9d54-3ca6c0532fa9 tags:
%% Cell type:code id: tags:
``` python
results_file_name='SP_SynGenTrStab_SMIB_Fault_SlewCase2_JsonSyngenParams_SP.csv'
# Get file by name
f = r.get_file_by_name(results_file_name)
# Create temp dir
tmpdir = tempfile.mkdtemp()
results_file_path = os.path.join(tmpdir,results_file_name)
# Load files as bytes
f = f.download(dest=results_file_path)
# Get time series object from csv
ts_res1 = read_timeseries_csv(results_file_path, print_status=True)
# Plot the currents
plt.figure(figsize=(8,12))
name_list = ['Rotor Angle','Output Power']
plt.subplot(2,1,1)
plt.ylabel("Angle (degree)")
plt.xlabel("time (s)")
plt.plot(ts_res1['delta_r_gen'].time, ts_res1['delta_r_gen'].values, label='Rotor Angle task 1.b', color='C0')
plt.xlim([1, 30])
plt.legend(loc='upper right')
plt.subplot(2,1,2)
plt.ylabel("Power (MW)")
plt.xlabel("time (s)")
plt.plot(ts_res1['P_elec'].time, ts_res1['P_elec'].values/1e6, label='Output Power task 1.b', color='C0')
plt.xlim([1, 30])
plt.legend(loc='upper right')
plt.show()
```
%% Cell type:markdown id:87835d8e-afcd-4a23-8b36-596eaaca7b92 tags:
%% Cell type:markdown id: tags:
### Subtask 2.a
To check your results, enter your solution for $D$ rounded to 4 digits behind the comma:
%% Cell type:code id:56d9f0db-b158-4fc3-a9b0-5a2d8931da9b tags:
%% Cell type:code id: tags:
``` python
D=input('D in Subtask 2.a:')
print('Your result is', 'correct!' if round(float(D),4)==round(outputs['D_T2a'],4) else 'incorrect. You should double-check your calculations.')
```
%% Cell type:markdown id:0848fc38-50ad-421a-8442-9f8b9c26a1e0 tags:
%% Cell type:markdown id: tags:
### Subtask 2.b
%% Cell type:markdown id:3c0fd278-b58a-4af7-a101-4a52e1a32c94 tags:
%% Cell type:markdown id: tags:
#### Download simulation results from VILLASweb
%% Cell type:markdown id:af0ec7ca-9cf7-4986-9ae9-ab762a792b5f tags:
%% Cell type:markdown id: tags:
Enter VILLASweb under https://slew.rwth-aachen.de/.
Adjust the parameter $D$ and run a corresponding simulation.
Then, enter your code snippet for result download in the following cell:
%% Cell type:code id:8331e105-8b66-4479-9caf-6ec038c1bce0 tags:
%% Cell type:code id: tags:
``` python
# Access result using token
r = Result(1, 'xyz', endpoint='https://slew.rwth-aachen.de')
```
%% Cell type:markdown id:f9879ce7-72ae-4306-9d65-8f8604484c43 tags:
%% Cell type:markdown id: tags:
#### Plot the results
%% Cell type:code id:ccad2758-d711-46c9-a54b-a788efb563eb tags:
%% Cell type:code id: tags:
``` python
results_file_name='SP_SynGenTrStab_SMIB_Fault_SlewCase2_JsonSyngenParams_SP.csv'
# Get file by name
f = r.get_file_by_name(results_file_name)
# Create temp dir
tmpdir = tempfile.mkdtemp()
results_file_path = os.path.join(tmpdir,results_file_name)
# Load files as bytes
f = f.download(dest=results_file_path)
# Get time series object from csv
ts_res2 = read_timeseries_csv(results_file_path, print_status=False)
# Plot the currents
plt.figure(figsize=(8,12))
name_list = ['Rotor Angle','Output Power']
plt.subplot(2,1,1)
plt.ylabel("Angle (degree)")
plt.xlabel("time (s)")
plt.plot(ts_res1['delta_r_gen'].time, ts_res1['delta_r_gen'].values, label='Rotor Angle task 1.b', color='C0')
plt.plot(ts_res2['delta_r_gen'].time, ts_res2['delta_r_gen'].values, label='Rotor Angle task 2.b', color='C1', linestyle=':')
plt.plot(ts_res2['delta_r_gen'].time, ts_res2['delta_r_gen'].values, label='Rotor Angle task 2.b', color='C1')
plt.plot(ts_res1['delta_r_gen'].time, ts_res1['delta_r_gen'].values, label='Rotor Angle task 1.b', color='C0', linestyle=':')
plt.xlim([1, 30])
plt.legend(loc='upper right')
plt.subplot(2,1,2)
plt.ylabel("Power (MW)")
plt.xlabel("time (s)")
plt.plot(ts_res1['P_elec'].time, ts_res1['P_elec'].values/1e6, label='Output Power task 1.b', color='C0')
plt.plot(ts_res2['P_elec'].time, ts_res2['P_elec'].values/1e6, label='Output Power task 2.b', color='C1', linestyle=':')
plt.plot(ts_res2['P_elec'].time, ts_res2['P_elec'].values/1e6, label='Output Power task 2.b', color='C1')
plt.plot(ts_res1['P_elec'].time, ts_res1['P_elec'].values/1e6, label='Output Power task 1.b', color='C0', linestyle=':')
plt.xlim([1, 30])
plt.legend(loc='upper right')
plt.show()
```
%% Cell type:markdown id:8e4f8736-d4a5-4d5b-8d56-fee4b7afb499 tags:
%% Cell type:markdown id: tags:
### Subtask 2.c
%% Cell type:markdown id:88f14679-151b-47d3-bf9e-0c912427e504 tags:
%% Cell type:markdown id: tags:
#### Download simulation results from VILLASweb
%% Cell type:markdown id:0740d062-5e8f-4eb9-88bc-a6eea0003391 tags:
%% Cell type:markdown id: tags:
Enter VILLASweb under https://slew.rwth-aachen.de/.
Adjust the parameter $D$ and run a corresponding simulation.
Then, enter your code snippet for result download in the following cell:
%% Cell type:code id:e490e568-1db0-4fb6-942a-30fafecee4bd tags:
%% Cell type:code id: tags:
``` python
# Access result using token
r = Result(1, 'xyz', endpoint='https://slew.rwth-aachen.de')
```
%% Cell type:markdown id:40ee9509-a952-42d8-a67d-4901ba2d95bd tags:
%% Cell type:markdown id: tags:
#### Plot the results
%% Cell type:code id:36505e96-7b81-41df-847c-a024269beb05 tags:
%% Cell type:code id: tags:
``` python
results_file_name='SP_SynGenTrStab_SMIB_Fault_SlewCase2_JsonSyngenParams_SP.csv'
# Get file by name
f = r.get_file_by_name(results_file_name)
# Create temp dir
tmpdir = tempfile.mkdtemp()
results_file_path = os.path.join(tmpdir,results_file_name)
# Load files as bytes
f = f.download(dest=results_file_path)
# Get time series object from csv
ts_res3 = read_timeseries_csv(results_file_path, print_status=False)
# Plot the currents
plt.figure(figsize=(8,12))
name_list = ['Rotor Angle','Output Power']
plt.subplot(2,1,1)
plt.ylabel("Angle (degree)")
plt.xlabel("time (s)")
plt.plot(ts_res2['delta_r_gen'].time, ts_res2['delta_r_gen'].values, label='Rotor Angle task 2.b', color='C1')
plt.plot(ts_res3['delta_r_gen'].time, ts_res3['delta_r_gen'].values, label='Rotor Angle task 2.c', color='C2', linestyle=':')
plt.plot(ts_res3['delta_r_gen'].time, ts_res3['delta_r_gen'].values, label='Rotor Angle task 2.c', color='C2')
plt.plot(ts_res2['delta_r_gen'].time, ts_res2['delta_r_gen'].values, label='Rotor Angle task 2.b', color='C1', linestyle=':')
plt.xlim([1, 30])
plt.legend(loc='upper right')
plt.subplot(2,1,2)
plt.ylabel("Power (MW)")
plt.xlabel("time (s)")
plt.plot(ts_res2['P_elec'].time, ts_res2['P_elec'].values/1e6, label='Output Power task 2.b', color='C1')
plt.plot(ts_res3['P_elec'].time, ts_res3['P_elec'].values/1e6, label='Output Power task 2.c', color='C2', linestyle=':')
plt.plot(ts_res3['P_elec'].time, ts_res3['P_elec'].values/1e6, label='Output Power task 2.c', color='C2')
plt.plot(ts_res2['P_elec'].time, ts_res2['P_elec'].values/1e6, label='Output Power task 2.b', color='C1', linestyle=':')
plt.xlim([1, 30])
plt.legend(loc='upper right')
plt.show()
```
%% Cell type:code id: tags:
``` python
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment