You are on page 1of 146

CBuilder FX

Tutorial
Table of Contents
1 MULTIPLE INPUT ADDER ....................................................................................................................... 1
1.1 Introduction .................................................................................................................................. 1
1.2 Create a New Component............................................................................................................. 1
1.3 Create the Required Parameters .................................................................................................. 2
1.5 Draw the Graphics......................................................................................................................... 5
1.6 Add the IO Points ........................................................................................................................ 11
1.7 Adding the Model Code .............................................................................................................. 14
1.8 Sample ‘C’ Code for the Multiple Input Adder............................................................................ 15
2 INTEGRATOR ......................................................................................................................................... 1
2.1 Introduction .................................................................................................................................. 1
2.2 draw Graphics and Add Parameters ............................................................................................. 2
2.3 Adding the Model Code ................................................................................................................ 2
2.4 Sample ‘C’ Code for an Integrator................................................................................................. 3
2.5 Add a Reset Input to the Integrator .............................................................................................. 4
3 VARIABLE CAPACITOR ........................................................................................................................... 1
3.1 Introduction .................................................................................................................................. 1
3.2 Capacitor ....................................................................................................................................... 2
3.3 Draw Graphics and Add Parameters ............................................................................................. 3
3.4 Adding the Model Code ................................................................................................................ 4
3.5 Adding an Optionally Monitored Variable .................................................................................... 6
4 MULTI-MASS SYSTEM.............................................................................................................................. 1
4.1 Introduction .................................................................................................................................. 1
4.2 Single Mass Rotating About And Axis ........................................................................................... 2
4.2.1 Equations Of Motion Representing A Single Mass Rotating About An Axis .......................... 2
4.3 Damping ........................................................................................................................................ 4
4.4 Two Rotating Masses Coupled By A Shaft .................................................................................... 6
4.4.1 Equations Of Motion For 2 Rotating Masses Coupled By A Shaft ......................................... 6
4.5 Multi-Mass Model Using Matrix Formulation .............................................................................. 9
4.6 Multi-Mass Model Algortithm .................................................................................................... 11
4.7 Model Development Using C-Builder ......................................................................................... 11
4.7.1 Conceptual Layout Of The New Component ...................................................................... 11

1
4.7.2 Component Icon Creation In C−Builder (Graphics & Nodes) .............................................. 12
4.7.3 Define User Supplied Data Menus (Parameters)................................................................. 12
4.7.4 Write Data Preparation Portion Of The ‘C’ Program ........................................................... 12
4.7.5 Write ‘C’ Code To Implement The Algorithm ...................................................................... 12
4.7.6 Test Newly Developed Model ............................................................................................. 12
4.7.7 Conceptual Layout Of The New Component....................................................................... 12
4.7.8 Component Icon Creation In C−Builder ............................................................................... 15
4.7.9 Add Parameter Entry Menus ............................................................................................... 20
4.7.10 Write Data Preparation Portion Of The ‘C’ Program ............................................................. 22
4.7.11 Write ‘C’ Code To Implement The Algorithm ...................................................................... 25
4.7.12 Test Newly Developed Model .............................................................................................. 30
4.8 References .................................................................................................................................. 31
5 MULTI-THREAD COMPONENT............................................................................................................... 1
5.1 Introduction .................................................................................................................................. 1
5.2 Multi-Function Relays ................................................................................................................... 2
5.3 Multi-Thread Component ............................................................................................................. 2
5.4 Model Development using CBuilder ............................................................................................. 3
5.5 Multi-Thread Model Algorithm ................................................................................................... 12
5.6 Multi-Thread Static Section ........................................................................................................ 13
5.7 Multi-Thread Ram section .......................................................................................................... 14
5.8 Multi-Thread Code Section ......................................................................................................... 17
6 PMU SHELL COMPONENT ..................................................................................................................... 1
6.1 Introduction .................................................................................................................................. 1
6.2 Phasor Measurement Unit ............................................................................................................ 1
6.3 Model Development using CBuilder ............................................................................................. 2
6.4 PMU Shell Component .................................................................................................................. 3
6.5 Load PMU Shell into CBuilder ....................................................................................................... 3
6.6 PMU Shell Algorithm ..................................................................................................................... 4
6.7 C Code Sections ............................................................................................................................. 6
6.8 References .................................................................................................................................. 11
7 GENERATOR CONTROL BLOCK .............................................................................................................. 1
7.1 Introduction .................................................................................................................................. 1
7.2 Draw Graphics and Add Parameters ............................................................................................. 1

2
7.3 Adding the Model Code ................................................................................................................ 2
7.4 Sample ‘C’ Code for the DC1 Type Exciter .................................................................................... 3
7.5 Data Preparation and Initialization ............................................................................................. 11
7.6 Add an Internal Slider ................................................................................................................. 13
7.7 Add Code for realpole Function .................................................................................................. 15
7.8 Add Code leadlag Function ......................................................................................................... 15
7.9 Add Code for washOut Function ................................................................................................. 15
7.10 Add Code for Saturation Function .............................................................................................. 16
7.11 Adding the Code.......................................................................................................................... 16
7.12 Add a Dial to Select InterNal Variables for Monitoring .............................................................. 20
7.13 Add a Generic Output ................................................................................................................. 21
7.14 Add Monitoring Code.................................................................................................................. 21
8 SIMPLE TRANSFORMER ......................................................................................................................... 1
8.1 Introduction .................................................................................................................................. 1
8.2 Theory ........................................................................................................................................... 1
8.2.1 Modelling a Transformer ...................................................................................................... 1
8.2.2 RTDS Solution Algorithm ....................................................................................................... 4
8.2.3 Integrating the Transformer Model into the RTDS Solution Algorithm ................................ 5
8.2.4 Generalizing the Transformer Equations .............................................................................. 9
8.3 Draw Graphics and Add Parameters ........................................................................................... 11
8.4 Adding the Model Code .............................................................................................................. 12
8.5 Basic Algorithm ........................................................................................................................... 13
8.6 References .................................................................................................................................. 19
9 MULTIPLIER WITH COMPLEX NUMBERS AS INPUTS ............................................................................. 1
9.1 Introduction .................................................................................................................................. 1
9.2 Create the Required Parameters .................................................................................................. 1
9.3 Add the IO Points .......................................................................................................................... 2
9.4 Adding the Model Code ................................................................................................................ 3
9.5 Sample ‘C’ Code for the Multiple Input Multiplier with Complex Number Inputs ....................... 4

3
1 MULTIPLE INPUT ADDER

1.1 INTRODUCTION
Simple use of the Component Builder (CBuilder) module in RSCAD FX is going to be detailed
in this chapter. CBuilder module lets users‘ create their own components for RSCAD. The
CBuilder FX includes a conversion utility to convert CBuilder components created in older
versions of RSCAD into RSCAD FX.
In this tutorial chapter, the user will build an adder component that can add or subtract two
or three inputs. This adder will be able to accept real type inputs.

1.2 CREATE A NEW COMPONENT


• Start RSCAD, Open “Component Builder” from the Launch menu.
• Select ”’New Component” at the welcome dialog.
• Select ”Control” for the Component Type

Figure 1.1: Set Initial Options Menu

The CBuilder module will appear as shown in Figure 1.2.

1
CBuilder Tutorial: Multiple Input Adder

Figure 1.2: CBuilder FX

• Save the component as “tutorialc”. It will have a .def file extension.

1.3 CREATE THE REQUIRED PARAMETERS


The required parameters are going to be added into a new section. Each section will appear
as a separate tab in Draft when you edit the parameters of the component. The “New
Section” and “New parameter” buttons are identified in the toolbar in Figure 1.3.
• Select the Parameters tab.

Figure 1.3: Parameters Tab

• Add a new section titled “addercontrol”


• New parameters will be added at the insertion point, which is a blue line in the
table. By clicking on a section header, the insertion point will be placed at the end
of that section. Click on a existing parameter and the insertion point will be placed
immediately after that parameter. Before adding a new parameter ensure that the

2
CBuilder Tutorial: Multiple Input Adder

insertion point is in the section “addercontrol”.

Figure 1.4: Insertion Point

• A number of fields must be entered to define each new parameters. Add the
following parameters to the newly created section.

Parameter #1
Name numInputs
Description Number of Inputs
Type INTEGER
Unit And Toggle Entries <leave blank>
Value 2
Min 2
Max 3

Parameter #2
Name sign1
Description Sign of Input 1
Type TOGGLE
Unit And Toggle Entries Add;Subtract
Value Add
Min 0
Max 1

• The toggle entries must be entered separated by semicolon “;”


• The parameter sign1 will be assigned a value of 0 if the “Add” toggle
entry is selected, it will be assigned a value of 1 if “Subtract” is selected.

3
CBuilder Tutorial: Multiple Input Adder

Inputs sign2 and sign3 must also be added as parameters. They can be added
manually or the existing sign1 parameter can be copied, pasted and modified. Note
the sign3 is conditionally enabled.
Parameter #3
Name sign2
Description Sign of Input 2
Type TOGGLE
Unit And Toggle Entries Add;Subtract
Value Add
Min 0
Max 1

Parameter #4
Name sign3
Description Sign of Input 3
Type TOGGLE
Unit And Toggle Entries Add;Subtract
Value Add
Min 0
Max 1
Enabled Condition numInputs>2

1.4 DRAW THE GRAPHICS


The main toolbar shown in Figure 1.5 contains tools for drawing the component’s graphics.

Add node

Figure 1.5: Tools For Drawing Component Graphics

There are four sections of graphics for each component. The user can switch between these
graphics section using a dropdown in the Graphics tab which is shown in Figure 1.6.
1. Main

4
CBuilder Tutorial: Multiple Input Adder

2. Tiny
3. Library
4. Loadflow

Note: All four sections should be present for all components. The later chapters will not
further discuss the tiny and library graphics, but it is the users’ responsibility to make sure
those sections are present and to follow the guidelines presented in this chapter.

Figure 1.6: Graphics Dropdown Menu

In the toolbar, the “Add macro” dropdown menu has a collection of basic shapes that can
make the drawing process efficient.

Figure 1.7: Available Macros

5
CBuilder Tutorial: Multiple Input Adder

1.4.1 Main Graphics


The goal is to draw a component icon that looks similar to Figure 1.8.

Figure 1.8: Finished Component Icon


Several snap-to options exist to make drawing component graphics easier. There are a
number of helpful toolbar buttons as seen in Figure 1.9. In the figure the option “Snap to
Grid” is selected. This will allow the graphical objects to snap to the points on the grid. A
dropdown can be used to set the grid point spacing as small as 2 pixels, or as large as 32
pixels. The user can also choose to not snap to grid.

Figure 1.9: Grid Options

• Start by drawing the unconditional graphics. The graphics can be drawn


by using the drawing tools at the top toolbar of the main window.
Ensure that the graphics are drawn near the center of the canvas
(indicated by the intersecting lines).

6
CBuilder Tutorial: Multiple Input Adder

Figure 1.10: Drawing the Unconditional Graphics

• Select the “Graphics” tab. With the unconditional graphics drawn, the
graphics section should appear similar to Figure 1.11.

Figure 1.11: Unconditional Graphics

Please refer to Figure 1.12 and Figure 1.13 for the steps below.
• Add a new “If” graphics condition. This condition will be used to change
the look of the icon depending on the number of inputs.

7
CBuilder Tutorial: Multiple Input Adder

Figure 1.12: Selecting “If” from Add Condition Drop Down Menu

• Enter the condition sign1==0 in the box provided.


• Ensure the insertion point is located within the new ‘sign1==0’ (Add) condition. This
can be done by clicking on the condition. Any graphics added will now be placed
within the ‘If’ condition.
• Draw a ’+’ sign with lines at the 12 o’clock position of the inside of the circle using
the line tool to indicate the sign of input1.
• Ensure the insertion point is inside the ‘sign1==0’ condition. Add a new ’Else’
condition. The insertion point should now be inside the Else condition (Subtract).
• Draw a ’−’ sign over the ‘+’ sign. The graphics for the minus sign should now appear
under the Else condition. Note that the shapes inside each If/Else can be shown or
hidden by clicking on the triangle beside the If/Else.
• Move the insertion point outside of the conditions. This can be done by clicking on a
graphical object in the tree that is not inside a condition. Repeat the above steps to
create conditional graphics for ‘sign2==0’, except put the graphics at the 9 o’clock
position of the circle.
• Move the insertion point outside of the conditions and add a new ’If condition’.
• Enter condition ‘numInputs>2’
• Ensure the insertion point is inside the ‘numInputs>2’ condition and draw the third
input lines.
• Ensure the insertion point is still inside ‘numInputs>2’ and add the condition
‘sign3==0’.
• Ensure the insertion point is now inside the ‘sign3==0’ condition and add the
conditional ‘+’ and ‘- graphics described in previous steps at the 6 o’clock position of
the circle.

8
CBuilder Tutorial: Multiple Input Adder

The icon should now appear similar to Figure 1.13.

Figure 1.13: Component Icon

The conditional graphics section in the graphics tab would appear as:

Figure 1.14: Conditional Section of the Graphics

9
CBuilder Tutorial: Multiple Input Adder

1.4.2 Tiny Graphics


The tiny graphics section is used in RSCAD when the zoom level of a draft circuit is reduced
beyond a chosen threshold. These graphics are meant to be a simplified representation of
the component with the aim of reducing the computational burden of rendering graphics
when a large network is being viewed. Minimal conditional graphics should be used. Use of
text is discouraged and black should be the only graphic colour used. An example is shown
in Figure 1.15.

Figure 1.15: Tiny Graphics Example

1.4.3 Library Graphics


The library graphics are the graphics displayed in the library. This is another simpler
representation of the component. Library graphics needs to be drawn in the space provided.
Use of conditional graphics is discouraged. An example is shown in Figure 1.16

Figure 1.16: Library Graphics Example

10
CBuilder Tutorial: Multiple Input Adder

1.4.4 Loadflow Graphics


This section is applicable for power system components only. Control components do no
participate in the loadflow so this section will remain blank for control components.

1.5 ADD THE IO POINTS


In this example some of the IO points are conditional.
• Select the ’IO Points’ tab.

• Add 3 nodes using the ‘Draw Node’ button from the toolbar, . Clicking twice on
the button will allow several nodes to be drawn successively. Place two of the nodes
at the first 2 inputs, place the third at the output of the component. Node details can
be modified by selecting each node and editing the information box that appears
below the graphics window. See Figure 1.17.

Figure 1.17: Adding Node Information

The information for the IO nodes are listed below.


IO point fInput1
Name fInput1
Type SIGNAL INPUT
Data Type REAL

11
CBuilder Tutorial: Multiple Input Adder

IO point fInput2
Name fInput2
Type SIGNAL INPUT
Data Type REAL

IO point fOutput
Name fOutput
Type SIGNAL OUTPUT
Data Type REAL

• Inside the IO tab, create an ‘If’ condition and enter ‘numInputs==3’ as the condition.
• Select the condition ’If numInputs==3’ to ensure the insertion point is inside the
condition and add the fInput3 IO point (input to sign3).

Figure 1.18: Adding Conditional Graphics

IO point fInput3
Name fInput3
Type SIGNAL INPUT
Data Type REAL

The IO tab should now appear as shown in Figure 1.19.

12
CBuilder Tutorial: Multiple Input Adder

Figure 1.19: Creating Conditions in IO Points Tab

1.6 ADDING THE MODEL CODE


• Select the ’C File Associations’ tab.

• Select the icon to Add New Association.


• Enter a model name such as ’tutorialc’
• The associations should appear similar to Figure 1.20.

Figure 1.20: Adding a New Association

13
CBuilder Tutorial: Multiple Input Adder

• The input and output points appear under the ’INPUTS’ and ’OUTPUTS’ sections and
not the ’NODES’ section. This is a controls component and the NODES section is
reserved for power system component electrical type nodes.
• The next step is writing the c-code which defines the behaviour of the component.
Select the icon to begin editing the .c file.
Simple ’c’ code to add two inputs together and produce an output might look
something like the following:

CODE:
fOutput = fInput1 + fInput2;

• Type the c-code listed in Section 1.7 into tutorialc.c then push the compile icon
in the C File Association tab, to compile the code. If the compile is successful, the
component is ready to be included in a Draft circuit.
• Ensure that the CBuilder component is saved.
• Draft has an internal memory of the components used during a draft session. If a
component icon is modified while Draft is open, the icons must be refreshed. Select
the icon from the library toolbar to refresh components.

1.7 SAMPLE ‘C’ CODE FOR THE MULTIPLE INPUT ADDER


Note: The code should not be copy pasted due to encoding issue. The user should write the
code in their editor.
Code is shown below:
#include ”tutorialc.h”

STATIC:
// use the mult variables to keep track of sign of input
int mult1;
int mult2;
int mult3;

RAM:
// the parameters sign1,sign2 and sign3 are toggles where
// 0 == plus and 1 == minus
// use the mult variables to keep track of sign of input

if (sign1 == 1)

14
CBuilder Tutorial: Multiple Input Adder

mult1 = −1;
else
mult1 = 1;

if (sign2 == 1)
mult2 = −1;
else
mult2 = 1;

if (sign3 == 1)
mult3 = −1;
else
mult3 = 1;

CODE:
if (numInputs > 2)
fOutput = (mult1*fInput1) + (mult2*fInput2) + (mult3*fInput3);
else
fOutput = (mult1*fInput1) + (mult2*fInput2);

15
20210209

2 INTEGRATOR

2.1 INTRODUCTION
The integrator reads in one real input, integrates the input with a user specified
time−constant (T) and writes one output. The basic equations, based on trapezoidal rule of
integration with a simulation time−step of ∆t, are used to compute the integral of the input
as shown in Equation 2-1, Equation 2-2, Equation 2-3, and Equation 2-4.

Figure 2.1: Basic Integral

1
𝑌(𝑡) = ∫ 𝑋(𝑡)𝑑𝑡 Equation 2-1
𝑇

1 𝑡
𝑌(𝑡) = ∫ 𝑋(𝑡)𝑑𝑡 + 𝑌(𝑡 − ∆𝑡) Equation 2-2
𝑇 𝑡−∆𝑡

1 ∆𝑡 ∗ [𝑋(𝑡 − ∆𝑡) + 𝑥(𝑡)]


𝑌(𝑡) = { } + 𝑌(𝑡 − ∆𝑡) Equation 2-3
𝑇 2

∆𝑡
𝑌(𝑡) = {𝑋(𝑡 − ∆𝑡) + 𝑥(𝑡)} + 𝑌(𝑡 − ∆𝑡) Equation 2-4
2𝑇

Data Preparation:
Initialize Xold= 0.0;
Initialize Yold= 0.0;
Compute K= dt/(2T);

1
CBuilder Tutorial: Integrator

Algorithm:
Read X;
Y= K * (Xold + X) + Yold;
Write Y;

2.2 DRAW GRAPHICS AND ADD PARAMETERS


• Draw an icon that looks similar to Figure 2.2.

Figure 2.2: Integrator Component Icon

The component icon for the integrator includes two I/O points. One signal input
named input and one signal output named output, both are real.
• Add a parameter ’T’ to specify the time constant (type REAL).

2.3 ADDING THE MODEL CODE


• Select the ’C File Associations’ tab.
• Select the “Add new Association” which is a plus sign on a green circle.
• Enter the model name as “integrate”.
• Select the “Edit C File” to write the code.
Input and Output points (listed under the IO Points tab) and user defined parameters (listed
under the Parameters tab) are automatically associated with the model and placed in the .h
file. Left clicking the “View .h file” button opens the .h file in an editor. A model that includes
one input, one output and a parameter would have the following lines in the .h file:

2
CBuilder Tutorial: Integrator

INPUTS:
double input;

OUTPUTS:
double output;

PARAMETERS:
double T;

2.4 SAMPLE ‘C’ CODE FOR AN INTEGRATOR


#include ”integrate.h”

STATIC:
/* −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− */
/* Variables declared here may be used in both the */
/* RAM: and CODE: sections below. */
/* −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− */
double dt;
double input_old,output_old,K;
/* − E n d o f S T A T I C : S e c t i o n − */

RAM:
/* −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− */
/* Place C code here which computes constants */
/* required for the CODE: section below. The C */
/* code here is executed once, prior to the start */
/* of the simulation case. */
/* −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− */
dt= getTimeStep();

input_old = 0.0;
output_old = 0.0; K = dt/(2.0*T);

/* −−−− E n d o f R A M : S e c t i o n −−−− */

3
CBuilder Tutorial: Integrator

CODE:
/* −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− */
/* Place C code here which runs on the RTDS. The */
/* code below is entered once each simulation */
/* step. */
/* −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− */

output = (input + input_old) * K + output_old;

input_old = input;
output_old = output;

2.5 ADD A RESET INPUT TO THE INTEGRATOR


• Add shapes to the icon to include a reset input.

Figure 2.3: Adding Reset Input to Integrator

• Add an integer I/O point named reset to the reset input.


• Update the association to include the new I/O point.
• Modify the ’C’ code to reset the integrator when a value other than 0 is applied to
the reset input.
• Recompile the new code.
• Save the new icon.
CODE:
if (reset != 0)
{

4
CBuilder Tutorial: Integrator

output = 0;

input_old = 0;
output_old = 0;
}
else
{
output = (input + input_old) * K + output_old;

input_old = input;
output_old = output;
}

• Draft has an internal memory of the components used during a draft session. If a
component icon is modified while Draft is open, the icons must be refreshed. Select
the icon from the Draft toolbar to refresh components.

Note: Compile the model. The component is now ready. Make sure to save the file. User can
load it in RSCAD and test out the component. In order to load the component in RSCAD, right
click on a an empty spot in draft, and select Add Component > User > load the definition file.

5
3 VARIABLE CAPACITOR
3.1 INTRODUCTION
This component will be modeled as a power system component in CBuilder.
Control system components interact with other components using control type input and
output signals and do not interact directly with the solution of the power system network.
Power system components, on the other hand, need to interact directly with the solution of
the power system network. The interface is usually made by specifying an impedance at the
nodes to which the component is connected and by providing current injections into those
nodes.

Figure 3.1: Current Injection

The network solution expects to receive current injection values from power system
components well before the end of the simulation time−step so that there is enough time
remaining in the time−step to compute the new node voltages. To accommodate this, the
CODE: section for power system components is divided into two portions Begin−T0 and
T0−T2.
The first portion, referred to as Begin−T0, is used to execute the statements required to
compute current injections which the component injects into the nodes to which it is
connected. Once the current injections are ready, the executable code is suspended until all
of the other power system models have completed their current injection calculations. At
this point the current injections from all of the power system models allocated to the RTDS
rack are sent to the processor/core dedicated to solving the power system network. Upon
completion of this T0 transfer, executable code for the components who participated in T0
continues. The remaining portion of the executable code, referred to as T0−T2 may be used
to solve portions of the algorithm that are not needed to compute the current injections, for
preparing variables that are written out for monitoring and preparing for the next time−step.

1
CBuilder Tutorial: Variable Capacitor

Once the second portion of code is completed the executable code is again suspended until
all of the variables transferred during the T2 communication interval have been transferred
between processors. Control type variables, monitored variables and node voltages are
exchanged during the T2 communication interval. The node voltages are computed by the
processor allocated to the network solution and transferred to other processors in the rack.
As such, new node voltage data is available once the processors are restarted for the next
simulation time-step.

3.2 CAPACITOR
Application of the trapezoidal rule of integration to the basic capacitor equation is used for
the numerical solution of the capacitor.

Figure 3.2: Simple Capacitor

𝑉𝑉(𝑡𝑡) = 𝑉𝑉𝑁𝑁1 (𝑡𝑡) − 𝑉𝑉𝑁𝑁2 (𝑡𝑡) Equation 3-1

𝑑𝑑𝑑𝑑(𝑡𝑡)
𝑖𝑖(𝑡𝑡) = 𝐶𝐶 ∗ Equation 3-2
𝑑𝑑𝑑𝑑
1
𝑉𝑉(𝑡𝑡) = � 𝑖𝑖(𝑡𝑡)𝑑𝑑𝑑𝑑 Equation 3-3
𝐶𝐶

1 𝑡𝑡
𝑉𝑉(𝑡𝑡) = � 𝑖𝑖(𝑡𝑡)𝑑𝑑𝑑𝑑 + 𝑉𝑉(𝑡𝑡 − ∆𝑡𝑡) Equation 3-4
𝐶𝐶 𝑡𝑡−∆𝑡𝑡

Applying trapezoidal rule of integration results in Equation 3-5.

2𝐶𝐶 2𝐶𝐶
𝑖𝑖(𝑡𝑡) = ∗ 𝑉𝑉(𝑡𝑡) − ∗ 𝑉𝑉(𝑡𝑡 − ∆𝑡𝑡) − 𝑖𝑖(𝑡𝑡 − ∆𝑡𝑡) Equation 3-5
∆𝑡𝑡 ∆𝑡𝑡

2
CBuilder Tutorial: Variable Capacitor

Figure 3.3: IH: Current Injection

Define:

2𝐶𝐶
𝐼𝐼𝐼𝐼(𝑡𝑡) = − ∗ 𝑉𝑉(𝑡𝑡 − ∆𝑡𝑡) − 𝑖𝑖(𝑡𝑡 − ∆𝑡𝑡) Equation 3-6
∆𝑡𝑡

2𝐶𝐶
𝑖𝑖(𝑡𝑡) = ∗ 𝑉𝑉(𝑡𝑡) + 𝐼𝐼𝐼𝐼(𝑡𝑡) Equation 3-7
∆𝑡𝑡

3.3 DRAW GRAPHICS AND ADD PARAMETERS


• Draw a capacitor icon similar to that shown in Figure 3.4.

Figure 3.4: Capacitor Icon

The component icon for the variable capacitor includes two power system nodes
and one signal input as shown in Figure 3.4. The signal input ’CVAL’ is used to read
in variable capacitance values.
• Add a parameter ’Cinit’ to specify the initial value of capacitance.
• A power system node is created by creating an I/O Point/Node and selecting “PSYS
Node” as the connection type.

3
CBuilder Tutorial: Variable Capacitor

3.4 ADDING THE MODEL CODE


• Select the ’C File Associations’ tab.

• Select the icon to Add New Association.


Creating the C File Associations for the component automatically generates the
following associations:
INPUTS: CVAL, capacitance value signal input
NODES: N1, N2 power system nodes
PARAMETERS: Cinit, initial value of capacitance
In addition to those listed above, the following additional associations need to be
made:
GVALUES: A conductance value (1/R) that the component places between the nodes
to which it is connected. Recall, that the representation of the capacitor requires a
resistor equal to ∆t/(2C) to be placed between the nodes to which the component is
connected. The equivalent conductance is equal to 1/R= 2C/∆t. To add the GVALUE
association select the Add Variable to .h File “+” button from the C File Associations
Tab and select New GValue. Edit new gvalue window will appear at the right hand
side when the gvalue line is selected. Type will be Real and enter the variable name
to which the conductance value will be assigned in the .c code.

Figure 3.5: Adding Gvalues to Power System Model

INJECTIONS: The capacitance model injects current into node2 and out of node1.
To add an injection, click the + on the injections section. Type: REAL. Enter the name
for the current injection variable (CINJN1). Select the down arrow icon for the

4
CBuilder Tutorial: Variable Capacitor

CINJN1 variable and select Node N1. Add another current injection variable
(CINJN2) and associate it with Node N2.

• Selecting File−>Save causes the newly added GVALUES and INJECTIONS variables to
be written to the .h file so they can be accessed in the .c file.

• Write the ’c’ code. Select the icon to edit the .c file.

Basic Algorithm:
Read 2 node voltages v1(t), v2(t)
Compute V(t)= v1(t) − v2(t)
Compute branch current: i(t)= 2C/∆t*V + IH(t−dt)
note: IH(t) from previous time−step
Read Capacitance Value Compute Gc= 2C/∆t
Set new Gc value for network solution
Compute Injection Current: IH(t)= −2C/∆t*V − i(t)
Set injection current for node1 and node2

The RAM section initializes the history term current IH(t−dt) to


0.0 and computes the constant 1/∆t for use in the CODE: section.
Static:
double dt, invdt, Ih, Gcap, Vbra, ib;

RAM:
dt= getTime-step();
invdt= 1.0/dt;
Ih= 0.0;
Gcap= 2.0 * Cinit * 1.0e−6 * invdt;

5
CBuilder Tutorial: Variable Capacitor

The CODE: section computes the branch current for the capacitor, the new
conductance for the capacitance and the current injections into the nodes between
which the component is connected. All of the code is assigned to the BEGIN_T0
portion since it is required to compute the injection currents. The capacitance value
is read in as micro−farads (i.e. 1.0 is interpreted as 1.0e−6 farads) so the CVAL
variable must be multiplied by 1.0e−6before it can be used.
CODE:

BEGIN_T0:

/* Compute branch current */


Vbra= N1 − N2;
ib= Gcap*Vbra + Ih;

/* Compute new value of Cfarad */


Gcap= 2.0 * CVAL * 1.0e−6 * invdt;
GCVAL= Gcap;

/* Compute new History Current */


Ih= −Gcap*Vbra − ib;

/* Write current injections into N1, N2 */


/* +ve means current out of node */
CINJN1= Ih;
CINJN2= −Ih;

3.5 ADDING AN OPTIONALLY MONITORED VARIABLE


It is often desirable to permit the user to optionally monitor various internal variables
associated with a component. Monitoring of such internal variables may be useful for
debugging when the component is part of a larger control circuit. The monitoring may be
included without adding additional output points to the component. The following
procedure is suggested:
1. Add a Yes/No Toggle type parameter which permits the user to select whether the
current is to be monitored in a new section called “MONITORING”. (see 1 of Figure 3.6).
2. Add a Name type parameter which permits the user to enter a name for the monitored

6
CBuilder Tutorial: Variable Capacitor

current. The Name entry can be made conditional on the monitoring being enabled in a
new section called “Signal Names” (see 2 of Figure 3.6).
3. Add a new generic output variable which is active only if the monitoring is enabled in
the C File Association.
4. Add statements to the RTDS C code to assign the branch current to the monitored
variable.

Figure 3.6 Adding a Monitored Variable in CBuilder

The new parameters MonI and Iname must be added to the .h file. Select the Add New
IO Points/Nodes/Parameters/Computations to Association icon from the C File Associations
tab to add these new parameters.

Figure 3.7: Adding New IO Points to C File Association

7
CBuilder Tutorial: Variable Capacitor

To add the monitored variable parameter to the .h file, left click the Add Variable to .h File
button under the C File Associations tab. Select create: Generic Outputs from the pulldown
menu associated with the Section: field and set Type: to REAL. Enter a variable name (e.g.
IMON) to be used for assignment of the monitored variable in the .c file. After selecting OK,
the Edit Output menu appears in which additional parameters for the output variable may
be specified.

Figure 3.8: Editing The Generic Output Section

Type: REAL
H File VAR: IMON
Output Name: Iname
Group: “Branch Currents”
Min Value: −100.0
Max Value: +100.0
Unit: “kA”
Condition: MonI==1
Min and Max values are used as the default limits for a meter or plot component assigned
to display the signal specified by Output Name. The specified unit name also appears on the
meter or plot component in RSCAD/RunTime.
The create: OUTPUTS data line for the monitored output variable appears as:

Figure 3.9: Creating a Generic Output

8
CBuilder Tutorial: Variable Capacitor

• “1” is the parameter name for .c file.


• “2” is the signal name available in RSCAD/RunTime.
The C code statement to write out the monitored variable is as follows:
IMON = ib;

• The current monitoring should be assigned in the T0_T2 section of the CODE.

9
20210310

4 MULTI-MASS SYSTEM

4.1 INTRODUCTION

Representation of the mechanical characteristics of turbine generator units in


electromagnetic transients programs is necessary if the interaction between the electrical
system and mechanical system is to be studied. In some situations a resonant condition may
exist between the electrical system and the mechanical system which can lead to torsional
oscillations which stress the mechanical couplings between the various turbines and
between the turbine and generator. Perhaps the best documented case of such a resonance
was at the Navajo Project, a coal fired generation unit located in northern Arizona, U.S.A.
[1]. Data from the Navajo Project was used to develop a first and second benchmark model
for torsional oscillations [2],[3].

This document outlines how the mechanical characteristics of a turbine−generator system


may be incorporated into a model for use on the RTDS. Once the equations for the
multi−mass system have been developed, the procedure for implementing the
corresponding algorithm using the CBuilder feature under RSCAD is documented.

Development of the equations representing the mechanical system follows that presented
in Kundar [4]. Firstly, the equations of motion for a single mass rotating about an axis are
developed. The analysis is then expanded to account for two masses connected by a shaft
and finally generalized to multiple masses.

1
Tutorial: Multi-Mass System

4.2 SINGLE MASS ROTATING ABOUT AND AXIS

4.2.1 EQUATIONS OF MOTION REPRESENTING A SINGLE MASS ROTATING ABOUT AN AXIS

Figure 4.1: Single Mass Rotating Motion

The basic equation of motion for a rotating mass stems from Newton’s Second Law of motion
(commonly stated as F=mA) where the Force is the difference between the mechanical
torque applied by a turbine and the electrical torque applied across the air−gap of the
generator. Acceleration for the rotating mass is the rate of change of its rotational speed
(𝜔𝑚 ). Instead of the mass of the rotating body, the mass’ moment of inertia (J) is used. The
moment of inertia considers both the rotating body’s mass and its distribution around the
axis of rotation.

𝑑𝜔𝑚 [1]
𝐽 = 𝑇𝑚− 𝑇𝑒
𝑑𝑡

J Mass’ moment of Inertia in kg·m2


𝜔𝑚 rotational speed of the mass in mech. rad/sec
𝑇𝑚 Mechanical torque applied by the turbine (N·m)
𝑇𝑒 Electrical torque applied by the generator (N·m)
(1 N = 1 kg·m/sec2)

It is important to note that 𝜔𝑚 in [1] above represents the mechanical rotational speed of
the machine in rad/sec. It is to be differentiated from the machine’s electrical rotational
speed. Mechanical speed and electrical speed is the same for a machine with only one pole
pair. Machines that have more than a single pole pair will have a slower mechanical
rotational speed than one with just one pole pair.

𝜔𝑒 = 𝜔𝑚 ∗ 𝑛 (n is the number of pole pairs)

2
Tutorial: Multi-Mass System

By using the per−unit inertia constant, H, which is defined as the mass’ kinetic energy in
watt−seconds at rated speed, as opposed to the moment of inertia, equation [1] can be
expressed in terms of electrical rad/sec. H and J are related as –

2
1 𝐽𝜔0𝑚
𝐻=
2 𝑉𝐴𝑏𝑎𝑠𝑒
𝐻 [2]
𝐽 = 2 2 𝑉𝐴𝑏𝑎𝑠𝑒
𝜔0𝑚

𝜔20𝑚 rated rotational speed of the mass in mechanical rad/sec.


𝑉𝐴𝑏𝑎𝑠𝑒 Volt−Amp base for the system

Substituting [2] into [1] yields –

2𝐻 𝑑𝜔𝑚 [3]
2 𝑉𝐴𝑏𝑎𝑠𝑒 𝑑𝑡 = 𝑇𝑚 − 𝑇𝑒
𝜔0𝑚

Noting that –

𝜔𝑚 𝜔𝑟 [4]
= = 𝜔𝑝𝑢
𝜔0𝑚 𝜔0
𝑉𝐴𝑏𝑎𝑠𝑒 𝑇 [5]
𝑇𝑏𝑎𝑠𝑒 = , = 𝑇𝑝𝑢
𝜔0𝑚 𝑇𝑏𝑎𝑠𝑒

𝜔𝑟 rotational speed of the mass in electrical rad/sec


𝜔0 rated rotational speed of the mass in electrical rad/sec.
𝑇𝑏𝑎𝑠𝑒 base value of mechanical torque we re−arrange equation [3]
such that equations [4] and [5] may be substituted.

𝑑 𝜔𝑚 𝑇𝑚 − 𝑇𝑒 [6]
2𝐻 [ ]=
𝑑𝑡 𝜔0𝑚 𝑉𝐴𝑏𝑎𝑠𝑒 /𝜔0𝑚
𝑑 𝜔𝑟 𝑇𝑚 − 𝑇𝑒 [7]
2𝐻 [ ]=
𝑑𝑡 𝜔0 𝑉𝐴𝑏𝑎𝑠𝑒 /𝜔0𝑚
𝑑 𝜔𝑟 𝑇𝑚 − 𝑇𝑒 [8]
2𝐻 [ ]=
𝑑𝑡 𝜔0 𝑇𝑏𝑎𝑠𝑒

Equation [8] above relates the per−unit applied torque to the per−unit rotational speed of
the mass. Implementation of equation [8] into the the RTDS solution algorithm may be done
by applying trapezoidal rule to yield −
𝜔𝑝𝑢(𝑡) − 𝜔𝑝𝑢(𝑡 − ∆𝑡) 𝑇𝑎𝑝𝑢(𝑡) + 𝑇𝑎𝑝𝑢(𝑡 − ∆𝑡) [9]
2𝐻 =
∆𝑡 2

3
Tutorial: Multi-Mass System

𝑇𝑎𝑝𝑢 per-unit accelerating torque

𝑇𝑎𝑝𝑢 = (𝑇𝑚 − 𝑇𝑒 )/ 𝑇𝑏𝑎𝑠𝑒

At the beginning of the simulation time−step all of the quantities in [9] listed as functions of
(t − ∆𝑡) are known, as are the constants 2𝐻 and ∆𝑡. The most recently computed value of
𝑇𝑎𝑝𝑢 is used as 𝑇𝑎𝑝𝑢(𝑡) . This leaves only 𝜔𝑝𝑢(𝑡) to be computed.

To demonstrate the action of [9], we can apply a constant 1 per−unit torque with no
electrical torque (ie. open circuit conditions for a frictionless generator) and note that the
mass’ speed linearly increases. Under such conditions the rotating mass reaches 1 per−unit
rotational speed after 2𝐻 seconds. 2𝐻 is referred to as the mechanical starting time.

Figure 4.2: Mechanical Starting Time

4.3 DAMPING

In the equations for the rotating mass described above, there was no consideration of
damping. Removing the applied torque in the example above results in the mass rotating at
𝜔𝑝𝑢 indefinitely. In [4] a damping term proportional to ∆𝜔𝑟 is introduced. Adding such a
term to [8] yields –

𝑑 𝜔𝑟 𝑇𝑚 − 𝑇𝑒 𝜔𝑟 [10]
2𝐻 [ ] = − 𝐷∆ [ ]
𝑑𝑡 𝜔0 𝑇𝑏𝑎𝑠𝑒 𝜔0

𝜔
Damping proportional to speed deviation (ie. 𝐷∆ [𝜔𝑟 ]) results in an accelerating torque
0
when the speed of the rotating mass is less than the rated speed. Such a representation is
reasonable for small perturbations of speed around the rated speed. However, if the mass
is to be used as part of a generator − turbine model which is required to have large deviations
from synchronous speed, the chosen representation of damping leads to unrealistic
behavior. Take for instance the case where the generator is to be started from standstill. At

4
Tutorial: Multi-Mass System

zero speed the speed deviation is − 1𝑝𝑢 and according to [10] the mass is subjected to an
accelerating torque of + 𝐷𝑝𝑢 .

A physical interpretation of the damping term proportional to speed deviation is given in the
discussion to reference [5].

A damping term proportional to per−unit speed, representing the friction and windage
losses, can be introduced into [8] to obtain [1]. The addition of a speed proportional damping
term changes the response of the mass to a constant mechanical torque input as shown in
Figure 4.3 (compare with Figure 4.2 which shows the response with no damping term).

𝑑 𝜔𝑟 𝑇𝑚 − 𝑇𝑒 𝜔𝑟 [11]
2𝐻 [ ] = − 𝐷[ ]
𝑑𝑡 𝜔0 𝑇𝑏𝑎𝑠𝑒 𝜔0

Figure 4.3: Response With Speed Proportional Damping

Removal of the applied torque, using [11] to represent the rotating mass, results in the mass’
rotational speed slowing to 0.0. Note that equation [11] has the same form as a first order
lag with a gain of 1/D and a time−constant of 2H/D seconds.

5
Tutorial: Multi-Mass System

1
𝐸(𝑡) = 𝑇 − 𝑤(𝑡)
𝐷 (𝑡)
1
𝑤(𝑡) = 𝐸
𝑠(2𝐻/𝐷) (𝑡)
1
𝑤(𝑡) = [1 / 𝐷 ∗ 𝑇(𝑡) − 𝑤(𝑡) ]
𝑠(2𝐻/𝐷)

1
𝑤(𝑡) = ∫[𝑇(𝑡) − 𝐷 ∗ 𝑤(𝑡) ] 𝑑𝑡
2𝐻

1st order lag function with Gain= 1 / 𝐷 and time constant = 2𝐻/𝐷. Compare with equation [11]
above.

4.4 TWO ROTATING MASSES COUPLED BY A SHAFT

4.4.1 EQUATIONS OF MOTION FOR 2 ROTATING MASSES COUPLED BY A SHAFT

Figure 4.4: Two Rotating Masses

The equations developed above are now extended to two masses coupled by a shaft. One
mass represents a turbine and the other the rotating mass of the generator. The mass of the
shaft itself is lumped proportionally into the rotating mass’ inertia constants. The shaft
connecting the generator mass to the turbine mass is considered as a torsional spring.
Torque transferred across the shaft between the turbine and the generator results in

6
Tutorial: Multi-Mass System

twisting of the shaft. The amount of twist depends on the torque transferred across the shaft
and on the torsional strength of the material comprising the shaft.

𝑇 = 𝐾𝜃𝑚 [12]

𝑇 Torque transferred across the shaft (N¡m)


𝜃𝑚 Mechanical angle of twist across
the shaft (rad)
𝐾 Shaft Stiffness (N¡m/rad)

The shaft stiffness constant (𝐾) defines the torque required to create an angular twist of 1
radian across the shaft. Values of K are typically very large since the torque, in N¡m, required
to twist a large turbo generator shaft by 1 radian (~57 degrees) is significant. In order to use
[12] with [11] developed above, equation [12] needs to be converted so as to relate per−unit
torque to per−unit angle. Using the base values for mechanical angle and torque as shown
below −

𝜃𝑚 𝑏𝑎𝑠𝑒 = 𝜔0𝑚
𝑉𝐴𝑏𝑎𝑠𝑒
𝑇𝑏𝑎𝑠𝑒 =
𝜔0𝑚

the base shaft stiffness may be computed as –

𝑉𝐴𝑏𝑎𝑠𝑒
𝐾𝑏𝑎𝑠𝑒 =
𝜔0𝑚

𝜔0𝑚 rated rotational speed of the mass in mech. rad/sec.

The torque applied by the shaft to the masses to which it is attached is given by –

𝑇𝑇𝐺 = 𝐾𝑇𝐺 (𝜃𝑇 − 𝜃𝐺)

𝑇 in pu if 𝐾𝑇𝐺 𝜃 in pu

The equations of motion for the two rotating masses can now be written –

Generator Mass 𝑑𝑤𝑔𝑒𝑛 [13]


2𝐻 = 𝑇𝑡𝑢𝑟𝑏 − 𝑇𝑒 − 𝐷𝑔𝑒𝑛 𝜔𝑔𝑒𝑛
𝑑𝑡
Turbine Mass 𝑑𝑤𝑔𝑒𝑛 [14]
2𝐻 = 𝑇𝑡𝑢𝑟𝑏 − 𝐷𝑡𝑢𝑟𝑏 𝜔𝑡𝑢𝑟𝑏
𝑑𝑡
Shaft Angle 𝑇𝑡𝑢𝑟𝑏 − 𝑇𝑒 [15]
𝜃𝑇 − 𝜃𝐺 =
𝐾𝑇𝐺
All quantities in per− unit

7
Tutorial: Multi-Mass System

Equations [13] and [14] can be solved numerically using the trapezoidal rule as –

𝜔(𝑡) − 𝜔(𝑡 − ∆𝑡) 𝜔(𝑡) − 𝜔(𝑡 − ∆𝑡) 𝜃(𝑡) + 𝜃(𝑡 − ∆𝑡) 𝑇(𝑡) + 𝑇(𝑡 − ∆𝑡) [16]
2𝐻 + 𝐷 +𝐾 =
∆𝑡 2 2 2

All of the history terms (ie. those at 𝑡 − ∆𝑡) are known at the start of a new time−step. 2𝐻,
𝐷, K and ∆𝑡 are constants and the new value of applied torque 𝑇(𝑡) is assumed to be known.
The values 𝜔(𝑡) and 𝜃(𝑡) are unknown at the beginning of the time−step. Using the relation
(17a) and applying trapezoidal rule an expression for 𝜃(𝑡) can be derived in terms of 𝜔(𝑡).

𝑑𝜃 [17a]
= 𝜔
𝑑𝑡
𝜃(𝑡) − 𝜃(𝑡 − ∆𝑡) 𝜔(𝑡) + 𝜔(𝑡 − ∆𝑡) [17b]
=
𝑑𝑡 2
∆𝑡 [17c]
𝜃(𝑡) = [𝜔(𝑡) + 𝜔(𝑡 − ∆𝑡] + 𝜃(𝑡 − ∆𝑡)
2

Equation [17c] can be substituted into [16] to eliminate the 𝜃(𝑡) term and leave 𝜔(𝑡) as the
only unknown.

2 ∆𝑡
𝜔(𝑡) [ 2𝐻 + 𝐷 + 𝐾] =
∆𝑡 2

2 ∆𝑡 [18]
𝑇(𝑡) + 𝑇(𝑡 − ∆𝑡) + 𝜔(𝑡 − ∆𝑡) [ 2𝐻 − 𝐷 − 𝐾] − 2𝐾𝜃(𝑡 − ∆𝑡)
∆𝑡 2

2 ∆𝑡 [19]
𝑑𝑒𝑓𝑖𝑛𝑒 𝐴 = [ 2𝐻 + 𝐷 + 𝐾]
∆𝑡 2
2 ∆𝑡
𝐵 = [ 2𝐻 − 𝐷 − 𝐾]
∆𝑡 2

solving for 𝜔(𝑡) in [18] substituting A and B as defined above yields –

𝜔(𝑡) = 𝐴−1 [𝑇(𝑡) + 𝑇(𝑡 − ∆𝑡) + 𝜔(𝑡 − ∆𝑡) [𝐵] − 2𝐾𝜃(𝑡 − ∆𝑡)] [20]

Equation [20] is solved for each mass substituting in the appropriate parameters for 𝐻, 𝐷
and 𝑇.

It is worth noting that the constants defined in [19] include terms which are multiplied by
2/∆𝑡 and ∆𝑡 /2. For a typical simulation time−step of 50 𝜇𝑠 these multiplying factors vary by
ten orders of magnitude. Given typical values for 𝐻 and 𝐾 the constants can be computed
as –

8
Tutorial: Multi-Mass System

2 2.0
∗ 2𝐻 = ∗ 2 ∗ 0.8688 = 69,504.0
∆𝑡 50𝑒 −6
∆𝑡 50𝑒 −6
∗𝐾 = ∗ 14042.92 = 0.3511
2 2.0

Even with the typically large difference in magnitude between 𝐻 and 𝐾 the elements
comprising constants 𝐴 and 𝐵 are still different by five orders of magnitude. As for the
damping factor (𝐷) which is also required to compute 𝐴 and 𝐵, there is little in the way of
typical data available in the literature. In many cases the damping is set to zero.

4.5 MULTI-MASS MODEL USING MATRIX FORMULATION

Representation of n masses coupled by shaft segments is straight forward. By arranging the


equations developed for 2 masses in matrix form, the solution can be generalized to any
number of masses. For the present model, matrix sizes are dimensioned to permit eight
turbine masses, one generator mass and two rotating exciter masses for a total of 11 coupled
masses.

Figure 4.5: Multi Mass

Equation [20] re−written in matrix form is –

[𝜔𝑛 (𝑡)] = [𝐴−1 ] [[𝑇𝑛 (𝑡 − ∆𝑡)] + [𝜔𝑛 (𝑡 − ∆𝑡)][𝐵] − [2𝐾][𝜃𝑛 (𝑡 − ∆𝑡)] [21]

where –
𝑛 mass index 1 . . . number of masses

[𝜔𝑛 (𝑡)] newly computed speed of mass n

[𝐴−1 ] inverse of tri−diagonal matrix A (full matrix)


𝑇𝑛 (𝑡) latest value of torque applied to mass n

9
Tutorial: Multi-Mass System

𝑇𝑛 (𝑡 − ∆𝑡) previous value of torque applied to mass n

[𝜔𝑛 (𝑡)] previously computed value of speed of mass n

[𝐵] tri−diagonal matrix of B constants


[2𝐾] tri−diagonal matrix of 2 ∗ 𝐾 spring constants

[𝜃𝑛 (𝑡 − ∆𝑡)] previous value of mass angle

[𝐷]: tri−diagonal damping coefficient matrix used in the


calculation of the 𝐴 and 𝐵 matrices.

The damping matrix includes both terms for the diagonal and off diagonal elements. Diagonal
elements represent the self−damping factors (friction, windage) described above.
Off−diagonal terms represent the damping due to the twisting of the shaft. Under transient
conditions, when a varying torque is applied across the shaft segments, the back and forth
twisting of the shaft results in heating and hence some damping. Data for this mutual
damping is often not available. Note that the mutual damping is across a shaft segment so
that only the n−1, n and n+1 elements of the damping matrix have non−zero terms.

𝑋11 𝑋12 0 0 [22]


𝑋21 𝑋22 𝑋23 0
𝐷=[ ]
0 𝑋32 𝑋33 𝑋34
0 0 𝑋43 𝑋44
𝑋𝑚𝑛 non-zero elements

Damping Matrix form for 4 mass system

10
Tutorial: Multi-Mass System

4.6 MULTI-MASS MODEL ALGORTITHM

The algorithm for the multi−mass model is based on the solution of equation [21] above. The
dimension of matrices and column vectors required for the solution is determined by the
number of masses that constitute the system under study. Solution of [21] requires that
mechanical torque applied to the turbines, electrical torque from the generator, a number
of constants and information from the previous time−step are known.

Mechanical torque to each turbine is provided as input to the multimass model from a
separate component which models the speed control and torque production. Electrical
torque is provided as output from the synchronous machine model or from the induction
motor model and passed to the multimass model. User entered data, 𝐻𝑛 , 𝐾𝑛 , 𝐷𝑛 and
simulation time−step are used to compute constants 𝐴1, 𝐵 and [2𝐾].

Solution of [21] solves for mass rotational speeds from which mass angles and shaft torques
can be computed. These quantities are provided as output from the multimass model.

A mechanism is provided to lock all of the modelled mass speeds to a specified speed (often
synchronous speed). A lock/free switch can be created in RSCAD/RunTime as part of the
model, or the user can provide the lock/free signal input from an external signal. When in
lock mode, all mass rotational speeds are set equal to the specified speed. Lock mode is
often used to temporarily bypass the turbine dynamics during initialization of the power
system to which the multimass system is connected.

It is also possible operate the multimass model so as to lump all of the masses into a single
rotating mass. In this way the shaft dynamics can be removed. A single/multi switch can be
created in RSCAD/RunTime as part of the model, or the user can specify that the single/multi
signal come from an external source. When in single mode, the torques applied to all of the
turbine masses are added to form a single mechanical torque input. The equivalent mass’
inertia constant is equal to the sum of all modelled masses. The sum of all the self damping
terms is used for the damping.

4.7 MODEL DEVELOPMENT USING C-BUILDER

Development of the multi−mass model requires the following steps −

4.7.1 CONCEPTUAL LAYOUT OF THE NEW COMPONENT

a. Which inputs should be connected using wires


b. Which outputs should be connected using wires
c. appearance of the component icon
d. options which change appearance of icon
e. What data is required to prepare the constants

11
Tutorial: Multi-Mass System

f. How to group related data fields


g. What monitoring options should be available
h. control system or power system component type

4.7.2 COMPONENT ICON CREATION IN C−BUILDER (GRAPHICS & NODES)

a. Define component as a Control system typecomponent


b. locate and place all of the input / output points and add associated logic blocks
c. Draw component icon portions which do not require conditional logic.
d. Draw component icon portions for each option which changes the component’s
appearance.

4.7.3 DEFINE USER SUPPLIED DATA MENUS (PARAMETERS)

a. Add all of the data sections defined under I(f) above.


b. Add logic to parameters so the parameter entry fields are visible only when the
corresponding options are selected.

4.7.4 WRITE DATA PREPARATION PORTION OF THE ‘C’ PROGRAM

a. Create C File and Declare required variables


b. Compute constants required for the executable code
c. Optionally write critical data to the .map file

4.7.5 WRITE ‘C’ CODE TO IMPLEMENT THE ALGORITHM

a. Declare required variables


b. Create variables for named output signals
c. Create variables for named input signals

4.7.6 TEST NEWLY DEVELOPED MODEL

a. Check data preparation to ensure constants are computed correctly.


b. Run simulation cases to confirm basic operation
c. Run simulation cases to verify against benchmark cases

4.7.7 CONCEPTUAL LAYOUT OF THE NEW COMPONENT

a. Torque inputs to each turbine section and the generator (𝑇𝑒) will be connected to input
points. The user will thus be able to interconnect the governor/torque production
model to the multimass model via wires. The synchronous generator model’s Te
output signal can also be connected to the multimass model via a wire component.

12
Tutorial: Multi-Mass System

b. The synchronous generator model requires the generator mass speed signal as an
input. Note that the speed signal may change very little from simulation time−step
to time−step. Within the GPC processor, computations are done using double (64 bit)
precision. However, when the data is sent from the multimass model to the generator
model over the rack backplane, the speed signal is converted to a single precision
number. Rather than sending the speed signal directly from the multimass to the
machine model, a delta−omega (ie. change from synchronous speed) signal is sent
instead.
Input and output points for the multimass model are shown in Figure 4.6.

Figure 4.6: Input and Output Points

c. The component’s appearance is shown in Figure 4.7. Each of the turbine torque inputs
connects to an icon representing a single turbine mass. Electrical torque is connected
as an input to an icon representing the rotating portion of the generator. A change
from synchronous speed signal for the generator mass is available as an output. At
synchronous speed this signal is equal to 0.0. Two exciter masses are connected on
the right side of the generator mass.

Figure 4.7: Multimass Component Appearance

13
Tutorial: Multi-Mass System

d. There are a number of options which may be set by the user which require the
appearance of the component icon to change −

• Number of turbine masses (1−8)


• Number of exciter masses (0−2)
• Lock/Free switch input mode
• Single/Multi switch input mode

The generator mass and HP turbine mass are always drawn. If the number of turbines is set
less than 8, then unused turbine icons are replaced by extending the shaft between the
generator and last turbine. Exciter masses are drawn only if selected.

Figure 4.8: Extended Shaft Between the Generator and Turbine

Multi−Mass component icon with 4 turbine masses, 1 exciter mass and switch inputs created
as part of the model.

e. The following data must be supplied by the user before the constants required for
the algorithm can be computed −

𝐻 Inertia Constant for each mass (MW sec / MVA)


𝐾 Spring Constant for each shaft (in pu)
𝐷𝑠 Self Damping for each mass (in pu)
𝐷𝑚 Mutual Damping for each shaft section (in pu)

Logic is included as part of the component so that only the data required for the number of
selected turbines needs to be entered. Data items not required for the selected
configuration appear grey in the menus and cannot be selected for input.

14
Tutorial: Multi-Mass System

f. The following data tabs are defined for the multi−mass component −

CONFIGURATION Basic configuration options


INERTIA CONSTANTS 𝐻 values for each mass
SHAFT SPRING CONSTANTS 𝐾 values for each shaft section
SELF DAMPING 𝐷𝑠 values for each mass
MUTUAL DAMPING 𝐷𝑚 values for each shaft section
MONITORING OPTION TABS see below

g. The user is able to select the following items for monitoring.

These are named variables and as such there is no wire protruding from the component icon
for any of these outputs.

• Mass Speed
• Mass Angle with respect to the generator
• Shaft Torque

Tabs are included in the component icon to facilitate selection of the signals to be monitored
and the name assigned to each monitored variable. Logic is included as part of the
component to permit selection of only those variables which are computed for the specified
configuration.

h. C−Builder requires that the user specify whether the component is a power system
or control system type component. Power system components connect to power
system nodes as defined by node icons in RSCAD/Draft and often contribute current
injections into those nodes to which the component is connected. Control system
components do not connect to power system nodes and are not able to supply current
injections into the power system network.

The GPC processor to which a control system component is allocated automatically


becomes a control system processor for the simulation case and only other control
system components may be allocated to that processor. It is not possible to allocate
both control system and power system components to the same GPC processor.

4.7.8 COMPONENT ICON CREATION IN C−BUILDER

The C−Builder Users Manual should be consulted for additional details on defining the
component icon. Information provided here outlines the major steps required to complete
the icon associated with the multi−mass model.

a. Define the Component as a Control System Component

15
Tutorial: Multi-Mass System

When a new component is created the user is prompted to select whether the component
type is control or power system. For the multimass model select control.

The component type can be changed after a new component is created from the “Other”
tab.

b. Define the Input/Output points and associated conditional logic under the IO Points Tab

Torque input for the HP Turbine, electrical Torque input to the generator and generator
delta−omega output are always present. No logic needs to be placed around these input /
output points. Select the create input/output point button from the drawing toolbar and left
click when the circle is positioned as shown in Figure 4.9. Use the create input/output
function to create points for the HPT input, The input and delta−omega output signals. A
menu for the input/output point name and type (input or output, int or real) appears at the
bottom when a input/output point is selected. All of the torque inputs are specified as real
type.

Figure 4.9: IO Points

The number of turbines included in each instance of the component is set by the user.
Torque inputs for turbines other than for the HP turbine need to be placed inside conditional
logic so that the inputs are enabled only when dictated by the number of selected turbines.
To define a new condition, under the IO Points section, left click the add condition button
and select the if option from the pull down. Enter the logic condition as shown below. The
parameter nturb, defined later, holds the number of turbines selected by the user.

16
Tutorial: Multi-Mass System

Figure 4.10: Input/Output Points Details

While the If (nturb>1) −EndIf block is highlighted in the IO Points section, add the input point
for the IPA torque signal. The new input point is created inside the highlighted If−EndIf logic.

Data under the IO Points tab should appear as shown in Figure 4.11 once all of the input /
output points and associated logic has been entered.

17
Tutorial: Multi-Mass System

Figure 4.11: Data Under the I/O Points Tab

18
Tutorial: Multi-Mass System

c. Draw the unconditional graphics.

d. Draw the conditional graphics.

Turbine blocks which are not enabled are replaced by a shaft section for the component’s
appearance in RSCAD/Draft. Exciter masses are only drawn if enabled. L/F (Lock/Free) and
S/M (Single/Multi) input wires are only drawn if the user selects these inputs are to come
from a signal input rather than an RSCAD/RunTime switch.

To add a logic condition under the Graphics tab select the Add Condition button and choose
the if option from the pulldown. Enter the condition appropriate for the turbine section
which is to be drawn within the logic condition. Since either a shaft section or turbine icon
will be drawn, an if−else−endifstructure is required. To add an else section, highlight the
newly created if−EndIf condition by left clicking on the If statement (the If and EndIf lines
will turn red). Left click the Add Condition button and this time select Else from the pull down
that appears.

The condition logic should appear as follows –

if (nturb>1)
Else
EndIf

To add drawing commands into a particular condition, left click the small arrow next to the
logic condition in which the drawing commands are to be placed. The condition turns red
and the arrow should point downwards. Use the drawing commands to draw the shapes
required for the icon portion. Drawing commands are placed within the highlighted logic
condition. To draw the icon portion in the 𝑒𝑙𝑠𝑒 section left click the small arrow next to the
if line so that it again points to the right. The components drawn within the 𝑖𝑓 section
disappear from the drawing canvas. Now left click the small arrow next to the 𝑒𝑙𝑠𝑒 line. The
line becomes red and the arrow points downward. Draw the shapes required for the 𝑒𝑙𝑠𝑒
portion of the icon. Repeat the above procedure for each turbine section.

The multimass model permits representation of up to 2 rotating exciters. No torque input is


applied to these exciter masses. A variable named “EXCen” is set to 0/1/2 by the user to
indicate the number of exciter masses to be modelled. The logic for drawing the exciters can
be arranged as follows –
If (EXCen > 0)
Draw shapes to represent exciter net to generator
EndIf

If (EXCen == 2)
Draw shapes to represent 2nd exciter
EndIf

19
Tutorial: Multi-Mass System

4.7.9 ADD PARAMETER ENTRY MENUS

a. Now that the component icon, including input / output points and conditional graphics
have been completed the menus for data entry are created. These menus are defined
under the Parameters tab in the control pane area of the RSCAD/C−Builder window.

The following sections are required for the multimass component.

• CONFIGURATION: basic configuration parameters including the number of turbines


to be represented (nturb) and how many exciter masses are to be modelled (EXCen)
• SELF DAMPING: the self damping factors for each modelled mass.
• MUTUAL DAMPING: the damping factors for the shafts connecting the modelled
masses.
• SHAFT SPRING CONSTANTS: the spring constants for the shafts connecting the
modelled masses.
• INERTIA CONSTANTS: the inertia constants for each modelled mass.
• MASS SPEED MONITORING ENABLE: enable speed monitoring for each modelled
mass.
• MASS SPEED SIGNAL NAMES: signal name for each monitored mass speed signal.
• MASS ANGLE MONITORING ENABLE: enable monitoring for the angle between each
modelled mass.
• MASS ANGLE SIGNAL NAMES: signal name for each monitored mass angle signal.
• SHAFT TORQUE MONITORING ENABLE: enable shaft torque monitoring for each
modelled shaft segment.
• SHAFT TORQUE SIGNAL NAMES: signal name for each monitored shaft torque signal.

To create the component data entry sections listed above, left click the add section button
in the control pane area of the RSCAD/C− Builder window. Enter the Section name in the
menu that appears.

None of the sections need an associated logic condition.


Once all of the data entry sections have been created, left click the small arrow next to the
section to which the parameters are to be added. The arrow points down and the section
heading is highlighted. Left click the add parameter button and fill in the appropriate data in
the menu that appears. The new parameter entry element is added under the highlighted
section.

20
Tutorial: Multi-Mass System

Figure 4.12: Parameters Tab

b. Some parameters should only permit data entry when required.

For example, if the user specifies that only 1 turbine mass is to be modelled (nturb = 1) then
data for the IPA, IPB . . . LPA turbine masses is not necessary and the associated parameters
should not permit data entry. To facilitate this, a logic condition may be added to each
parameter.

To enable data entry for the IPA inertia constant only when the IPA turbine is to be modelled,
add the following logic condition to the IPAH parameter entry −

nturb>1

If the nturb parameter defined under the CONFIGURATION menu is set to 1 by the user then
the IPAH parameter entry line will be greyed out.

21
Tutorial: Multi-Mass System

Names for monitored signals should only be entered if the associated turbine is modelled
AND if the user has enabled that signal for monitoring. In this case the AND function can be
used in the logic condition –

nturb>1 &&HPIPATen

4.7.10 WRITE DATA PREPARATION PORTION OF THE ‘C’ PROGRAM

a. Create C File and Declare Variables

There are two ‘C’ code programs that must be written by the user to complete the model.
Firstly, a ‘C’ program which computes the constants required by the algorithm must be
written. Secondly, the program which executes the algorithm for the model must be written.
Only the second program runs on the RTDS hardware. Both ‘C’ programs are stored in the
same file. A template for the ‘C’ file is created by selecting the “Add Model” button under
the C File Associations tab. The newly created file can be edited by selecting the edit button.

All of the input / output signals and parameters, as well as, their types are listed in a .h file
which is automatically generated by C− Builder. The .h file is included as part of the ‘C’ code
using the #include statement at the top of the ‘C’ code file. As such, all of the input / output
and parameter signals may be used as part of the ‘C’ code. The simulation time−stepmay be
obtained by adding the following statement into the ‘C’ code −

dt= getTimeStep();

The algorithm to be solved for the multimass model is essentially defined in equation 21
above. In order to solve [21] the following matrices must be computed as part of the data
preparation code.

[𝐻], [𝐷], [𝐾]


[𝐴], [𝐵]
[𝐴]-1

The matrices are declared as double precision and dimensioned to the maximum number of
masses (= 8 turbine masses + 1 generator mass + 2 exciter masses = 11 masses).

RAM:
#define MAXMASS 11
double H[MAXMASS][MASSMASS];
double K[MAXMASS][MASSMASS];
double D[MAXMASS][MASSMASS];
double A[MAXMASS][MASSMASS];

22
Tutorial: Multi-Mass System

double B[MAXMASS][MASSMASS];

The above matrices are declared under the RAM: section in the ‘C’ code file since they are
only used for the data preparation. The matrix Ainverse is required in both the data
preparation and algorithm portions of the ‘C’ code and as such is declared under the STATIC:
section of the ‘C’ code file.

STATIC:
double AINV[MAXMASS][MAXMASS];

b. Load Data into Variables

Data storage into the matrices and arrays is such that the lowest indexed entry is allocated
to the High Pressure turbine. The next entry to the IP turbine and so on. Generator data is
entered into the element pointed to by nturb. Exciter #1 is entered into the element pointed
to by nturb+1. For example if the user has specified that four turbine masses are to be
modelled (nturb=4) then the following code would be used to load the H matrix elements.
Note that the inertia constants are loaded into the diagonal elements only and that
off−diagonal elements of the H matrix are 0.0.

H[0][0] = HPH;
H[1][1] = IPAH;
. . .
H[7][7] = LPAH;
H[ntrub][ntrub] = GENH;
H[ntrub+1][ntrub+1] = EXC1H;
H[ntrub+2][ntrub+2] = EXC2H;

The 𝐷 and 𝐾 matrices are tri−diagonal (see equation [22]) meaning that only their diagonal
and diagonal +/− 1 elements have non−zero values. Elements of these matrices are loaded
one value at a time –

D[0][0]= HPSD + HPIPAMD;


D[0][1]= −HPIPAMD;
D[1][0]= −HPIPAMD;
D[1][1]= HPIPAMD + IPASD + IPAIPBMD;
D[1][2]= −IPAIPBMD;
. . .

23
Tutorial: Multi-Mass System

D[7][7]= LPCLPDMD + LPDSD + LPDGENMD;


D[nturb][nturb]= GENSD + LPDGENMD;

Exciter damping factors are added into nturb+1 and nturb+2 elements.

Elements of the 𝐾 matrix are filled in using the same procedure as for the 𝐷 matrix. Once
the 𝐾, 𝐷 and 𝐻 matrix elements are filled, the 𝐴 and 𝐵 matrices are computed as follows
(see equation [19]). Computations are done only for the number of masses which are being
modelled.

nmass= nturb+1+EXCen;
K1= 4/dt;
K2= dt/2;
for (row=0;row<nmass;row++)
{
for (col=0;col<nmass;col++)
{
A[row][col]=H[row][col]*k1+D[row][col] + K[row][col]*k2;
B[row][col]=H[row][col]*k1−D[row][col] + K[row][col]*k2;
}
}

The inverse of the A matrix is required for the algorithm (see equation [21]). An internal
matrix inversion routine is available to generate the required inverse matrix −

i= matx_invert(nmass,A,MAXMASS,AINV,MAXMASS);
where −
nmass= dimension of matrix to invert
A= matrix to invert
MAXMASS= dimension of matrices A and AINV
AINV= matrix to store inverse of A

The Ainv matrix is a full matrix. In addition to the Ainv matrix, the algorithm portion of the
‘C’ code also requires the B matrix and 2 times the K matrix. However, the B and 2*K matrices
are tri−diagonal and to conserve computations they will be stored in eleven separate arrays
of dimension three. Each array holds the n−1, n and n+1 elements (where n is the diagonal
element). Since these vectors are used in both the data preparation and algorithm portion
of the ‘C’ code they are declared under the STATIC: section −

STATIC:
double K2TRI0[3], BTRI0[3];
double K2TRI1[3], BTRI1[3];
. . .
double K2TRI10[3], BTRI10[3];

24
Tutorial: Multi-Mass System

The K2TRI and BTRI vectors are loaded from the K and B vectors.

for (i=0;i<3;i++)
{
BRTRI0[i]= B[0][i];
K2TRI0= 2.0 * K[0][i];
. . .
BTRI10[i]= B[10][i+8];
K2TRI10[i]= 2.0 * K[10][i+8];
}

c. Write Critical Data to the .map File


It may be useful to include an option in the component’s CONFIGURATION menu to print
computed data into the .map file. Such data may be useful for debugging purposes during
the model’s development and testing, as well as, solving problems that may arise if third
parties begin to use the model.

Printing to the .map file may be done using the following structure of the fprintf statement

fprintf(mapFile,”\n D[%d][%d]= %lf“, row, col, D[row][col]);

4.7.11 WRITE ‘C’ CODE TO IMPLEMENT THE ALGORITHM

Now that all of the constants required for the algorithm have been computed, the ‘C’ code
to implement the algorithm itself can be written. Code to execute the model algorithm is
placed under the CODE: section in the ‘C’ file template. The basic structure of the code is as
follows –

variable declarations initializing


If (mode == lock)
{
set all mass speeds
}
Else if (mode = single)
{
solve one mass model
}
Else

25
Tutorial: Multi-Mass System

{
compute multimass algorithm
}
write output signals

The algorithm used to solve the multimass model is based on equation [21] (repeated below)
and proceeds in the following steps.

[𝜔𝑛 (𝑡)] = [𝐴−1 ] ∗ [[𝑇𝑛 (𝑡)] + [𝑇𝑛 (𝑡 − ∆𝑡)] + [𝐵][𝜔𝑛 (𝑡 − ∆𝑡)] − [2𝐾][𝜃𝑛 (𝑡 − ∆𝑡)]

1. Compute [𝐵𝑊] = [𝐵] ∗ [𝜔(𝑡 − 𝑑𝑡)]. Since only the non−zero elements of [𝐵] are
stored the calculation is done as follows –

𝐵𝑊0 𝐵00 𝐵01 0 0 𝑊𝑜𝑙𝑑0


𝐵𝑊1 𝐵10 𝐵11 𝐵12 0 𝑊𝑜𝑙𝑑1
[ ]= [ ][ ]
𝐵𝑊2 0 𝐵21 𝐵22 𝐵23 𝑊𝑜𝑙𝑑2
𝐵𝑊3 0 0 𝐵32 𝐵33 𝑊𝑜𝑙𝑑3

BW[0] = BTRI0[0] * wold[0] + BTRI0[1] * wold[1];


BW[1] = BTRI1[0] * wold[0] + BTRI1[1] * wold[1] + BTRI1[2] * wold[2];
BW[2] = BTRI2[0] * wold[1] + BTRI2[1] * wold[2] + BTRI2[2] * wold[3];
BW[3] = BTRI3[0] * wold[2] + BTRI3[1] * wold[3] + BTRI3[2] * wold[4];

2. Compute [𝐾2𝑇𝐻] = [𝐾2] ∗ [𝑇𝐻𝑜𝑙𝑑(𝑡 − 𝑑𝑡)]. Since only the non−zeroelements of [𝐾2]
are stored the calculation is done as follows −

𝐾2𝑇𝐻0 𝐾200 𝐾201 0 0 𝑇𝐻𝑜𝑙𝑑0


𝐾2𝑇𝐻1 𝐾2 𝐾211 𝐾212 0 𝑇𝐻𝑜𝑙𝑑1
[ ] = [ 10 ][ ]
𝐾2𝑇𝐻2 0 𝐾21 𝐾222 𝐾223 𝑇𝐻𝑜𝑙𝑑2
𝐾2𝑇𝐻3 0 0 𝐾232 𝐾233 𝑇𝐻𝑜𝑙𝑑3

K2TH[0] = K2TRI0[0] * THold[0] + K2TRI0[1] * THold[1];


K2TH[1] = K2TRI1[0] * THold[0] + K2TRI1[1] * THold[1] + K2TRI1[2] *
THold[2];
K2TH[2] = K2TRI2[0] * THold[1] + K2TRI2[1] * THold[2] + K2TRI2[2] *
THold[3];
K2TH[3] = K2TRI3[0] * THold[2] + K2TRI3[1] * THold[3] + K2TRI3[2] *
THold[4];

3. Compute [𝐵𝑐𝑜𝑙] = [𝑇𝑜𝑙𝑑] + [𝐵𝑊] − [𝐾2𝑇𝐻]. [𝐵𝑊] and [K2TH] were computed in
steps 1 and 2 above. [Told] are the shaft torques computed in the previous time−step.
[𝑇𝑜𝑙𝑑], [𝐵𝑊] and [𝐾2𝑇𝐻] are column vectors and can thus [𝐵𝑐𝑜𝑙] may be computed

26
Tutorial: Multi-Mass System

using a for loop as shown below –

for (ii=0;ii<nmass;ii++)
{
BCOL[ii]= T[ii]+BW[ii]−K2TH[ii];
}

4. Compute [Bcol]= [Bcol] + [T]. The [T] vector is the latest shaft torques which must first be
read in from the external source. Only those input torques associated with masses that
are actually modelled may be read in. Once read, the new shaft torques can be added to
the [BCOL] vector computed in step 3a.

T[0]= HPT;
if (nturb == 8)
{
T[1]= IPAT;
T[2]= IPBT;
T[3]= IPCT;
T[4]= LPAT;
T[5]= LPBT;
T[6]= LPCT;
T[7]= LPDT;
}
else if (nturb == 7)
{
. . .
}
. . .
else if (nturb == 2)
{
T[1]= IPAT;
}
for (ii=0;ii<nmass;ii++)
{
BCOL[ii]= BCOL[ii] + T[ii];
}
5. Compute [w]= [Ainv]*[BCOL]. Matrix [Ainv] is stored as a full nxn matrix and as such for
loops can be used to compute the new mass speed vector [W].

for (ii=0;ii<nmass;ii++)
{
w[ii]= 0.0
for (jj=0;jj<nmass;jj++)
{
w[ii]= w[ii] + Ainv[ii][jj]*BCOL[jj];
}

27
Tutorial: Multi-Mass System

6. With the new speeds of each modelled mass known from step 4, it is now possible to
compute the angles of each mass. The computed mass angles are used in step 2 during
the next time−step in the computation of speed. The vector THold is used to store the
newly computed values of mass angles.

dt2= 0.5*delt;
for (ii=0;ii<nmass;ii++)
{
THold[ii]= THold[ii] +
dt2*(wold[ii] + w[ii]);
}

The generator mass angle is chosen as the reference (0 deg). The computed generator mass
angle is subtracted from each modelled mass, including the generator mass itself.

for (ii=0;ii<nturb;ii++)
{
THold[ii]=
THold[ii] − THold[nturb];
}
THold[nturb+1]= THold[nturb+1]−THold[nturb];
THold[nturb+2]= THold[nturb+2]−THold[nturb];
THold[nturb]= 0.0;

7. Now that the multimass algorithm has been solved, monitored variables can be
prepared. All of the computations done within the algorithm are based on per−unit
quantities. Monitored variables need to be converted to the desired units prior to being
written out. The following conversions are done −

[w] speed pu * 2*PI*Base_Freq −> speed in rad/sec


[THold] shaft angle in pu *360 * 2*PI*Base_Freq −>
shaft angle in degrees

Shaft torques are computed using the angle across the shaft. For example, to compute the
torque across the shaft connecting the HP and IPA masses –

HPIPAT= HPIPAK * (THold[0]−THold[1])


where HPIPAK is the spring
constant for the shaft

8. Some additional code needs to be added to the algorithm to handle the lock/free switch.
The lfm parameter under the CONFIGURATION menu permits the user to select whether
the lock/ free switch is automatically created by the model or whether an external signal

28
Tutorial: Multi-Mass System

connected to an input point controls the lock/free operating mode of the multimass
model. To handle both input options a variable lfmode is created and assigned input from
the external signal or from the automatically created RSCAD/RunTime switch depending
upon the selection of the lfm parameter. If the lfm parameter is equal to 0 then an
RSCAD/RunTime switch is automatically created, otherwise the lock/free signal is read
from an input point.

if (lfm > 0)
{
lfmode= lfswinp;
}
else
{
lfmode= lfsw;
}

Both the lfswinp and lfsw variables are defined in the .h file that is created when the
component is compiled.

When the lock/free signal is set to free (lfmode=0), the algorithm as defined in steps 1−6
above is executed. When in lock mode (lfmode= 1) all modelled mass speeds are fixed.

k3= 1.0;
if (rpsinit == 0) k3= rps/omo;
if (lfmode == 1)
{
for (ii=0;ii<nmass;ii++)
{
w[ii]= k3;
}
}

The variable k3 is set to 1.0 (ie. 1.0 per−unit speed represents synchronous speed) if the
rpsinit parameter is set to synchronous speed (rpsinit == 1 (Yes)) by the user. If the rpsinit
parameter is set to non−synchronous speed (rpsinit == 0 (No)) then the specified initial speed
is used to compute the initial per−unit speed of the machine and this value is used for all of
the modelled mass speeds when operating in lock mode.

When in lock mode or within the first time steps, the angles of each modelled mass can be
computed based on the torque applied to each mass and the shaft spring constant. If there
is only one turbine mass then the angle between the turbine and the generator may be
computed as −

THold[0]= Te / LPDGENK;

29
Tutorial: Multi-Mass System

Where Te is the torque applied to the generator LPDGENK is the shaft spring constant
between the generator and turbine.

If two turbine masses are modelled the initial mass angles are computed as −

THold[1]= Te / LPDGENK;
THold[2]= THold[1] + (Te−IPAT)/HIPPAK;

Initial angles for the exciters are set to 0.0 since no external torque is applied to the exciters.

If the mode switches are set so that the lock/free is free and single/ multi is set to single,
then all of the modelled masses are considered as one lumped mass. The torque applied to
the lumped mass is equal to the sum of torques read in and the inertia constant of the
equivalent mass is equal to the sum of all the modelled mass inertia constants. Self damping
terms for all modelled masses are summed to give an equivalent self damping factor for the
equivalent mass. Mass speed is computed as −

w[0]= C2*w[0] + C1*(Ttotal − Te);


w[1]= w[0];
. . .
where C1= dt / (2*totH);
C2= 1.0 − ((dt*totSD)/2*totH);

4.7.12 TEST NEWLY DEVELOPED MODEL

Testing of the multimass model can start by examining the output written to the .map file and
see whether it matches hand calculations. Multiplication of the A matrix by its inverse to see
whether the unity matrix is obtained checks whether the matrix inversion routine in the data
preparation code was properly executed.

Once the basic data preparation is verified, a number of simulation cases increasing in
complexity may be run to verify the model’s operation. It is useful to run the model in its
simplest mode (single mass) and compare its dynamic response to that which is expected.

As a final test, the multimass model is tested against the First Benchmark Case as described
in [2].

30
Tutorial: Multi-Mass System

4.8 REFERENCES

[1] R. Farmer, A. Schwalb, “Navajo Project Report on Subsynchronous Resonance


Analysis and Solutions”, IEEE Transactions on Power Apparatus and Systems, Vol.
PAS−96, No. 4, July 1977, pp.1226−1232.

[2] IEEE Subsynchronous Resonance Task Force “First Benchmark Model for Computer
Simulation of Subsynchronous Resonance”, IEEE Transactions on Power Apparatus and
Systems, Vol. PAS−96, No. 5, Sept/Oct 1977, pp.1565−1572.

[3] IEEE SSR Working Group “Second Benchmark Model for Simulation of
Subsynchronous Resonance”, IEEE Transactions on Power Apparatus and Systems,
Vol. PAS−104, No. 5, May 1985, pp.1057−1066.

[4] P. Kundar, Power System Stability and Control, McGraw−Hill, 1994.

[5] G. Gross and M.C. Hall, “Synchronous Machine and Torsional Dynamics Simulation in
the Computation of Electromagnetic Transients”, IEEE Transactions on Power
Apparatus and Systems, Vol. PAS−97, No. 4, July/Aug. 1978, pp1074−1086. (in particular
Appendix & Discussion)

31
5 MULTI-THREAD COMPONENT

5.1 INTRODUCTION
In real time digital power system simulation, the minimum length of time step used in the
simulation is dictated by the most time-consuming algorithm which has to be completed in
the time step. Provided the resulting time step is compatible with the bandwidth of the
phenomena being investigated the simulation can run in real time. When a smaller time step
is necessary to meet the bandwidth requirements the simulation can still run but not in real
time.
If the relay algorithm can be broken down into a number of independent blocks of code
which can be evaluated sequentially in successive time steps and subsequently organized
into a complete relay algorithm solution when all blocks have been evaluated then the time
step used in the main simulation can be smaller than the time needed to run the complete
relay algorithm. These blocks of code running in different time steps are called” threads”
which are subsequently ”woven” together to form the complete relay solution. Any
component algorithm can be separated into individual blocks of code processed
independently of each other to create a multi−threaded component running in the main
simulation. The multi−threaded component requires additional code to keep track of the
multi−threaded loop and adjust delays for timers when new sampled data is available. This
additional code will ensure the individual blocks of code are executed sequentially, and
restart the sequence when new sampled data is ready.
This document outlines how the multi−threaded component can be incorporated into a
model for use on the RTDS. Once the template for the multi−thread component is
developed, the procedure for implementing some simple algorithms using the CBuilder
feature under RSCAD is documented.

1
CBuilder Tutorial: Multi-Thread Component

5.2 MULTI-FUNCTION RELAYS

Figure 5.1: Multi-Functional Relay

Normally a micro−processor based intelligent electronic device (IED) will use data sampled
every 8/16/32/ or 64 samples per cycle. Relaying components are created using basic
protection theory and standard techniques for processing digitally sampled data from the
time domain. Essentially sampled data is transferred into the phase domain using a DFT or
equivalent technique. The phasor information is then evaluated against algorithms that can
discern between normal operating conditions and fault conditions. Control algorithms can
then be processed that will isolate the faulted portion of the power system. The same control
algorithm can then later restore the isolated portion of the power system when the fault
condition has been removed.

5.3 MULTI-THREAD COMPONENT


A down−sampler is used to provide data at the correct number of samples per cycle for the
algorithm. In an example case with a nominal 60 Hz base sampling rate of 8 samples per
cycle, the control algorithm obtains and uses new data every 2.08333 ms. If the simulation
time−step is 50 μsec, then the main simulation will be executed 41 times between samples.
This means that it is possible to have 41 different threads executed sequentially every
2.08333 ms. The execution time for a multifunctional relay algorithm without using threads
will require the use of a longer simulation time step. If there are 5 threads in the
multi−thread cycle with an additional thread every new sample the normal delay cycle
between individual threads is 250 μsec. The additional thread every sample is normally used
for the signal processing. This means the multi−thread cycle would execute about 7 times
between new samples. Keep in mind that some code will be executed each time step and
must be taken into consideration for overall execution time of each thread. The sample rate
is not always an integer value of the time−step therefore new samples will occur with an

2
CBuilder Tutorial: Multi-Thread Component

accuracy limited to a few time−steps. This means that the thread cycle will restart at
different thread counts changing the amount of delay between the executions of code within
a thread. This delay can be adjusted from the normal 250 μsec to a temporary value
whenever the new data sample interrupts the thread cycle and restarts.

Figure 5.2: Multi-Threaded Time-Step

If a timer is used in thread 1 the time between executions of thread 1 changes when a new
sample occurs indicated by the red line. When the control algorithm is ready to read the new
sample data, the multi−thread was executing thread 2. Because new sample data is ready to
be read the control algorithm has to move back to thread 0 and read in and process the new
sampled data that will be used for the other threads.
When the multi−thread moves back to thread 1 and starts executing the code, only 3 main
simulation timesteps have occurred. To properly service a timer in thread 1 the amount of
delay added to the timer would have to be temporarily adjusted by 3/5 of the 250 μsec (5
time-steps) normally added.
The multi−thread component example will contain the necessary code to temporarily
change the amount of time added to timers when a new sample occurs.

5.4 MODEL DEVELOPMENT USING CBUILDER


Development of the multi−thread model requires the following steps:
1. Conceptual layout of the new component
a) Which inputs should be connected using wires?
b) Which outputs should be connected using wires?

3
CBuilder Tutorial: Multi-Thread Component

c) Appearance of the component icon.


d) Options which change appearance of icon.
e) What data is required to prepare the constants?
f) How to group related data fields.
g) What monitoring options should be available?

2. Component Icon Creation in C−Builder (Graphics & Nodes)


a) Define component as a Control system type component.
b) Locate and place all of the input/output points.
c) Draw component icon.

3. Define User Supplied Data Menus (Parameters)


a) Add all of the data sections defined under I(f) above.
b) Add logic to parameters so the parameter entry fields are visible only when the
corresponding options are selected.

4. Write Data Preparation Portion of the ‘C’ Program


a) Create C File and Declare required variables.
b) Compute constants required for the executable code.
c) Optionally write critical data to the .map file.

5. Write ‘C’ code to implement the algorithm


a) Declare required variables.
b) Create variables for named output signals.
c) Create variables for named input signals.

6. Test newly developed Model


a) Check data preparation to ensure constants are computed correctly.
b) Run simulation cases to confirm basic operation.

4
CBuilder Tutorial: Multi-Thread Component

1. Conceptual Layout of the New Component


a) Typically, controls components are drawn such that input points are on the left
side and output points are on the right side of the component.
b) The example model requires the name of an external variable to choose which
thread’s fractional delay is on output 7 (Frac).
c) The component’s appearance is shown below. IN1 − IN6 start the timers when 0
−>1 transition occurs on the inputs.

IN1 −IN6 starts the timers


Improve delay adjusts of the thread delay
Frac Elapsed changes the outputs from elapsed time to the fraction delay
for each thread
Analog IP is the input for the sampler and DFT
Timer−1 to Timer−6 is the output for each thread
Frac is the output of the monitored thread
Thread Count is the thread cycle
Info is a word variable with the status of each timer

5
CBuilder Tutorial: Multi-Thread Component

Figure 5.3: Multi Thread Component

d) The following data tabs are defined for the multi−thread component:
CONFIGURATION: Basic configuration options
TIMERS: Time delay values for each timer
MONITORING OPTION TAB: see below
e) The user is able to select the following items for monitoring. These are named
variables and as such there is no wire protruding from the component icon for
any of these outputs.
Trigger count when new sample occurs
Analog input data
Tabs are included in the component icon to facilitate selection of the signals to be
monitored and the name assigned to each monitored variable. Logic is included

6
CBuilder Tutorial: Multi-Thread Component

as part of the component to permit selection of only those variables which are
computed for the specified configuration.
f) C-Builder requires that the user specify whether the component is a power
system or control system type component. Power system components connect to
power system nodes as defined by node icons in RSCAD/Draft and often
contribute current injections into those nodes to which the component is
connected. Control system components do not connect to power system nodes
and are not able to supply current injections into the power system network.

The Nova Cor to which a control system component is allocated automatically


becomes a control system processor for the simulation case and only other
control system components may be allocated to that processor. It is not possible
to allocate both control system and power system components to the same
NovaCor.

2. Component Icon Creation in C-Builder


The C−Builder User’s Manual should be consulted for additional details on defining the
component icon. Information provided here outlines the major steps required to
complete the icon associated with the multi−thread model.
a) Define the Component as a Control System Component.
When a new component is created the user is prompted to select whether the
component type is control or power system. For the multi−thread model select
control.
The component type can be changed anytime from the “Other” menu.
Define the Input/Output points and associated conditional statements under the IO
Points Tab.
Inputs to start the timers are always present and require no conditional statements
to be placed around these input/output points. Select the “Draw Node” button from
the drawing toolbar and create points for the 6 inputs. All of the timer inputs are
specified as integer type.

7
CBuilder Tutorial: Multi-Thread Component

Figure 5.4: Component Icon in CBuilder

Data under the IO Points tab should appear as shown in Figure 5.5 once all of the
input/output points have been entered. The input/output points shown are outside
logic conditions.

8
CBuilder Tutorial: Multi-Thread Component

Figure 5.5: Data under IO Points Tab

b) Draw the portions of the component icon which are outside of conditional logic.
3. Add Parameter Entries
a) Now that the component icon, including input/output points and conditional
graphics, has been completed the menus for data entry are created. These menus
are defined under the Parameters tab in the control panel area of the
RSCAD/C−Builder window.
The following sections are required for the multi−thread component.
CONFIGURATION: basic configuration parameters including the IED name, base
frequency, variable name to choose value of OUT7, enable monitoring.
TIMERS: pickup and dropout delay values for each timer.
MONITORING: signal name for trigger count and signal name for analog input
sampled data. Names for monitored signals should only be entered if plotting is
enabled.
plots=1

9
CBuilder Tutorial: Multi-Thread Component

To create the component data entry sections listed above, use the new section

button in the control panel area of the RSCAD/C−Builder window. Enter the
Section name in the menu that appears. None of the sections need an associated
logic condition.
Once all of the data entry sections have been created, left click the small arrow next
to the section to which the parameters are to be added. The arrow points down and
the section heading is highlighted. Left click the add parameter button and fill in the
appropriate data in the menu that appears. The new parameter entry element is
added under the highlighted section.

Figure 5.6: Adding Parameters

4. Determine Ram Loader Code


a) Some variables must change value when the base frequency changes. In this case the
sample rate will change and the cutoff frequency will change when the base
frequency changes. To facilitate this, a logic condition is added for each of the
frequency parameter’s state.
To enable parameter changes relative to base frequency, add the following logic

10
CBuilder Tutorial: Multi-Thread Component

condition to the computations section.


If the freq parameter defined under the CONFIGURATION menu is set to 1 (50 hz) by
the user, then the SF parameter will be 0.400 and the fc variable will be 133.33. If the
freq parameter is set to 0 (60 hz) then the SF parameter will be 0.480 and the fc
variable will be 160.0.
The parameter “freq” is added to the parameters section and used within the C
program to change the 2 variables SF and fc.

5. Write Data Preparation Portion of the ‘C’ Program


a) Create C File and Declare Variables.
There are two ‘C’ code programs that must be written by the user to complete the
model. First, a ‘C’ program which computes the constants required by the algorithm
must be written. Secondly, the program which executes the algorithm for the model
must be written. Only the second program runs on the RTDS hardware. Both ‘C’
programs are stored in the same file. A template for the ‘C’ file is created by selecting
the “Add Model” button under the C File Associations tab. The newly created file can
be edited by selecting the edit button.
All of the input / output signals and parameters, as well as, their types are listed in a
.h file which is automatically generated by C−Builder. The .h file is included as part of
the ‘C’ code using the #include statement at the top of the ‘C’ code file. As such, all
of the input / output and parameter signals may be used as part of the ‘C’ code. The
simulation time−step may be obtained by adding the following statement into the ‘C’
code:
dt= getTimeStep();

The algorithm to be solved for the model is essentially a down sampler, a DFT, and
timers. In order to run the anti−alias filter the constants must be computed as part
of the data preparation code. As well the down sampler should have a sample rate
relative to the base frequency. The RAM section will be used to perform all of the
off−line section of code.
b) Load Data into Variables.
The main portion DFT will use an 8-point buffer to determine the DC, fundamental,
and second harmonic content of the analog input. The starting point of the buffer
can be initialized such that the phasor will be at angle zero.

11
CBuilder Tutorial: Multi-Thread Component

c) Write Critical Data to the .map File


It may be useful to include an option in the component’s CONFIGURATION menu to
print computed data into the .map file. Such data may be useful for debugging
purposes during the model’s development and testing, as well as, solving problems
that may arise if third parties begin to use the model.
Printing to the .map file may be done using the following structure of the fprintf
statement:
fprintf(mapFile,”\n D[%d][%d]= %lf“,
row, col, D[row][col]);

6. Write ‘C’ Code to Implement the Algorithm.


Now that all of the constants required for the algorithm have been computed, the ‘C’
code to implement the algorithm itself can be written. Code to execute the model
algorithm is placed under the CODE: section in the ‘C’ file template. The basic structure
of the code is shown on pages in latter sections.

7. Test Newly Developed Model


Testing of the multi−thread model can start by examining the output of the timers with
input 7 enabled or disabled.
Once the basic data preparation is verified, a number of simulation cases increasing in
complexity may be run to verify the model’s operation. It is useful to run the model with
a pure sine wave at base frequency and evaluate the plots to what is expected.

5.5 MULTI-THREAD MODEL ALGORITHM


The algorithm for the multi−thread model is based on the above idea. The model will contain
seven threads with a timer in six of the threads. The timers are activated when a value
greater than 0 is applied to the appropriate input. The model will also contain code for data
sampling and a DFT function.
The main purpose here is not to develop a complex relay but to introduce a template which
can be used to create multi−functional relays.
// Processing Threads are:
// 0 − Anti−alias filter, downsampler, DFT
// 1 − Timer 1, phasor rotation and plots

12
CBuilder Tutorial: Multi-Thread Component

// 2 − Timer 2
// 3 − Timer 3
// 4 − Timer 4
// 5 − Timer 5
// 6 − Timer 6

5.6 MULTI-THREAD STATIC SECTION


// Include file below is generated by C−Builder
// and contains the variables declared as −
// PARAMETERS, INPUTS, OUTPUTS . . .
#include ”PN_MT_temp.h”

// time delay counters


double tdpu_ip1,tdpu_ip2,tdpu_ip3;
double tdpu_ip4,tdpu_ip5,tdpu_ip6;
double tddo_ip1,tddo_ip2,tddo_ip3;
double tddo_ip4,tddo_ip5,tddo_ip6;

// Other variables
double dt,del,fracdel,nThread,nThreadInv;
int sample_new,trig,trigcnt,trigcnt_old,nThreadInt;
int ip1,ip2,ip3,ip4,ip5,ip6,ip7,ip8,nfrac,dthalf;
int start1,start2,start3,start4,start5,start6;
double va_re,va_im,va2_re,va2_im;
double temp_re, temp_im, os1_1,os1_2;
double inv_dt,bfreq,favg;
double e_timer,f_timer,w_tan1,w_tan2,f_F13;
double f_sample_t,meas1,meas1old,hold1,tmp;
double va_buff[8];

13
CBuilder Tutorial: Multi-Thread Component

int n_1[3], n_2[3],int idx;


double FUND_FACTOR,DC_FACTOR,_2ND_FACTOR;
double A[5], B[5], C[5],a_bre, a_bim;

/* − End o f S TATIC: Section − */

OUTPUTS:
intcnt_old = createOutput(nP1, strcat2(”Relays|”,iedName),0,100,”NA”,p1&&plots);
double A1RE = createOutput(nP2r, strcat2(”Relays|”,iedName),0,100,”x”,p2&&plots);
double A1IM = createOutput(nP2i, strcat2(”Relays|”,iedName),0,100,”y”,p2&&plots);
doubleA1FUND= createOutput(nP2fm, strcat2(”Relays|”,iedName),0,100,”NA”,p2&&plots);
doubleA12ND = createOutput(nP22nd, strcat2(”Relays|”,iedName),0,100,”NA”,p2&&plots);
double A1DC = createOutput(nP2dc, strcat2(”Relays|”,iedName),0,100,”NA”,p2&&plots);

5.7 MULTI-THREAD RAM SECTION


int i,k,nsn;
double nsf,wcp,cosn,x;

if(freq==0)
{
SF = 0.480;
fc = 160.0;
} else {
SF = 0.400;
fc = 133.33;
}
dt = getTimeStep();// Simulation time step nThreadInt = 7;
nThread = 7.0;
nThreadInv = 1.0 / nThread;

14
CBuilder Tutorial: Multi-Thread Component

fracdel = nThread * dt;// RSCAD time step,delay is multiple # of threads


del = fracdel;
dthalf = 0.5*del; // Pick Up Delay Calculation tdpu_ip1 = 0.0;
tdpu_ip2 = 0.0;
tdpu_ip3 = 0.0;
tdpu_ip4 = 0.0;
tdpu_ip5 = 0.0;
tdpu_ip6 = 0.0;
tddo_ip1 = 0.0;
tddo_ip2 = 0.0;
tddo_ip3 = 0.0;
tddo_ip4 = 0.0;
tddo_ip5 = 0.0;
tddo_ip6 = 0.0;
ip1 = 0;
ip2 = 0;
ip3 = 0;
ip4 = 0;
ip5 = 0;
ip6 = 0;
ip7 = 0;
ip8 = 0;
start1 = 0;
start2 = 0;
start3 = 0;
start4 = 0;
start5 = 0;
start6 = 0;

15
CBuilder Tutorial: Multi-Thread Component

// INPUT processing Initialization


nsn = 1;
nsf = 1.0;
inv_dt = 1.0 / dt;
f_sample_t = 0.001 / SF;
bfreq = SF * 125.0;
favg = bfreq;
idx = 6; // 6 samples to rotate by 270, normalizes Aph to 0.0 deg
e_timer= 0.0; // timer to enable freq tracking
f_timer= 10.25*dt; // adjustment to help zero the phase
// LP Filter constants calculations for( k = 0; k < nsn; ++k )
{
wcp = sin( fc * PI * dt ) / cos( fc * PI * dt );
cosn = cos(( 2.0 * ( k + nsf + 1.0 ) − 1.0 ) * PI / ( 4.0 * nsf ));
x = 1.0 / ( 1.0 + wcp * wcp − 2.0 * wcp * cosn );
A[ k ] = wcp * wcp * x;
B[ k ] = 2.0 * ( wcp * wcp − 1.0 ) * x;
C[ k ] = ( 1.0 + wcp * wcp + 2.0 * wcp * cosn ) * x;
}
for(i=0;i<8;i++)
{
va_buff[i]=0.0;
}
FUND_FACTOR=0.176776695; // for RMS => 0.5*(1/sqrtN)
FUND_FACTOR=FUND_FACTOR*1.009910335; // adjust for the loss in the BW Filt at 160.0
FC
_2ND_FACTOR=FUND_FACTOR*1.135933359; // adjust for the loss in the BW Filt
DC_FACTOR=0.125;
/* −−−−End of R AM: S ection −−−−*/

16
CBuilder Tutorial: Multi-Thread Component

5.8 MULTI-THREAD CODE SECTION


meas1 = IN9;
// Butterworth Filter for anti−aliasing 2nd order LP
// VA first stage
tmp = −B[ 0 ] * os1_1 + −C[ 0 ] * os1_2 + A[ 0 ] * meas1;
meas1 = tmp + 2.0 * os1_1 + os1_2;
os1_2 = os1_1;
os1_1 = tmp;
meas1old = hold1;
f_F13 = f_timer;
e_timer = e_timer + dt;
f_timer = f_timer + dt;
if(f_timer > f_sample_t)
{
// linear interpolation
tmp = ((meas1 − meas1old) * inv_dt) * (f_sample_t − f_F13);
meas1 = tmp + meas1old;
// 8 SAMPLE BUFFER
va_buff[idx] = meas1;
idx = idx+1;
idx = idx % 8;
// DFT FOR THE VOLTAGES AND CURRENTS
A1DC=(va_buff[0]+va_buff[1]+va_buff[2]+va_buff[3]+va_buff
[4]+va_buff[5]+va_buff[6]+va_buff[7])*DC_FACTOR; va_re=(va_buff[0]−va_buff[4]+
INV_ROOT2*(va_buff[1]−va_buff[3]−va_buff[5]+va_buff[7]))
*FUND_FACTOR;
va_im=(−va_buff[2]+va_buff[6]+INV_ROOT2*(−va_buff[1]−v
a_buff[3]+va_buff[5]+va_buff[7]))*FUND_FACTOR;
va2_re=( va_buff[0]−va_buff[2]+va_buff[4]−va_buff[6])*_2ND_FACTOR;

17
CBuilder Tutorial: Multi-Thread Component

va2_im=(−va_buff[1]+va_buff[3]−va_buff[5]+va_buff[7])*_2N D_FACTOR;

trig = 1;
f_timer = f_timer − f_sample_t;
trigcnt_old = trigcnt;
trigcnt = 0;
sample_new = 1;
// set the values for Inputs ip1 = IN1;
ip2 = IN2;
ip3 = IN3;
ip4 = IN4;
ip5 = IN5;
ip6 = IN6;
ip7 = IN7;
ip8 = IN8;
}
else
{
trig = 0;
hold1 = meas1;
trigcnt = trigcnt + 1;
if (trigcnt > nThreadInt){
sample_new = 0;
trigcnt = 1; // go to Thread 1
}
///////////////////// THREAD 1 /////////////////////////////
if (trigcnt == 1){
if (sample_new==1){

18
CBuilder Tutorial: Multi-Thread Component

if (trigcnt_old<trigcnt){
fracdel = (trigcnt + trigcnt_old + 5)*nThreadInv*del;
}
if (trigcnt_old==trigcnt){
fracdel = (trigcnt_old + 1)*nThreadInv*del;
}
if (trigcnt_old>trigcnt){
fracdel = (trigcnt_old + 1)*nThreadInv*del;
}
if (e_timer>0.1&& ip7>0){
w_tan1 = atan2(va_im,va_re);
// figure out the real and imag,then rotate the phasors
a_bre = cos(w_tan1);
a_bim = −sin(w_tan1);
temp_re=(va_re * a_bre) − (va_im * a_bim);
temp_im=(va_re * a_bim) + (va_im * a_bre);
va_re = temp_re;
va_im = temp_im;
}
}
else
{
fracdel = del;
}
// set the values for plots
A1RE = va_re;
A1IM = va_im;
A1FUND = sqrt((va_re * va_re) + (va_im * va_im));

19
CBuilder Tutorial: Multi-Thread Component

A12ND = sqrt((va2_re * va2_re) + (va2_im * va2_im));


}
///////////////////// THREAD 2 /////////////////////////////
else if (trigcnt == 2){
if (sample_new==1 && ip7>0){
if (trigcnt_old<trigcnt){
fracdel = (trigcnt + trigcnt_old + 5)*nThreadInv*del;
}
if (trigcnt_old==trigcnt){
fracdel = (trigcnt_old + 1)*nThreadInv*del;
}
if (trigcnt_old>trigcnt){
fracdel = (trigcnt_old + 1)*nThreadInv*del;
}
}
else
{
fracdel = del;
}
// set the outputs for Timer 1
if (ip1 > 0){
if (tdpu_ip1 < T1PU){
tdpu_ip1 = tdpu_ip1 + fracdel;
}
if (tdpu_ip1 >= T1PU){
start1 = 1;
}
}

20
CBuilder Tutorial: Multi-Thread Component

else
{
if (start1 > 0){
tddo_ip1 = tddo_ip1 + fracdel;
}
if (tddo_ip1 >= T1DO){
start1 = 0;
tdpu_ip1 = 0.0;
tddo_ip1 = 0.0;
}
} // end of setoutputs
if statement if (ip8 == 1){
OUT1 = fracdel;
}
else
{
if (ip1 > 0){
OUT1 = tdpu_ip1;
}
else
{
OUT1 = tddo_ip1;
}
}
}
///////////////////// THREAD 3 /////////////////////////////
else if (trigcnt == 3){
if (sample_new==1 && ip7>0){

21
CBuilder Tutorial: Multi-Thread Component

if (trigcnt_old<trigcnt){
fracdel = (trigcnt + trigcnt_old + 4)*nThreadInv*del;
}
if (trigcnt_old==trigcnt){
fracdel = (trigcnt_old + 1)*nThreadInv*del;
}
if (trigcnt_old>trigcnt){
fracdel = (trigcnt_old + 1)*nThreadInv*del;
}
}
else
{
fracdel = del;
} // CODE AS PER TIMER 1
}
///////////////////// THREAD 4 /////////////////////////////
else if (trigcnt == 4){
if (sample_new==1 && ip7>0){
if (trigcnt_old<trigcnt){
fracdel = (trigcnt + trigcnt_old + 3)*nThreadInv*del;
}
if (trigcnt_old==trigcnt){
fracdel = (trigcnt_old + 1)*nThreadInv*del;
}
if (trigcnt_old>trigcnt){
fracdel = (trigcnt_old + 1)*nThreadInv*del;
}
}

22
CBuilder Tutorial: Multi-Thread Component

else
{
fracdel = del;
} // CODE AS PER TIMER 1
}
///////////////////// THREAD 5 /////////////////////////////
else if (trigcnt == 5){
if (sample_new==1 && ip7>0){
if (trigcnt_old<trigcnt){
fracdel = (trigcnt + trigcnt_old + 3)*nThreadInv*del;
}
if (trigcnt_old==trigcnt){
fracdel = (trigcnt_old + 1)*nThreadInv*del;
}
if (trigcnt_old>trigcnt){
fracdel = (trigcnt_old + 1)*nThreadInv*del;
}
}
else
{
fracdel = del;
} // CODE AS PER TIMER 1
}
///////////////////// THREAD 6 /////////////////////////////
else if (trigcnt == 6){
if (sample_new==1 && ip7>0){
if (trigcnt_old<trigcnt){
fracdel = (trigcnt + trigcnt_old + 2)*nThreadInv*del;

23
CBuilder Tutorial: Multi-Thread Component

}
if (trigcnt_old==trigcnt){
fracdel = (trigcnt + 1)*nThreadInv*del;
}
}
else
{
fracdel = del;
} // CODE AS PER TIMER 1
}
///////////////////// THREAD 7 /////////////////////////////
else if (trigcnt == 7){
if (sample_new == 1 && ip7>0){
if (trigcnt_old<trigcnt){
fracdel = (trigcnt + trigcnt_old + 1)*nThreadInv*del;
}
}
else
{
fracdel = del;
} // CODE AS PER TIMER 1
}
cnt_old = trigcnt_old;
OUT8 = trigcnt;
OUT9 = start1+start2+start3+start4+start5+start6;

24
6 PMU SHELL COMPONENT

6.1 INTRODUCTION
In real time digital power system simulation, the minimum length of time step used in the
simulation is dictated by the most time-consuming algorithm which has to be completed in
the time step. Provided the resulting time step is compatible with the bandwidth of the
phenomena being investigated the simulation can run in real time. When a smaller time step
is necessary to meet the bandwidth requirements the simulation can still run but not in real
time.
This document describes the implementation of a Phasor Measurement Unit (PMU)
algorithm using techniques introduced in tutorial chapter 5.
This document outlines how the create the PMU shell from the source files found in the
RSCAD installation directory.

6.2 PHASOR MEASUREMENT UNIT

Figure 6.1: PMU AC Connection

PMUs are available from virtually every manufacturer of protection and monitoring
equipment. They are often implemented as embedded functions within relays or
disturbance recorders. This document describes a PMU shell software model for use on a
Real Time Digital Simulator (RTDS). The algorithms that are part of the PMU shell are
developed using the signal processing reference model from IEEE C37.118.1−2011 Annex C.

1
CBuilder Tutorial: PMU Shell

Development of a C−Builder model involves many steps and generally requires weeks or
months from start to finish. The next page provides an overview of the steps typically
involved to develop a model.
RTDS has provided the source files that can be used by individuals to start developing their
own PMU signal processing algorithms with C−builder and the GTNET−PMU firmware.

6.3 MODEL DEVELOPMENT USING CBUILDER


Development of the multi−thread model requires the following steps:
1. Conceptual layout of the new component
a) Which inputs should be connected using wires?
b) Which outputs should be connected using wires?
c) Appearance of the component icon.
d) Options which change appearance of icon.
e) What data is required to prepare the constants?
f) How to group related data fields.
g) What monitoring options should be available?

2. Component Icon Creation in C−Builder (Graphics & Nodes)


a) Define component as a Control system type component.
b) Locate and place all of the input/output points.
c) Draw component icon.

3. Define User Supplied Data Menus (Parameters)


a) Add all of the data sections defined under I(f) above.
b) Add logic to parameters so the parameter entry fields are visible only when the
corresponding options are selected.

4. Write Data Preparation Portion of the ‘C’ Program


a) Create C File and Declare required variables.
b) Compute constants required for the executable code.
c) Optionally write critical data to the .map file.

5. Write ‘C’ code to implement the algorithm


a) Declare required variables.
b) Create variables for named output signals.
c) Create variables for named input signals.

6. Test newly developed Model


a) Check data preparation to ensure constants are computed correctly.
b) Run simulation cases to confirm basic operation.

2
CBuilder Tutorial: PMU Shell

6.4 PMU SHELL COMPONENT


C−Builder is used to create models that are not part of the normal RSCAD library. The source
files are created and stored in the RSCAD user’s root folder.
The source files for the PMU SHELL component are installed in the installation directory of
RSCAD. In this case it is assumed it is in C drive.:
C:\RSCAD_FX\\EXAMPLES\TUTORIAL\CBuilder\CH−6−PMU_SHELL\RTDS_USER
There are 2 sub folders ..\CMODEL_SOURCE and ...\ULIB, the “cmodel_source” folder
contains the *.c and *.h files while the “ulib” folder contains the component definition file.
The source files need to be copied to the RTDS_USER directory as follows:
1. Copy the file:
C:\RSCAD_FX\EXAMPLES\TUTORIAL\CBuilder\CH−6−PMU_SHELL\RTDS_USER\ULIB\_rt
ds_GTNET_PMU_shell.def to your ULIB folder C:\RTDS_USER\ULIB\
2. Copy the file:
C:\RSCAD_FX\EXAMPLES\TUTORIAL\CBuilder\CH−6−PMU_SHELL\RTDS_USER\CMODEL
_SOURCE\PMU_m.c to your BIN folder C:\RTDS_USER\BIN\CMODEL_SOURCE
3. Copy the file:
C:\RSCAD_FX\EXAMPLES\TUTORIAL\CBuilder\CH−6−PMU_SHELL\RTDS_USER\CMODEL
_SOURCE\PMU_m.h to your BIN folder C:\RTDS_USER\BIN\CMODEL_SOURCE
4. Copy the file:
C:\RSCAD_FX\EXAMPLES\TUTORIAL\CBuilder\CH−6−PMU_SHELL\RTDS_USER\CMODEL
_SOURCE\PMU_p.c to your BIN folder C:\RTDS_USER\BIN\CMODEL_SOURCE
5. Copy the file:
C:\RSCAD_FX\EXAMPLES\TUTORIAL\CBuilder\CH−6−PMU_SHELL\RTDS_USER\CMODEL
_SOURCE\PMU_p.h to your BIN folder C:\RTDS_USER\BIN\CMODEL_SOURCE

6.5 LOAD PMU SHELL INTO CBUILDER


Start CBuilder and open the PMU shell component definition file:
“_rtds_GTNET_PMU_shell.def”. Once the component is loaded into CBuilder, the source
files need to be compiled.
Select the “C File Associations” tab (see 1 of Figure 6.2) and then click on the edit button
for the PMU_p model (see 2 of Figure 6.2). Then click on the Compile button (see 3 of
Figure 6.2).
Repeat the following steps for PMU_M.

3
CBuilder Tutorial: PMU Shell

Figure 6.2: Compiling PMU Shell Source Files in CBuilder

6.6 PMU SHELL ALGORITHM


The PMU model developed to run on the RTDS includes the P class and M class reference
models from the IEEE standard C37.118.1 Annex C. Figure 3 shows the typical steps used
within the reference PMU to process the input signals [1]. A GTSYNC card provides the
absolute time−reference and the simulation data is sampled using a fixed sample rate. The
quadrature oscillator operates at nominal frequency and is used to perform complex
multiplication of the input signal. The LP filters are Finite Impulse Response (FIR) and remove
the double frequency component thus leaving the Re and Im part of the original input signal.
For P and M class the LP filters are implemented using symmetrical FIR filters with an odd
number of stages. The P class filter coefficients are calculated using a triangular window and
the M class filter coefficients are calculated using windowed “sinc” function multiplied with
a Hamming window. Each sample is time−stamped and compensated for the group delay of
the LP filter. The phasor estimate at the center of the estimation window is unbiased by the
actual system frequency and does not require further phase correction when the
time−stamp at the center of the window is used. In IEEE C37.118.1−2011 Annex C the P class
samples data at 15 samples per cycle and the M class samples data at 16 samples per cycle
at nominal frequency. We have modified the P class to sample at 16 samples per cycle so we
can use higher reporting rates.

4
CBuilder Tutorial: PMU Shell

Figure 6.3: PMU Phasor Signal Processing Reference Model

Although the block diagram in Figure 6.3 explains the concept of the reference model quite
well, there are some subtle changes that need to be done for it to work on a real time digital
simulator. The simulation data must be interpolated when sampled because the PMU
sample rate may not be an integer multiple of the simulation time−step. The quadrature
oscillator must also be interpolated by the same amount as the simulation data. The
maximum reporting latency allowed by C37.118.1−2011 is 2/Fs for P class and 5/Fs for M
class where Fs is the reporting rate [2]. Therefore, the LP filter order must have latency less
than the maximum allowed by the standard and also allow for other delays. The LP filter
order can be quite large at the lower reporting rates and exceed the amount of available
RAM. For example, an M class PMU operating at nominal 50Hz with a reporting rate of 10Fs
requires a filter order of 700. The number of variables for just one PMU would be equal to
12,618. Because the RTDS model was designed to support 8 PMUs the amount of variables
just to process the FIR filters would equal 100,944 for a 50HzMclass PMU reporting at 10Fs.
During development of the RTDS PMU model the lowest supportable reporting rate was
found to be 10Fs at 50Hz. As the reporting rates become lower the filter window length
becomes larger to the point that the available memory limit is exceeded. The standard
reference model does not provide filter parameters for reporting rates higher than 100Fs or
120Fs. In order to provide reporting rates at 200Fs and 240Fs for 50Hz and 60Hz respectively
a 30 tap FIR filter using Dolph−Chebyshev coefficients was used.

5
CBuilder Tutorial: PMU Shell

Figure 6.4: Magnitude Response of 240 frames/second Filter

The processing of the simulation data and manipulation of the data into the format defined
by the IEEE standard is computed on a NovaCor. Because each of the eight PMUs operating
on the RTDS is independent, it is possible that all eight PMUs may output data at the same
time. Therefore, a method to limit servicing of one PMU per simulation time−step was
needed; to prevent buffer overflows on the GTNET. When PMU data is ready to be sent to
the GTNET a service interrupt flag is set and is cleared once the PMU data is sent to the
GTNET.

6.7 C CODE SECTIONS


The two *.c files have been prepared to use the parameters specified in the PMU Shell
component definition file. There are some very specific sections that SHOULD NOT BE
MODIFIED!
Before the
// !!! DO NOT CHANGE THIS !!!
STATIC:

6
CBuilder Tutorial: PMU Shell

// GTNET PHASOR ARRAY variables


// INPUT processing variables
// FIR coefficients etc...
The basic
INPUTS:

OUTPUTS:

RAM_PASS1:

RAM_PASS2:

DOWNLOAD_FILE_CODE:
// *******************************
// * CREATE THE DLOAD FILE ENTRIES
// *******************************
CODE_FUNCTIONS:
There are a number of functions called by the main CODE, each function has some comments
about what the function does. the main function is the pmu_data function and it is used to
create the phasors and prepare the data so it can be sent to the GTNET card.
//////////////////////////////////////////////////////////
// fir_split function
// Calculates the Filtered phasor from the sampled quadrature osc. data
// Inputs:
// input1 ... Quadrature Osc sampled data
// input2 ... Quadrature Osc sampled data
// ntaps ... number of stages
// h ... FIR co−efficients for PMU 0−7
// z ... pointer for Z delay line

7
CBuilder Tutorial: PMU Shell

// out ... pointer for phasor data


// p_state ... pointer for stage of FIR
// update ... flag to update the stage of the FIR
// Output:
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// adjust_phasor function
// Returns the corrected phasor from the array for the PMU output
// Inputs:
// pmu ... PMU number 0−7
// Output:
// temp_re, temp_im
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// symmetrical function
// Calculates the symmetrical components from the phasor array for the PMU output
// Inputs:
// A ... Va or Ia from #define
// B ... Vb or Ib from #define
// C ... Vc or Ic from #define
// VorI ... V1 or I1 from #define
// pmu ... PMU number 0−7
// Output:
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// complex_division function
// Returns the corrected phasor magnitude from the array for the PMU output
// using Annex C equation C.6 correction factor

8
CBuilder Tutorial: PMU Shell

// Inputs:
// pmu ... PMU number 0−7
// Output:
// temp_re, temp_im
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// phasor1 function
// Returns the correct type of output Re,Im or Cn,Phi
// Inputs:
// enable ... Enable
// OUTF ... Format
// pmu ... PMU number 0−7
// Output:
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// calc_angle_diff function
// Returns the correct angle difference between 2 angles
// Inputs:
// Angle1 ...
// Angle2 ...
// Output:
// angle_diff
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// pmu_data function
// Calculates the V and I phasor from the Input data and fills the phasor array for the PMU
// output
// Implements the P CLASS reference model from Annex C of C37.118.1

9
CBuilder Tutorial: PMU Shell

// Inputs:
// pmu ... PMU number 0−7
// IN1 ... Va
// IN2 ... Vb
// IN3 ... Vc
// IN4 ... Ia
// IN5 ... Ib
// IN6 ... Ic
// Output:
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// pmu_out function
// by Dean Ouellette/Marc Desjardine
// Send the PMU output to the GTNET−PMU
// Inputs:
// Output:
// !!! DO NOT CHANGE THIS !!!
//////////////////////////////////////////////////////////
CODE:
There is not much code here in the main section and the C file contains enough comments
to be able to figure out how the program works.

10
CBuilder Tutorial: PMU Shell

6.8 REFERENCES
[1] IEEE C37.118.1−2011 Annex C
[2] IEEE C37.118.1−2011 section 5.5.9

11
7 GENERATOR CONTROL BLOCK
7.1 INTRODUCTION
The DC1 type exciter requires real inputs from a generator model. The two required inputs
are the per unit generator terminal voltage (Vpu) and the generator speed (W). An optional
real stabilizer input and load compensation input is available. The exciter model produces
the field voltage output (Ef) required by the generator.

7.2 DRAW GRAPHICS AND ADD PARAMETERS


• As a starting point, an existing generator control block can be loaded into component
builder. This eliminates the need to draw the icon and create all the parameters.
Existing generator control blocks can be found in the installation directory of RSCAD
> MLIB > Components > CONTROLS > GENERATOR.
• Upon loading the component, a popup box appears requesting the type of
component. Select ’Control’.

Figure 7.1: EXDC1 Component Icon

The component icon for the exciter includes five I/O points. Four signal inputs and one
signal output, all are real.
• Save the component builder icon to a new file name located in the RTDS_USER|ULIB
folder.

1
CBuilder Tutorial: Generator Control Block

7.3 ADDING THE MODEL CODE


• Select the ’C File Associations’ tab.
• Select the “+” icon to Add New Association.
• Enter a model name.
• Input and Output points (listed under the IO Points tab) and user defined parameters
(listed under the Parameters tab) are automatically associated with the model and
placed in the .h file. Left clicking the “View Header File” button opens the .h file in an
editor. The model includes four inputs, one output and a number of parameters:
INPUTS:
double VPU;
double VS;
double Speed;
double VC;

OUTPUTS:
double OUT;

PARAMETERS:
char Gen[11];
int Mon;
int PSS;
double Vi;
double Tr;
double Ka;
double Ta;
...

2
CBuilder Tutorial: Generator Control Block

7.4 SAMPLE ‘C’ CODE FOR THE DC1 TYPE EXCITER


• The C code is written for the model by clicking on the edit icon to open up the text
editor window.
• The code for the DC1 type exciter is based on the block diagram shown in Figure 7.2.

3
CBuilder Tutorial: Generator Control Block

Figure 7.2: EXDC1 Diagram

4
CBuilder Tutorial: Generator Control Block

• The data preparation and code for the DC1 type exciter is shown below.
VERSION:

3.001

#include ”myEXDC1.h”

STATIC:

double dt,washoutG;

double Vmax, Vref, tmp;

double efldi,Verr,v_init;

double mon1,mon2,mon3,mon4,mon5,mon6,mon7,mon8,mon9,mon10;

int mon_array[10] = {1,2,3,4,5,6,7,8,9,10};

#include <builtin_gcc_generatorStructures.h>

struct realpolex realpole1;

struct realpolex realpole2;

struct integratorx integrator1;

struct washoutx washout1;

struct leadlagx leadlag1;

struct satKEx satKE1;

RAM_FUNCTIONS:

#include ”initTransferFunctions.inc”

RAM:

dt= getTime-step();

/* Parameter Validation */

if(Vrmax <= 0.0)

5
CBuilder Tutorial: Generator Control Block

if(E2< E1)

printf(”\nWarning: Vrmax is less than zero.”);

printf(”\n E2 must be greater than E1”);

printf(”\n Subsystem %d, Machine %s, exciter type ESDC1A.\n”, getSubsystem(),Gen);


reportError(”EXDC1”,1);

Vrmax = (Se2 + Ke)*E2;

Vrmin = −1*Vrmax;

if (Vrmax < Vrmin)

tmp = Vrmin;

Vrmin = Vrmax;

Vrmax = tmp;

printf(”\nWarning: Vrmax is less than Vrmin.”);

printf(”\n Vrmin set to Vrmax and Vrmax set to Vrmin”);

printf(”\n Subsystem %d, Machine %s, exciter type EXDC1.\n”, getSubsystem(),Gen);

reportError(”EXDC1”,1);

/* read initial field voltage */

efldi = get_data(Gen,”Efldi”);

/* Compute initial Vref value */

if (Vi < 0.0 || LFInit==1)

Vi= get_data(Gen,”Vpu”);

if (LDComp == 1)

6
CBuilder Tutorial: Generator Control Block

Vi = computeInitVcomp(Gen);

/* Compute initial Se + KE */

if (Ke == 0.0)

v_init = 0.0;

printf(”\nWarning: Ke entered as 0.0. Calculation of Ke such that the”);

printf(”\n initial condition of Vc is zero is not supported.”);

printf(”\n Subsystem %d, Machine %s, exciter type EXDC1.\n”, getSubsystem(),Gen);


reportError(”EXDC1x”,1);

else

v_init = initSatKE(E1,Se1,E2,Se2,efldi,Ke,&satKE1);

printf(”The value of v_init is %f\n”,v_init);

Verr = v_init/Ka;

Vref = Verr + Vi;

Vmax= 1.2;

if (Vref > Vmax) Vmax= 1.2*Vref;

/* the create_slider function is in the .h file in the INPUTS section */


/* Initialize variables for real pole #1 */

initRealPole(1.0,Tr,Vi,Vi,&realpole1);

/* Initialize variables for lead − lag */

initLeadLag(Tb,Tc,Verr,Verr,&leadlag1);

/* Initialize variables for real pole #2 */

initRealPole(Ka,Ta,Verr,v_init,&realpole2);

/* Initialize variables for wash out */

7
CBuilder Tutorial: Generator Control Block

washoutG = Kf/Tf1;

initWashout(washoutG,Tf1,efldi,&washout1);

/* Initialize variables for integrator */

initIntegrator(Te,0.0,efldi,&integrator1);

/* Check initial output values are within Vrmax and Vrmin limits */

if (v_init > Vrmax || v_init < Vrmin)

printf(”\nWarning: Initial value of mon6 is not within the entered limits.”);

printf(”\n VRmax = %f, VRmin = %f, mon6 initial value = %f.”,Vrmax,Vrmin,v_init);

printf(”\n Subsystem %d, Machine %s, exciter type EXDC1x.\n”, getSubsystem(),Gen);

reportError(”EXDC1x”,1);

/* Initialize all monitoring variables that are going to be referenced in the code section before they are
assigned a value */

mon9 = v_init;

mon10 = 0.0;

CODE:

double puSpeed;

/* Include load compensation */

if (LDComp==1)

mon1 = VC;

else

mon1 = VPU;

/* realpole #1*/

8
CBuilder Tutorial: Generator Control Block

mon2 = realPole(mon1, 1.0, 0, 0.0, 0.0,0,0,0.0, &realpole1);

/* Summing junction */

mon3 = Vref1 − mon2;

/* Optionally include stabilizer input */

if (PSS == 1)

mon3 = mon3 + VS;

mon4 = mon3 − mon10;

/* lead−lag */

mon5 = leadLag(mon4,1.0,0,0.0,0.0,0,0,0.0,&leadlag1);

/* realpole #2 */

mon6 = realPole(mon5,Ka,1,Vrmin,Vrmax,0,0,0.0,&realpole2);

/* Summing Junction */

mon7 = mon6 − mon9;

/* Integrator */

mon8 = integrator(mon7,0,0.0,0.0,0,0,0.0,&integrator1);

/* Saturation Function */

mon9 = satKE(mon8, &satKE1);

/* Washout */

mon10 = washOut(mon8,washoutG,0,0.0,0.0,0,0,0.0,&washout1);

/* Efd */

OUT = mon8;

if (spdMult == 1)

puSpeed = Speed/wBase;

OUT = mon8 * puSpeed;

9
CBuilder Tutorial: Generator Control Block

/*check if monitoring is enabled, if so assign the output based on the dial position*/

if (Mon ==1)

if (dial1 == 2)

internalV = mon2;

else if (dial1 == 3)

internalV = mon3;

else if (dial1 == 4)

internalV = mon4;

else if (dial1 == 5)

internalV = mon5;

else if (dial1 == 6)

internalV = mon6;

else if (dial1 == 7)

internalV = mon7;

else if (dial1 == 8)

internalV = mon8;

10
CBuilder Tutorial: Generator Control Block

else if (dial1==9)

internalV = mon9;

else if (dial1==10)

internalV = mon10;

else

internalV = mon1;

7.5 DATA PREPARATION AND INITIALIZATION


Generic generator control models include the capability to initialize their internal variables
and to configure set−point sliders. Given the initial field voltage, the initial terminal voltage
and various gains of the exciter components, it is possible to compute the initial inputs and
output associated with each block of the DC1 controller. The initial terminal voltage and
gains of the exciter components are entered to the component as parameters. The initial
field voltage is computed by the generator model code and can be accessed using the
get_data function. The get_data function locates and returns data from another component.
In the RAM section the initial field voltage is determined using the code below;
efldi = get_data(Gen,”Efldi”);

The get data function requires two arguments. The first argument is the name of the
component, the second argument is the parameter name.
The name of the generator to which the exciter model is connected is required as a
parameter named ’Gen’.
The generator model pre−calculates the field voltage required to provide the desired real
and reactive power output. This data is written to the .map file and given the variable “Efldi”.
To extract the initial field voltage from the generator model, the parameter name Efldi must
be passed to the get_data function. The parameter name is case sensitive.
The error is calculated as the initial output of the saturation block ’v_init’ divided by the gain
Ka.

11
CBuilder Tutorial: Generator Control Block

Verr= v_init/Ka;

The initial value for Vref slider is computed as:


Vref= Vi+Verr;
Vmax= 1.2;
if (Vref > Vmax) Vmax= 1.2*(Vref);

The initial value ’Vref’ and the maximum value ’Vmax’ are used to initialize the slider in the
following section ’ADD AN INTERNAL SLIDER’.
Commonly used control functions are available as function calls in CBuilder. In this case, the
realPole, leadLag, washOut and Integrator functions are used. To use these functions in the
CODE section, the history terms must first be initialized in the RAM section. The calculated
history terms are then stored in a structure for use within the CODE section. The initialization
functions are stored in a file named “initTransferFunctions.inc”. This include statement must
appear in the RAM_FUNCTIONS section. Optionally, the initialization functions could appear
directly in the RAM_FUNCTIONS section and not in an include file. Please see APPENDIX E of
the CBuilder User’s Manual for complete details on initialization of the transfer functions.
RAM_FUNCTIONS:
#include “initTransferFunctions.inc”

The functions in the ’initTransferFunctions.inc’ file can be called from the RAM section.
/* Initialize variables for saturation function */
if (Ke <= 0.0)
{
v_init= initSatKE0(E1,Se1,E2,Se2,efldi,Vrmax,Cal,&satKE1);
}
else
{
v_init =
initSatKE(E1,Se1,E2,Se2,efldi,Ke,Cal,&satKE1);
}

/* Initialize variables for real pole #1 */


initRealPole(1.0,Tr,Vi,Vi,&realpole1);
/* Initialize variables for lead − lag */
initLeadLag(Tb,Tc,Verr,Verr,&leadlag1);
/* Initialize variables for real pole #2 */

12
CBuilder Tutorial: Generator Control Block

initRealPole(Ka,Ta,Verr,v_init,&realpole2);
/* Initialize variables for wash out */
washoutG = Kf/Tf1;
initWashout(washoutG,Tf1,efldi,&washout1);
/* Initialize variables for integrator */
initIntegrator(Te,0.0,efldi,&integrator1);

For example, to initialize the first realpole, the gain, time constant, initial input, initial output
and realpole structure are passed as parameters. The initial input and output of the realpole
are set to initial p.u voltage of the generator. The leadLag is initialized next, the precalculated
Verr value is passed as the initial input and output of the leadlag.

7.6 ADD AN INTERNAL SLIDER


Referring to the block diagram, a slider Vref is required as input to the control block. The
slider is an internal input to the component meaning that a physical input connection does
not exist on the component.
• Add an internal slider. Click the Add Variable button (see 1 of Figure 7.3) and then
select SLIDERS from the Section drop down menu in the “Add Variable” window (see
2 of Figure 7.3).

Figure 7.3: Adding an Internal Slider

When the parameter is selected the edit menu appears to the right window as shown in
Figure 7.4.

13
CBuilder Tutorial: Generator Control Block

Figure 7.4: Slider Menu Edit Option

• Assign a variable name to the slider so it can be referenced in the Code section. In
this example Vref1 is used.
• A slider name is required. This is the name of the slider as it will appear in RunTime.
To duplicate existing generic generator control models the Vref slider is located
under the CTLs|Inputs group and named V_generator name. To concatenate two
strings together, the strcat2 function can be used to create the slider name. The initial
value of the slider has been calculated in the RAM section and assigned to variable
Vref. The maximum value of the slider has also been calculated in the RAM section
and assigned to variable Vmax. The variables Vref and Vmax are entered as Initial
Value and Max Value.
• Save the CBuilder component.
After saving the component, a create_slider function appears in the INPUTS: section
of the .h file. The slider name ’Vref1’ can be used within the CODE section of the .c
file.

14
CBuilder Tutorial: Generator Control Block

7.7 ADD CODE FOR REALPOLE FUNCTION


The function realPole implements the transfer function as shown in Equation 7-1.

𝐺
𝑌(𝑠) = ∗ 𝑋(𝑠) Equation 7-1
(1 + 𝑠𝑇)

In the code section, the realPole function is called as follows:


/* realpole */

out=realPole(Input, Gain, Limit, minLim, maxLim,RST,RSTSIG,RVAL, &realpole1);

The realPole function requires nine arguments. For a complete description of the arguments
please see APPENDIX E of the CBuilder User’s Manual. The function returns the output Y(s)
of the realpole transfer function.

7.8 ADD CODE LEADLAG FUNCTION


The function leadLag implements the transfer function as shown in Equation 7-2.

𝐺(1 + 𝑠𝑇1)
𝑌(𝑠) = ∗ 𝑋(𝑠) Equation 7-2
(1 + 𝑠𝑇2)

In the code section, the leadLag function is called as follows:


/* leadLag */

out=leadLag(Input, Gain, Limit, minLim, maxLim,RST,RSTSIG,RVAL, &leadlag1);

The leadLag function requires nine arguments. For a complete description of the arguments
please see APPENDIX E of the CBuilder User’s Manual. The function returns the output Y(s)
of the leadLag transfer function.

7.9 ADD CODE FOR WASHOUT FUNCTION


The function washOut implements the transfer function as shown in Equation 7-3.

𝐺𝑠𝑇
𝑌(𝑠) = ∗ 𝑋(𝑠) Equation 7-3
(1 + 𝑠𝑇)

In the code section, the washOut function is called as follows:


/* washOut*/

out=washOut(Input, Gain, Limit, minLim, maxLim,RST,RSTSIG,RVAL, &washout1);

The washOut function requires nine arguments. For a complete description of the arguments
please see APPENDIX E of the CBuilder User’s Manual. The function returns the output Y(s)
of the washOut transfer function.

15
CBuilder Tutorial: Generator Control Block

7.10 ADD CODE FOR SATURATION FUNCTION


The saturation function satKE implements the saturation curve.

Figure 7.5: Saturation Curve

In the code section, the satKE function is called as follows:


/* saturation */

out=satKE(Input, &satKE1);

7.11 ADDING THE CODE


• Read in the p.u. voltage and check for load compensation.
if (LDComp==1)
{
mon1 = VC;
}
else
{
mon1 = VPU}

• Add function call for the first realpole function.


mon2 = realPole(VPU, 1.0, 0, 0.0, 0.0,0,0,0.0, &realpole1);

The realpole function requires nine arguments. The first argument is the input. Input
to the first realpole block is the p.u. voltage from the generator model. This input is

16
CBuilder Tutorial: Generator Control Block

an I/O point on the component and declared in the .h file as VPU.


The second argument is the gain. The gain is fixed at 1.0.
The third, fourth and fifth arguments are for limits. Limits are not included in this
block and therefore set to 0.
The sixth, seventh and eigth arguments are for reset. Reset is not included in this
block and therefore set to 0.
The ninth argument is the realpole structure. The variables within the structure were
initialized in the RAM section.
The output from the realpole is assigned the variable name ’mon2’ according to the
block diagram.
• Add code for the summing junction.
/* Summing junction */
mon3 = Vref1 − mon2;

/* Optionally include stabilizer input */


if (PSS == 1)
{
mon3 = mon3 + VS;
}

The summing junction subtracts the output from the realpole ’mon2’ from the Vref
slider. An optional third input can exist to the summing junction. If the parameter
PSS is set to YES in the component, a stabilizer input signal input is available and
added to the above. The output from the summing junction is assigned the variable
name mon3.
• Add code for the summing junction.
mon4 = mon3 − mon10;

The output from the washout block (mon10) is subtracted from the output of the
previous summing junction according to the block diagram.
• Add function call for the leadlag function.
mon5 = leadLag(mon4,1.0,0,0.0,0.0,0,0,0.0,&leadlag1);

The leadLag function requires nine arguments. The first argument is the input. Input
to the leadLag function is the output from the previous summing junction (mon4).

17
CBuilder Tutorial: Generator Control Block

The second argument is the gain. The gain is fixed at 1.0. The third, fourth and fifth
arguments are for limits. Limits are not included in this block and therefore set to
0.
The sixth, seven and eigth arguments are for reset. Reset is not included in this
block and therefore set to 0.
The ninth argument is the leadlag structure. The variables within the structure were
initialized in the RAM section.
The output from the leadlag is assigned the variable name ’mon5’ according to the
block diagram.
• Add function call for the second realpole function.
mon6 = realPole(mon5,Ka,1,Vrmin,Vrmax,0,0,0.0,&realpole2);

Input to the second realPole function is the output from the leadlag (mon5).
The second argument is the gain. The gain ’Ka’ is entered as a parameter.
Limits are included in the second realPole, therefore the third argument is set to 1.
The fourth and fifth arguments are the minimum and maximum limits Vrmin and
Vrmax. Vrmin and Vrmax are parameters entered by the user.
The sixth, seven and eigth arguments are for reset. Reset is not included in this
block and therefore set to 0.
The ninth argument is the realpole#2 structure. The variables within the structure
were initialized in the RAM section.
The output from the realpole is assigned the variable name mon6 according to the
block diagram.
• Add code for summing junction.
mon7 = mon6 − mon9;

The output from the saturation block (mon9) is subtracted from the output of
realpole#2 (mon6).
• Add function call for the integrator function.
mon8 = integrator(mon7,0,0.0,0.0,0,0,0.0,&integrator1);

The first argument in the integrator function call is the input. Input to the integrator
function is the output from the previous summing junction (mon7).
The second, third and fourth arguments are for limits. Limits are not included in this
block and therefore set to 0.

18
CBuilder Tutorial: Generator Control Block

The fifth, sixth and seven arguments are for reset. Reset is not included in this block
and therefore set to 0.
The eighth argument is the integrator structure. The variables within the structure
were initialized in the RAM section.
The output from the integrator is assigned the variable name ’mon8’ according to
the block diagram.
• Add function call for the saturation function.
mon9 = satKE(mon8,&satKE1);

The first argument in the satKE function call is the input. Input to the satKE function
is the output from the previous integrator (mon8).
The second argument is the saturation structure. The variables within the structure
were initialized in the RAM section.
• Add function call for the washout function.
mon10 = washOut(mon8,washoutG,0.0,0.0,0,0,0.0,&integrator1);

The first argument in the washOut function call is the input. Input to the washOut
function is the output from the integrator (mon8).
The second argument is the gain. The gain is computed as Kf/Tf1.
The third, fourth and fifth arguments are for limits. Limits are not included in this
block and therefore set to 0.
The sixth, seventh and eighth arguments are for reset. Reset is not included in this
block and therefore set to 0.
The ninth argument is the washout structure. The variables within the structure were
initialized in the RAM section.
The output from the washout is assigned the variable name ’mon10’ according to the
block diagram.
• Add multiplier and compute the output field voltage.
if (spdMult == 1){
puSpeed = Speed/wBase;
OUT = mon8 * puSpeed; }

The p.u speed is determined by dividing the machine speed by the base value
(wBase). wBase is a parameter entered by the user and Speed is an I/O point on the
component and declared in the .h file as Speed.

19
CBuilder Tutorial: Generator Control Block

The output from the integrator (mon8) is multiplied by the p.u. speed of the machine
to produce the field voltage (OUT). The signal OUT is an I/O point on the component
and declared in the .h file as OUT.

7.12 ADD A DIAL TO SELECT INTERNAL VARIABLES FOR MONITORING


Internal variables are displayed on the block diagram of the DC1 controller and are identified
with a mon# wire label. To maintain similar operation to existing generator controls, only
one internal variable may be monitored at one time in RunTime. The position of a dial
indicates which internal variable is displayed in RunTime.
• Add an internal dial. Click the Add Variable button (see 1 of Figure 7.6) and then select
DIALS from the Section drop down menu in the “Add Variable” window (see 2 of
Figure 7.6).

Figure 7.6: Adding a Dial

• Assign a variable name to the dial so it can be referenced in the Code section. In this
example dial1 is used.
• Use the Edit dial window to enter initial values for the dial.
• A dial name is required. This is the name of the dial as it will appear in RunTime. To
duplicate existing generic generator control models the dial is named “exc_mon” and
is located under the Machines|generatorname group to concatenate two strings
together, the strcat2 function can be used to create the Group name. The number of
internal monitoring variables is 10, therefore the number of positions available on
the dial has been set to 10. The initial position of the dial is set to 1. The dial values
are stored in an array with name mon_array. This array must be declared in the static
section of the .c file. Creation of the dial is conditional. If the parameter Mon

20
CBuilder Tutorial: Generator Control Block

(Monitor internal variable) is toggled to Yes, then the dial is created.


• Save the CBuilder component.
After saving the component, a create_dial function appears in the INPUTS: section of
the .h file. The dial name ’dial1’ can be used within the CODE section of the .c file.

7.13 ADD A GENERIC OUTPUT


An output signal must be added to display the monitored internal variable in RunTime.
• Add a generic output variable.

Figure 7.7: Adding a Generic Output

• Assign a variable name to the generic output so it can be referenced in the Code
section. In this example internalV is used.
• Use edit option to enter the initial values for the generic output variable.
A generic output is required to display internal variables in RunTime. An output name
is required, this is the name of the signal as it will appear in RunTime. The variable
name ivName is entered. ’ivName’ is a parameter. Therefore, the signal name
entered as parameter ’ivName’ is used as the output name. To duplicate existing
generic generator control models the signal name is located under the
Machines|generatorname group. To concatenate two strings together, the strcat2
function can be used to create the Group name. Creation of the generic output is
conditional. If the parameter Mon (Monitor internal variable) is toggled to Yes, then
the output signal is created.

7.14 ADD MONITORING CODE


The internal variables named mon# can be plotted in RunTime. The signal to monitor is based

21
CBuilder Tutorial: Generator Control Block

on the dial position.


• Add monitoring code for internal variables.
if (Mon == 1)
{
if (dial1 == 2)
{
internalV = mon2;
}
else if (dial1 == 3)
{
internalV = mon3;
}
else if (dial1 == 4)
{
internalV = mon4;
}
else if (dial1 == 5)
{
internalV = mon5;
}
else if (dial1== 6)
{
internalV = mon6;
}
else if (dial1 == 7)
{
internalV = mon7;
}
else if (dial1 == 8)
{
internalV = mon8;
}
else if (dial1==9)
{

22
CBuilder Tutorial: Generator Control Block

internalV = mon9;
}
else if (dial1==10)
{
internalV = mon10;
}
else
{
internalV = mon1;
}
}

Monitoring is enabled if the parameter Mon is toggled to Yes in the component. If the dial
position is 2, then the generic output signal ’exc_mon1’ is assigned internal variable mon2.
If the dial position is 3, then the generic output signal ’exc_mon1’ is assigned internal
variable mon3 etc. This code continues until all 9 dial positions have been associated with
an output. Note: the variable name of the dial declared in the .h file is dial1. The dial name
in RunTime will appear as exc_dial. The variable name of the generic output declared in the
.h file is exc_mon1. The name of the generic output will appear in RunTime as exc_mon.

23
8 SIMPLE TRANSFORMER

8.1 INTRODUCTION
The transformer model developed in this tutorial will include winding resistance, leakage
reactance as well as a linear magnetizing reactance. The effect of core saturation will not be
considered.

8.2 THEORY
8.2.1 Modelling a Transformer
Most power system components, regardless of their complexity, are simplified so that they
are modeled as one or more current sources in parallel with a conductance. The difficulty in
modeling components is often a problem of finding such a representation that accurately
represents the physical properties of the device being modeled. Our goal is to reduce the
two-winding transformer to something similar to what is shown in Figure 8.1. The equations
developed must model the coupling between the two windings of the transformer.

Figure 8.1: Framework for How to Model a Transformer

One of the keys to writing a successful power system model is to write out the correct
equations. It may be possible to write a set of equations in the continuous time−domain
which accurately represent the behavior of a particular piece of equipment but it may not

1
CBuilder Tutorial: Simple Transformer

be possible to discretize these equations in such a way that they can be seamlessly
integrated with the RTDS Solution Algorithm. Not only must the equations written be correct
in terms of physics, they must also integrate into the existing solution framework of the
simulator. The selection of the proper equations is often dependent upon experience.
Consider the per−unitized equivalent circuit for a transformer given in Figure 8.2. The
winding resistance and leakage reactance have been divided in half and the magnetizing
branch has been connected in the middle. Two loop equations can be written for this circuit.
The resulting equations are given by Equation 8-1 and Equation 8-2.

Figure 8.2: Per-Unitized Equivalent Circuit for a Transformer

𝑟𝑠 𝑥𝑙
𝑣1 (𝑡) = 𝑖1 (𝑡) + 𝑗 𝑖1 + 𝑗𝑥𝑚 (𝑖1 (𝑡) + 𝑖2 (𝑡)) Equation 8-1
2 2
𝑟𝑠 𝑥𝑙
𝑣2 (𝑡) = 𝑖2 (𝑡) + 𝑗 𝑖2 (𝑡) + 𝑗𝑥𝑚 (𝑖1 (𝑡) + 𝑖2 (𝑡)) Equation 8-2
2 2

The values in Equation 8-1 and Equation 8-2 are all per−unitized; Equation 8-1 and Equation
8-2 are re−written in ohmic values as Equation 8-3 and Equation 8-4, respectively. Equation
8-3 has been referred to the primary side while Equation 8-4 has been referred to the
secondary side.

𝑟𝑠 𝑣𝑟𝑎𝑡𝑒𝑑 12 𝑥𝑙 𝑣𝑟𝑎𝑡𝑒𝑑 12 𝑣𝑟𝑎𝑡𝑒𝑑 12 𝑣𝑟𝑎𝑡𝑒𝑑 2


𝑣1 (𝑡) = 𝑖1 (𝑡) + 𝑗 ( + 𝑥𝑚 ) 𝑖1 (𝑡) + 𝑗𝑥𝑚 𝑖 (𝑡) Equation 8-3
2 𝑠𝑟𝑎𝑡𝑒𝑑 2 𝑠𝑟𝑎𝑡𝑒𝑑 𝑠𝑟𝑎𝑡𝑒𝑑 𝑣𝑟𝑎𝑡𝑒𝑑 1 2

𝑟𝑠 𝑣𝑟𝑎𝑡𝑒𝑑 22 𝑥𝑙 𝑣𝑟𝑎𝑡𝑒𝑑 22 𝑣𝑟𝑎𝑡𝑒𝑑 22 𝑣𝑟𝑎𝑡𝑒𝑑 1


𝑣2 (𝑡) = 𝑖2 (𝑡) + 𝑗 ( + 𝑥𝑚 ) 𝑖2 (𝑡) + 𝑗𝑥𝑚 𝑖 (𝑡) Equation 8-4
2 𝑠𝑟𝑎𝑡𝑒𝑑 2 𝑠𝑟𝑎𝑡𝑒𝑑 𝑠𝑟𝑎𝑡𝑒𝑑 𝑣𝑟𝑎𝑡𝑒𝑑 2 1

Written in matrix form, Equation 8-3 and Equation 8-4 become Equation 8-5 and Equation
8-6, respectively.

2
CBuilder Tutorial: Simple Transformer

𝑟𝑠
𝑣1 (𝑡) 1 𝑣𝑟𝑎𝑡𝑒𝑑 12 0
[ ]= [ 2 ]
𝑣2 (𝑡) 𝑠𝑟𝑎𝑡𝑒𝑑 𝑟𝑠
0 𝑣𝑟𝑎𝑡𝑒𝑑 22
[ 2
𝑥𝑙
Equation 8-5
(𝑥𝑚 + ) 𝑣𝑟𝑎𝑡𝑒𝑑 12 𝑥𝑚 𝑣𝑟𝑎𝑡𝑒𝑑1 𝑣𝑟𝑎𝑡𝑒𝑑2 𝑖 (𝑡)
+𝑗[ 2 ] [1 ]
𝑥𝑙 2 𝑖2 (𝑡)
𝑥𝑚 𝑣𝑟𝑎𝑡𝑒𝑑1 𝑣𝑟𝑎𝑡𝑒𝑑2 (𝑥𝑚 + ) 𝑣𝑟𝑎𝑡𝑒𝑑 2
2 ]

𝑣 (𝑡) 𝑖 (𝑡) 𝑖 (𝑡)


[ 1 ] = [𝑟] [ 1 ] + 𝑗[𝑙] [ 1 ] Equation 8-6
𝑣2 (𝑡) 𝑖2 (𝑡) 𝑖2 (𝑡)

Equation 8-6 can be converted from the Laplace domain into the time domain and yields
Equation 8-7.

𝛿𝑖1 (𝑡)
𝑣 (𝑡) 𝑖 (𝑡)
] + [𝑙] [ 𝛿𝑡 ]
1
[ 1 ] = [𝑟] [ Equation 8-7
𝑣2 (𝑡) 𝑖2 (𝑡) 𝛿𝑖2 (𝑡)
𝛿𝑡

𝛿𝑖(𝑡)
[𝑣(𝑡)] = [𝑟][𝑖(𝑡)] + [𝑙] [ ] Equation 8-8
𝛿𝑡

Equation 8-8 can then be numerically integrated over a time−step using trapezoidal
integration.

(𝑣(𝑡) + 𝑣(𝑡 − ∆𝑡)) (𝑖(𝑡) + 𝑖(𝑡 − ∆𝑡))


[ ∆𝑡] = [𝑟] [ ∆𝑡] + [𝑙][𝑖(𝑡) − 𝑖(𝑡 − ∆𝑡)] Equation 8-9
2 2

Reorganization of Equation 8-9 leads to Equation 8-10.

[𝑖(𝑡)] = [𝑔𝑇𝑟 ][𝑣(𝑡)] + [𝑖ℎ(𝑡)] Equation 8-10

Where:
−1
𝑡 [𝑟]∆𝑡 Equation 8-11
𝑔𝑇𝑟 =∆ [ + [𝑙]]
2 2

2
[𝑖ℎ(𝑡)] = [𝑔𝑇𝑟 ] [[𝑣(𝑡 − ∆𝑡)] − [[𝑟] − [𝑙] ] [𝑖(𝑡 − ∆𝑡)]] Equation 8-12
∆𝑡

Equation 8-10 describes the currents entering the two terminals of the transformer. Each of
these two currents has two components. A portion of each current is a function of the
voltages across the terminals of the transformer at the current time−step. The other portion

3
CBuilder Tutorial: Simple Transformer

of each current can be considered as being contributed by a current source that is a function
strictly of the currents flowing into the transformer and the voltages across the terminals of
the transformer at the previous time−step. The component of the current vector [i(t)] that
is a function of past voltages and currents is grouped and labeled as [ih(t)]. This term is
generally known as a history current because it is a function strictly of the past voltages and
currents across and through the transformer.
At this point it is instructive to take a step back and look at the RTDS Simulator’s algorithm
in order to show how Equation 8-10 can be incorporated into it.
8.2.2 RTDS Solution Algorithm
The most effective way to explain the RTDS Solution Algorithm is to do so via example. Figure
8.3 shows a simple source connected to an RLC circuit. Two nodes have been labeled.

Figure 8.3: Arbitrary Circuit Used to Demonstrate RTDS Solution Algorithm

A Norton equivalent can be found for the voltage source and series resistance. It can be
shown that both the inductor and capacitor can each be represented by a current source in
parallel with a conductance. [1] The current sources become functions of past voltages and
currents across and through the element and are generally referred to as history currents.
For this tutorial the details of how to calculate these history currents is not critical; assume
they are known quantities. An equivalent for Figure 8.3 can then be drawn as shown in Figure
8.4. The circuit now consists strictly of current sources and conductance.

4
CBuilder Tutorial: Simple Transformer

Figure 8.4: Arbitrary Circuit Modified so that it Consists Purely of Current Sources and
Conductance Values

Writing the nodal equations at nodes 1 and 2 leads to Equation 8-13 and Equation 8-14
which can be written in matrix form as shown in Equation 8-15.

𝑖𝑠 = 𝑖ℎ𝑙 + 𝑣1 ∙ 𝑔𝑠 + (𝑣1 − 𝑣2 ) ∙ 𝑔𝑙 Equation 8-13

𝑖ℎ𝑙 = 𝑖ℎ𝑐 + (𝑣2 − 𝑣1 ) ∙ 𝑔𝑙 + 𝑣2 ∙ 𝑔𝑐 Equation 8-14

𝑔 +𝑔 −𝑔𝑙 𝑣1 𝑖𝑠 − 𝑖ℎ1
[ 𝑠−𝑔 𝑙 𝑔𝑙 + 𝑔𝑐 ] [𝑣2 ] = [𝑖ℎ1 − 𝑖ℎ𝑐 ]
Equation 8-15
𝑙

In Section 8.2.3 the calculations needed to simulate the interconnected circuits of this and
the previous section are enumerated. Details about how these calculations are divided
among several processors are then given.
8.2.3 Integrating the Transformer Model into the RTDS Solution Algorithm
In the circuit of Figure 8.5 the simple transformer model has been added to the arbitrary
circuit of Figure 8.4. The nodal equations for this circuit can be written as before except now
our system has three nodes. The resulting equations are shown in Equation 8-16, Equation
8-17, and Equation 8-18.

5
CBuilder Tutorial: Simple Transformer

Figure 8.5: Arbitrary Circuit with Simple Transformer Added to it

𝑖𝑠 = 𝑖ℎ1 + 𝑣1 ∙ 𝑔𝑠 + (𝑣1 − 𝑣2 ) ∙ 𝑔𝑙 Equation 8-16

𝑖ℎ𝑙 = 𝑖ℎ𝑐 + (𝑣2 − 𝑣1 ) ∙ 𝑔𝑙 + 𝑣2 ∙ 𝑔𝑐 + 𝑖𝑝𝑟𝑖 Equation 8-17

0 = 𝑖𝑠𝑒𝑐 Equation 8-18

If Equation 8-10 is rewritten with the appropriate indexing the terms ipri and isec can be
defined as given in the following equation.

𝑖𝑝𝑟𝑖 𝑔𝑇𝑅 𝑔𝑇𝑅 23 𝑣2 𝑖ℎ𝑝𝑟𝑖


[ ] = [𝑔 22 𝑔𝑇𝑅 33 ] [𝑣3 ] + [𝑖ℎ𝑠𝑒𝑐 ] Equation 8-19
𝑖𝑠𝑒𝑐 𝑇𝑅 32

Substituting Equation 8-19 into Equation 8-16, Equation 8-17, and Equation 8-18 and
re−arranging them gives the matrix Equation 8-20.

𝑔𝑠 + 𝑔𝑙 −𝑔𝑙 0 𝑣1 𝑖𝑠 − 𝑖ℎ𝑙
[ −𝑔𝑙 𝑔𝑙 + 𝑔𝑐 + 𝑔𝑇𝑅 22 𝑔𝑇𝑅 23 ] [𝑣2 ] = [𝑖ℎ𝑙 − 𝑖ℎ𝑐 − 𝑖ℎ𝑝𝑟𝑖 ] Equation 8-20
0 𝑔𝑇𝑅 32 𝑔𝑇𝑅 33 𝑣3 −𝑖ℎ𝑠𝑒𝑐

The solution to Equation 8-20 is the solution of the circuit of Figure 8.5. Notice that this
matrix can be assembled by inspection if parts of Equation 8-15 and 8-19 are ’overlayed’
while using the appropriate indexing.
Assuming the objective is to solve Equation 8-20 for all the node voltages, the vector
[v1,v2,v3]T can be found by inverting the conductance matrix of Equation 8-20. This leads to
Equation 8-21; time indices have been added for completeness.

6
CBuilder Tutorial: Simple Transformer

−1
𝑣1 (𝑡) 𝑔𝑠 + 𝑔𝑙 −𝑔𝑙 0 𝑖𝑠 (𝑡) − 𝑖ℎ𝑙 (𝑡)
[𝑣2 (𝑡)] = [ −𝑔𝑙 𝑔𝑙 + 𝑔𝑐 + 𝑔𝑇𝑅 22 𝑔𝑇𝑅 23 ] [𝑖ℎ𝑙 (𝑡) − 𝑖ℎ𝑐 (𝑡) − 𝑖ℎ𝑝𝑟𝑖 (𝑡)] Equation 8-21
𝑣3 (𝑡) 0 𝑔𝑇𝑅 32 𝑔𝑇𝑅 33 −𝑖ℎ𝑠𝑒𝑐 (𝑡)

Matrix Equation 8-21 is representative of the main calculation completed by the RTDS
Network Solution. It describes the interaction of all the elements in a circuit.
Before the RHS of this equation can be calculated, the currents is(t), ihl(t), ihc(t), ihpri(t) and
ihsec(t) must be known. This is where the simulation gets broken up into several parts.
The currents is(t), ihpri(t) and ihsec(t) which originate from the voltage source and transformer
can be calculated in parallel on different processors in order to reduce the computation time.
These current contributions will be referred to as current injections because they are injected
into the RTDS Network Solution.
The currents ihl(t) and ihc(t) are contributions from the circuit’s inductor and capacitor. In
general, the calculations associated with passive RLC components are included as part of the
network solution.
Figure 8.6 illustrates how the calculation of Equation 8-21 is divided among several
processors and gives some details about how the simple transformer model interacts with
the Network Solution. Figure 8.6 is very simplified and many details have been omitted.

7
CBuilder Tutorial: Simple Transformer

Figure 8.6: Interaction between Simple Transformer and the Network Solution

1. In the first part of any given time step, the network voltage vector from the previous
time−step, [V(t−1)], are used to calculate the currents flowing into the transformer at
the previous time−step, ipri(t−1) and isec(t−1). These two quantities can then be used to
calculate the history currents for the transformer, ihpri(t−1) and ihsec(t−1), using Equation
8-12. The calculations are done on a dedicated processor labeled component processor
#1.

2. While the history currents are being calculated for the simple transformer on
component processor #1, the calculation of is(t−1) for the voltage source are completed
on a different processor labeled component processor #2. Details of the calculation of
is(t−1) are not the focus of this tutorial. If the example circuit contained additional
components like a generator or a transmission line the currents associated with those
components could be calculated simultaneously on other processors in order to reduce
the computation time.

8
CBuilder Tutorial: Simple Transformer

3. The RTDS Network solution is responsible for the calculations associated with most
passive RLC components so it calculates ihl(t−1) and ihc(t−1).

4. The currents calculated in (1)−(3) become the current injections for then network
solution. The current injections are sent to the processor which calculates the main
network solution at a designated time labeled communication interval T0. The network
solution then uses the current injections to calculate the circuit’s node voltages by
solving Equation 8-21.

5. The calculated voltages are passed to all the component processors and the process
starts again at the next time−step.

These five steps illustrate how the calculation of Equation 8-21 could be divided among
several processors on the RTDS Simulator. The simple transformer model that will be
assembled in CBuilder is responsible for Step 1, the calculation of the transformer’s current
injections, as well as for the calculation of the transformer’s contribution to the conductance
matrix of Equation 8-21.
Every power system component makes two types of contributions to the RTDS Network
Solution: (1) current injections and (2) conductance values. Current injections are calculated
every time−step and are communicated to the RTDS Network Solution every time−step. The
conductance value contributions of component can either be fixed or time−varying
depending on the complexity of the component. If they are fixed they are calculated once
before the simulation is ran; if they are time−varying they are calculated every time−step
and must be communicated to the network solution every time−step. The simple
transformer of this tutorial does not include variable conductance values.
Next, a generalization of the transformer equations derived earlier is completed before the
component is implemented in Section 8.2.4.
8.2.4 Generalizing the Transformer Equations
All derivations done up to this point have assumed connections to ground at each end of the
transformer. The model will now be generalized so that a direct ground connection at the
winding is not assumed. Instead of measuring the voltage across the terminals of each
winding, each winding terminal is given its own label. This is reflected in Figure 8.7.

9
CBuilder Tutorial: Simple Transformer

Figure 8.7: Adjusted Framework for Transformer Model

Equation 8-10 can then be re−written as Equation 8-22.

𝑖𝑝𝑟𝑖_𝑝 (𝑡) 𝑔𝑇𝑅 𝑔𝑇𝑅 12 𝑣𝑝𝑟𝑖_𝑝 (𝑡) − 𝑣𝑝𝑟𝑖_𝑛 (𝑡) 𝑖ℎ𝑝𝑟𝑖 (𝑡)
[ ] = [ 𝑔 11 ] [
𝑔𝑇𝑅 22 𝑣sec_𝑝 (𝑡) − 𝑣sec_𝑛 (𝑡) ] + [ ] Equation 8-22
𝑖sec_𝑝 (𝑡) 𝑇𝑅21 𝑖ℎ (𝑡) 𝑠𝑒𝑐

Knowing that ipri_n(t) and isec_n(t) are equal to −ipri_p(t) and −isec_p(t) respectively, the
generalized matrix equation for our simple transformer can be written as in Equation 8-23.

𝑖𝑝𝑟𝑖_𝑝 (𝑡) 𝑔𝑇𝑅 11 𝑔𝑇𝑅 12 −𝑔𝑇𝑅 11 −𝑔𝑇𝑅 12 𝑣𝑝𝑟𝑖_𝑝 (𝑡) 𝑖ℎ𝑝𝑟𝑖 (𝑡)
𝑖sec_𝑝 (𝑡) 𝑔𝑇𝑅 21 𝑔𝑇𝑅 22 −𝑔𝑇𝑅 21 −𝑔𝑇𝑅 22 𝑣sec_𝑝 (𝑡) 𝑖ℎ𝑠𝑒𝑐 (𝑡)
= [−𝑔 −𝑔𝑇𝑅 12 𝑔𝑇𝑅 11 𝑔𝑇𝑅 12 ] 𝑣 + Equation 8-23
𝑖𝑝𝑟𝑖_𝑛 (𝑡) 𝑇𝑅 11 𝑝𝑟𝑖_𝑛 (𝑡) −𝑖ℎ𝑝𝑟𝑖 (𝑡)
−𝑔𝑇𝑅 21 −𝑔𝑇𝑅 22 𝑔𝑇𝑅 21 𝑔𝑇𝑅 22
𝑖 (𝑡)
[ sec⁡ _𝑛 ] [𝑣sec_𝑛 (𝑡) ] [−𝑖ℎ𝑠𝑒𝑐 (𝑡)]

Where:

𝑟𝑠
1 𝑣𝑟𝑎𝑡𝑒𝑑 12 0
𝑟= [ 2 ]⁡ Equation 8-24
𝑠𝑟𝑎𝑡𝑒𝑑 𝑟𝑠 2
0 𝑣
2 𝑟𝑎𝑡𝑒𝑑 2
𝑥𝑙
1 (𝑥𝑚 + 𝑣𝑟𝑎𝑡𝑒𝑑 12 ) 𝑥𝑚 𝑣𝑟𝑎𝑡𝑒𝑑1 𝑣𝑟𝑎𝑡𝑒𝑑2
𝑙= [ 2 ] Equation 8-25
𝑠𝑟𝑎𝑡𝑒𝑑 𝑥 𝑣 𝑥𝑙 2
𝑚 𝑟𝑎𝑡𝑒𝑑1 𝑣𝑟𝑎𝑡𝑒𝑑2 (𝑥𝑚 + ) 𝑣𝑟𝑎𝑡𝑒𝑑 2
2

10
CBuilder Tutorial: Simple Transformer

−1
∆𝑡 [𝑟]∆𝑡 𝑔𝑇𝑅 𝑔𝑇𝑅 12
𝑔𝑇𝑅 = [ + [𝑙]] = [𝑔 11 𝑔𝑇𝑅 22 ] Equation 8-26
2 2 𝑇𝑅 21

𝑖ℎ𝑝𝑟𝑖 (𝑡) 𝑣𝑝𝑟𝑖_𝑝 (𝑡 − ∆𝑡) 2 𝑖𝑝𝑟𝑖_𝑝 (𝑡 − ∆𝑡)


[ ] = [𝑔𝑇𝑅 ] [[ ] − [[𝑟] − [𝑙] ] [ ]] Equation 8-27
𝑖ℎ𝑠𝑒𝑐 (𝑡) 𝑣sec_𝑝 (𝑡 − ∆𝑡) ∆𝑡 𝑖sec_𝑝 (𝑡 − ∆𝑡)

Together, Equation 8-23, Equation 8-24, Equation 8-25, Equation 8-26, and Equation 8-27
form the equations that will be used to implement the simple transformer example. Details
regarding that implementation are given in Section 8.3.

8.3 DRAW GRAPHICS AND ADD PARAMETERS


Draw a transformer icon similar to that shown in Figure 8.8. Based on the circuit of Figure
8.5, the component icon for the Simple Transformer should include four (4) power system
nodes. The node names to be used are indicated in Figure 8.8.

Figure 8.8: Icon for Simple Transformer Component

Create a new section called ’TRANSFORMER PARAMETERS’ and then add an entry for each
one of the parameters in Figure 8.9. Default data is shown in the figure. The model includes
typical transformer properties such as leakage reactance and series resistance. Being a
simple example, no special care has been taken to limit the data entered in these
parameters.

11
CBuilder Tutorial: Simple Transformer

Save the definition file that has just been created as ’SimpleTR.def’.

Figure 8.9: Parameter Data for Simple Transformer Component

8.4 ADDING THE MODEL CODE


• Select the ’C File Associations’ tab.
• Add New Association.
When a new C File Association is made for the power system component, a menu
appears in which the model name must be entered.
Creating the C File Associations for the component automatically generates the following
associations:
NODES: V1p, V1n, V2p, V2n (power system nodes)
PARAMETERS: Name[11], Xl, Ra, MVA, V1rate, V2rate, Freq and Xm (transformer
parameters)
In addition to those listed above, the following additional associations need to be made:
INJECTIONS: A current injection will be made at each of the four power system nodes. To
add an injection click the + sign beside the Injections menu. Enter the name for the current
injection variable as ’I1p’. After selecting OK the INJECTIONS section is added with the single
line representing one current injection association. Select the down arrow icon for the ’I1p’
variable and select Node ’V1p’ so that the injection is associate with the correct node. The

12
CBuilder Tutorial: Simple Transformer

type would be REAL for all the injections in this case. Add the current injection variables ’I1n’,
I2p’ and ’I2n’ and then associate them with the appropriate nodes.

Figure 8.10: Required Current Injections for the Transformer

Selecting File−>Save causes the newly added INJECTIONS variables to be written to the .h file
so they can be accessed in the .c file.

8.5 BASIC ALGORITHM


1. When the case is compiled calculate the transformer’s contribution to the global
G−matrix. The contributions are fixed.
2. Read four node voltages V1p(t−1), V2p(t−1), V1n(t−1) and V2n(t−1).

3. Compute voltages across the primary and secondary windings during the previous
time−step, V1(t−1) and V2(t−1).

4. Use the calculated voltages to calculate the current in each winding at the previous
time−step, I1(t−1) and I2(t−1).

5. Use voltages and currents from the previous time−step to calculate the current
injections for the current time−step and pass them to the network solution.

6. Let the network solution complete the calculation of something similar to Equation 8-23
and then return to step 2 at the next time−step.
The contributions of the Simple Transformer to the global conductance matrix are fixed and
do not vary with time. Because of this, these contributions only need to be calculated once
when the simulation is being compiled. This will save both computation and communication
time compared situations when the model’s conductance contributions must be calculated
every time step.
Setting up the contributions is fairly straight forward but requires that initialization code be
placed in the RAM_PASS1 section instead of the RAM section. It also requires that calls be
made to some special functions which are listed in the code below.
Click “Edit C File” button to start editing the C code.

13
CBuilder Tutorial: Simple Transformer

−−−−−−−−−−−
// Simple Transformer Tutorial Example
// E RTDS Technologies, Inc.
// Written by Gregory Jackson
// August 22nd, 2013

#include ”simpleTR01.h”

// Declare some variable that will be


// used in the RAM_PASS1 and CODE sections
STATIC:
double v1_old, v2_old;
double i1_old, i2_old;
double IH1, IH1_old, IH2, IH2_old;
double dt;
double R11, R12, R21, R22;
double L11, L12, L21, L22;
double Gtr11, Gtr12, Gtr21, Gtr22;
double A, B, C, D;
double M11, M21;

RAM:

RAM_PASS1:
//read the simulation time−step
dt = getTime-step();

14
CBuilder Tutorial: Simple Transformer

//Determine which row and column in the G−matrix is


//associated with each node. The first statement below,
//for example, associates row and column 1 of the G
//matrix to node ”V1p”. The ’g_mat_nods[]’ array is
//reserved and must be used.
g_mat_nods[0] = getNodeNum(comp,”V1p”);
g_mat_nods[1] = getNodeNum(comp,”V2p”);
g_mat_nods[2] = getNodeNum(comp,”V1n”);
g_mat_nods[3] = getNodeNum(comp,”V2n”);

//Calculate Elements of the R and L matrices [Eq. 24]


R11 = Ra*0.5*V1rate*V1rate/MVA;
R12 = 0;
R22 = Ra*0.5*V2rate*V2rate/MVA;
R21 = 0;

L11 = (Xm + Xl*0.5)*V1rate*V1rate/MVA;


L12 = Xm*V1rate*V2rate/MVA;
L21 = Xm*V1rate*V2rate/MVA;
L22 = (Xm + Xl*0.5)*V2rate*V2rate/MVA;

// Calculate the elements of the transformer’s G−matrix


// The inversion of a 4x4 matrix is completed. [Eq. 25]
A = R11*dt/2 + L11;
B = R12*dt/2 + L12;
C = R21*dt/2 + L21;
D = R22*dt/2 + L22;

15
CBuilder Tutorial: Simple Transformer

Gtr11 = dt/(2*(A*D−B*C)) * D;
Gtr12 = dt/(2*(A*D−B*C)) * −B;
Gtr21 = dt/(2*(A*D−B*C)) * −C;
Gtr22 = dt/(2*(A*D−B*C)) * A;

//Setup the G−matrix for the transformer. [Eq. 23]


//g_mat_over[][] is a reserved array that must be used.
//The conductance matrix is fixed so it only needs to be
//calculated once here when the case is compiled.
g_mat_over[0][0]= Gtr11;
g_mat_over[0][1]= Gtr12;
g_mat_over[0][2]= −Gtr11;
g_mat_over[0][3]= −Gtr12;

g_mat_over[1][0]= Gtr21;
g_mat_over[1][1]= Gtr22;
g_mat_over[1][2]= −Gtr21;
g_mat_over[1][3]= −Gtr22;

g_mat_over[2][0]= −Gtr11;
g_mat_over[2][1]= −Gtr12;
g_mat_over[2][2]= Gtr11;
g_mat_over[2][3]= Gtr12;

g_mat_over[3][0]= −Gtr21;
g_mat_over[3][1]= −Gtr22;
g_mat_over[3][2]= Gtr21;
g_mat_over[3][3]= Gtr22;

16
CBuilder Tutorial: Simple Transformer

//Pass the component’s G−matrix contributions to the main


//network solution. The function’s argument is the
//dimension of the component’s G−matrix.
setupGMatrix(4);
CODE:

BEGIN_T0:
//Calculate the voltage across each of the transformer’s
// windings at the previous time−step.
v1_old = V1p−V1n;
v2_old = V2p−V2n;

//Calculate the current flowing in


//each winding at the previous time−step.
i1_old = Gtr11*v1_old + Gtr12*v2_old + IH1_old;
i2_old = Gtr21*v1_old + Gtr22*v2_old + IH2_old;

//Calculate the transformer’s history currents [Eq. 26]


M11=v1_old−(R11−L11*2/dt)*i1_old−(R12−L12*2/dt)*i2_old;
M21=v2_old−(R21−L21*2/dt)*i1_old−(R22−L22*2/dt)*i2_old;

IH1 = Gtr11*M11 + Gtr12*M21;


IH2 = Gtr21*M11 + Gtr22*M21;

//Keep track of old history terms IH1_old = IH1;


IH2_old = IH2;
//Current injections: a −ve value implies the current
//flowing into a node;a +ve value implies the current is

17
CBuilder Tutorial: Simple Transformer

//flowing out of a node


I1p = IH1;
I1n = −IH1;
I2p = IH2;
I2n = −IH2;

T0_T2:
−−−−−−−−−−−
After adding the code, try to compile your model. If successful, add the Simple Transformer
into DRAFT and build a simple test circuit such as the one shown in Figure 8.11. For the sake
of stability, it is important to have a reference to ground on each winding of the transformer.

Figure 8.11: Simple DRAFT Case used to Test Simple Transformer Model

After compiling and running the DRAFT case you should be able the observe the correct
voltage ratio between the primary and secondary sides of the transformer. You should also
be able to observe the load voltage drop as the secondary side load impedance is reduced.
This will be due to the voltage drop across the transformer’s leakage reactance and winding
resistance.

18
CBuilder Tutorial: Simple Transformer

8.6 REFERENCES
[1] Electro−Magnetic Transients Program (EMTP) Theory Book. Hermann W. Dommel.
1987.

19
9 MULTIPLIER WITH COMPLEX NUMBERS AS INPUTS

9.1 INTRODUCTION
The component can multiply 2 or 3 complex number inputs. The operation mode can be set
to either polar or rectangular form.

9.2 CREATE THE REQUIRED PARAMETERS


The goal is to draw a component icon that looks similar to Figure 9.1.

Figure 9.1: Multiplier with Complex Numbers as Inputs Component Icon

• Ensure to create conditional graphics for the third input line i.e. if (numInputs==1)
condition is selected and draw the third input line. You can even add text (under
condition, Mode==1) to indicate the operational mode. Refer to chapter 1 for
detailed graphics drawing instructions.
• Add the following parameters.
Parameter #1
Name: numInputs
Description: Number Of Inputs
Type: TOGGLE
Unit/Toggle Entries: Two; Three

1
CBuilder Tutorial: Multiplier with Complex Numbers as Inputs

Parameter #2
Name: Mode
Description: Operation mode
Type: TOGGLE
Unit/Toggle Entries: Re,IM; |X|,∠X

9.3 ADD THE IO POINTS


In this example some of the IO points are conditional. Start by making the conditions for the
IO points.
• Select the ’IO Points’ tab.
• Create a condition so the IO Points table appears similar to Figure 9.2.

Figure 9.2: Condition Created in IO Points Tab

• Select condition ’IO Points’ (highlighted in Figure 9.2). Using the IO point tool, place
a new IO point where the Input1 connection should be.
• You will be prompted for IO point information. Enter the information below.
IO point Input1
Name: Input1
conn: SIGNAL INPUT
var: COMPLEX
Type: EITHER
Condition: Mode==0
• The COMPLEX IO point supports Re, Im or |X|, ∠X or both types of inputs. The Type
value is used to set the particular type of input. If Either is selected for Type, then a

2
CBuilder Tutorial: Multiplier with Complex Numbers as Inputs

condition must be specifed based on which input type will be selected. If the
condition evaluates to True, then a Re, Im type input is expected. In this case we will
use Mode==0 as the condition. For example, if the selected mode was ’Re, Im’, the
condition (Mode==0) evaluates to true and real and imaginary type inputs are
expected. Input1[0] will hold the Real part and Input1[1] will hold the Imaginary part
of the complex number. If the selected Mode is |X|, ∠X, the condition evaluates to
false and magnitude and angle inputs are expected. Input1[0] will hold the
magnitude part and Input1[1] will hold the angle part of the complex number.
• Repeat the above process for IO point Input2 and output.
• Next add Input3. Before adding Input3 IO point, select the condition ’If
numInputs==1’.

9.4 ADDING THE MODEL CODE


• Select the ’C File Associations’ tab.
• Select the Add New Association.
• Enter a model name such as ’cpxMul’.
• The associations should appear similar to those in Figure 9.3.

Figure 9.3: Associations

• Edit the .c file.


• After writing the ’c’ code, select the compile button to compile the code. If the
compile is successful, the component is ready to be included in a Draft circuit.
• Ensure that the component builder icon is saved.

3
CBuilder Tutorial: Multiplier with Complex Numbers as Inputs

9.5 SAMPLE ‘C’ CODE FOR THE MULTIPLE INPUT MULTIPLIER WITH COMPLEX NUMBER INPUTS
STATIC:

double RL,IM;

RAM_FUNCTIONS:

RAM:

CODE:

if(Mode == 0)
{
RL=(Input1[0]*Input2[0] − Input1[1]*Input2[1]);
IM=(Input1[0]*Input2[1] + Input1[1]*Input2[0]);
if(numInputs == 1)
{
output[0]=RL*Input3[0] − IM*Input3[1];
output[1]=RL*Input3[1] + IM*Input3[0];
}
else
{
output[0]=RL;
output[1]=IM;
}
}
else
{
if(numInputs == 1)

4
CBuilder Tutorial: Multiplier with Complex Numbers as Inputs

{
output[0]=Input1[0] * Input2[0] * Input3[0];
output[1]=Input1[1] + Input2[1] + Input3[1];
}
else
{
output[0]=Input1[0] * Input2[0];
output[1]=Input1[1] + Input2[1];
}
}

You might also like