EMTDC Intrinsic Variables

 

The intrinsic variables within EMTDC can be an essential part of interfacing user source.  A good understanding of these variables is necessary to exploit the full potential from the tools available.  The majority of EMTDC intrinsic variables are accessible to the user, and may be utilized within external source, provided that the proper header files are included.  The following sections describe the most common variables:  More detail is provided later in this chapter as well.  If more information is required on intrinsic variables that are not discussed here, please contact the PSCAD support desk (support@pscad.com).

 

For a summary of which header file corresponds to a particular variable, see Include Files to Include later in this chapter.

EMTDC Storage Arrays

Storage arrays are required in cases where variables need to be stored and made available in subsequent time steps, or when passing information from the BEGIN section of the system dynamics to DSDYN and/or DSOUT.  The storage arrays are of single-dimension (sometimes referred to as a stack), where a different array exists for each variable type.

 

 

Type

EMTDC Storage Array

Description

Inter Time Step Data Transfer

REAL

STORF(NSTORF)

For floating point (REAL) storage only.

INTEGER

STORI(NSTORI)

For INTEGER storage only.

LOGICAL

STORL(NSTORL)

For LOGICAL storage only.

COMPLEX

STORC(NSTORC)

For COMPLEX storage only.

 

 

 

 

BEGIN to DSDYN/DSOUT Data Transfer

REAL

RTCF(NRTCF)

For floating point (REAL) storage only.

INTEGER

RTCI(NRTCI)

For INTEGER storage only.

LOGICAL

RTCL(NRTCL)

For LOGICAL storage only.

COMPLEX

RTCC(NRTCC)

For COMPLEX storage only.

 

Table 5-1 - Available Storage Arrays and Pointers

Inter Time Step Data Transfer

Figure 5-1 illustrates a typical storage array used in the transfer of data between time steps.  Data may be stored at individual address locations, using the corresponding pointer integer (i.e. NSTORF, NSTORI, etc.).  Proper use of the storage pointer is essential for accurate simulation results.  If, for instance, the pointer is not properly addressed, data stored in previously called subroutines, may be over-written.

 

 

 Figure 5-1 - Typical Storage Array (STORF) Usage by System Dynamics Procedures

 

Each time step, all storage array pointers are reset to one (1) and then the main program is sequenced from top to bottom.  Using the storage array and pointer, each subroutine may write data to and read data from an array, consistent with the sequence in which the subroutine appears in the main program.  In order to avoid stored data being over-written, each subroutine must increment the respective pointer, by the amount of storage locations used in the subroutine, before returning to the main program.  This will ensure that the pointers are in their proper positions when the next storage access is performed.

 

 

 

EXAMPLE 5-1:

 

Consider a user-written subroutine that requires that two variables be stored for retrieval in subsequent time steps:  Two REAL variables X and Y and one INTEGER variable Z.   The subroutine should include something similar to what is shown below:

 

!

      SUBROUTINE U_USERSUB(...)

!

      INCLUDE ′nd.h′

      INCLUDE ′emtstor.h′

!

      REAL     X, Y, X_OLD, Y_OLD

      INTEGER  Z, Z_OLD

!

! Retrieve the variables from storage arrays:

!

      X_OLD = STORF(NSTORF)

      Y_OLD = STORF(NSTORF + 1)

      Z_OLD = STORI(NSTORI)

!

! Main body of subroutine:

!

  ...

!

! Save the variables to storage arrays for use in next time step:

!

      STORF(NSTORF)     = X

      STORF(NSTORF + 1) = Y

      STORI(NSTORI)     = Z

!

! Increment the respective pointers before returning to the main

! program (very important):

!

      NSTORF = NSTORF + 2

      NSTORI = NSTORI + 1

!

      RETURN

      END

!

 

 Listing 5-1 – Illustration of STORx Array Usage

 

A good habit to get into is to make a copy of the storage pointer, and update the original one.  The copy is used only in the local subroutine; therefore, if other nested functions or subroutines exist, storage pointer confusion is avoided.  Using this approach, the above example would become:

 

!

      SUBROUTINE U_USERSUB(...)

!

      INCLUDE ′nd.h′

      INCLUDE ′emtstor.h′

!

      REAL     X, Y, X_OLD, Y_OLD

      INTEGER  MY_NSTORF, MY_NSTORI, Z, Z_OLD

!

! Copy the pointer values to locally declared variables:

!

      MY_NSTORF = NSTORF

      MY_NSTORI = NSTORI

!

! Increment the respective pointers before continuing:

!

      NSTORF = NSTORF + 2

      NSTORI = NSTORI + 1

!

! Retrieve the variables from storage arrays (using local pointers):

!

      X_OLD = STORF(MY_NSTORF)

      Y_OLD = STORF(MY_NSTORF + 1)

      Z_OLD = STORI(MY_NSTORI)

!

! Main body of subroutine:

!

  ...

!

! Save the variables to storage arrays for use in next time step:

!

      STORF(MY_NSTORF)     = X

      STORF(MY_NSTORF + 1) = Y

      STORI(MY_NSTORI)     = Z

!

      RETURN

      END

!

 

 Listing 5-2 – Illustration of STORx Array Usage with Local Pointers

 

 

 

BEGIN to DSDYN/DSOUT Data Transfer

The BEGIN section is used to perform pre-run (or time zero) operations, such as initialization of variables, etc.   Data transfer from BEGIN to both the DSDYN or DSOUT sections occurs at the beginning of each time step.  

 

 

 Figure 5-2 - Typical Storage Array Usage by BEGIN Procedures

 

BEGIN was introduced primarily to provide Runtime Configuration support in EMTDC when components exist within modules with multiple instances.  The storage arrays used to transfer data (i.e. the RTCx arrays) are included, so as to not affect the storage operations of legacy user-components that were created using PSCAD versions previous to X4.  All master library components use both storage array types when necessary.

 

To facilitate runtime configuration support (and thereby multiple instance modules support) within user-designed components, it may be necessary to utilize the BEGIN section (and hence the RTCx storage arrays).  This is normally the case if the component requires time zero initialization.

 

 

 

EXAMPLE 5-2:

 

Consider a user-defined component that needs to store a set of two xy data points at time zero, for use later during runtime.  The data points are defined as follows:

 

 

X

Y

Point 1

0.7

3.1

Point 2

1.2

3.8

 

Table 5-2 – Set of XY Data Points for This Example

 

The storage of these data points will need to occur within the BEGIN section of the system dynamics, so as to ensure that the component is Runtime Configurable.  The user decides to write a subroutine entitled U_BGN_XYPOINTS that will be called within the BEGIN section.  Note that the text BGN was added to the procedure name – this is to help identify it as BEGIN-type.

 

!

      SUBROUTINE U_BGN_XYPOINTS(X,Y)

!

      INCLUDE ′nd.h′

      INCLUDE ′rtconfig.h′

!

      REAL X(2), Y(2)

!

! Save variables to storage array for use in runtime:

!

      RTCF(NRTCF)     = X(1)

      RTCF(NRTCF + 1) = Y(1)

      RTCF(NRTCF + 2) = X(2)

      RTCF(NRTCF + 3) = Y(2)

!

! Increment the pointers before returning to the main program

! (very important):

!

      NRTCF = NRTCF + 4

!

      RETURN

      END

!

 

 Listing 5-3 – Illustration of RTCx Array Usage within BEGIN Subroutine

 

Now that the subroutine is defined, the user must specify to PSCAD that a call to it is to be inserted in the BEGIN section.  This is accomplished by using the #BEGIN/#ENDBEGIN directives within the component definition.  See Script Directives in the PSCAD manual chapter Definition Script if you are not familiar with these.

 

#BEGIN

      CALL U_BGN_XYPOINTS($X,$Y)

#ENDBEGIN

 

 Listing 5-4 –BEGIN Subroutine Call from Component Definition

 

The $X and $Y variables represent pre-defined quantities in the component definition.  These could be, for example, component input parameters.  Note that instead of defining a subroutine, the data storage may also be coded directly in the component definition as follows:

 

#BEGIN

      RTCF(NRTCF)     = $X(1)

      RTCF(NRTCF + 1) = $Y(1)

      RTCF(NRTCF + 2) = $X(2)

      RTCF(NRTCF + 3) = $Y(2)

!

      NRTCF = NRTCF + 4

#ENDBEGIN

 

 Listing 5-5 – Illustration of RTCx Array Usage within Component Definition

 

Now that the data is being stored in BEGIN, you will need to retrieve it during runtime.  The user has written a subroutine that defines the runtime (or the dynamic modeling) operation of the component called U_DYN_XYPOINTS.  This routine includes RTCx storage retrieval, along with STORx type arrays:

 

!

      SUBROUTINE U_DYN_XYPOINTS(...)

!

      INCLUDE ′nd.h′

      INCLUDE ′emtstor.h′

      INCLUDE ′rtconfig.h′

!

      REAL     X(2), Y(2)

      INTEGER  MY_NSTORI, TEMP

      INTEGER  MY_NRTCF

!

! Copy the pointer values to locally declared variables:

!

      MY_NSTORI = NSTORI

      MY_NRTCF  = NRTCF

!

! Increment the respective pointers before continuing:

!

      NSTORI = NSTORI + 1

      NRTCF  = NRTCF  + 4  ! Number of RTCF storage elements used

!

! Retrieve the variables from storage arrays (using local pointers):

!

      TEMP = STORI(MY_NSTORI)

      X(1) = RTCF(MY_NRTCF)

      Y(1) = RTCF(MY_NRTCF + 1)

      X(2) = RTCF(MY_NRTCF + 2)

      Y(2) = RTCF(MY_NRTCF + 3)

!

! Main body of subroutine:

!

  ...

!

! Save variables to storage arrays for use in next time step

! (STORx arrays only!):

!

      STORI(MY_NSTORI) = TEMP

!

      RETURN

      END

!

 

 Listing 5-6 – Illustration of RTCx Array Usage within DSDYN/DSOUT Subroutine

 

 

Common Intrinsic Network Variables

Through intrinsic variables, the user may access electric network data, such as branch and node numbers, as well as monitor branch current and node voltage.  Some network variables, such as branch voltage may even be controlled.

NOTE:  In the following tables, BRN and SS stand for branch number and subsystem number respectively.  NN stands for node number.

Node Numbers

Node numbers may be accessed as follows:

 

Variable Name

Description

IEF(BRN,SS)

Gives the number of the mapped ‘from’ node

IET(BRN,SS)

Gives the number of the mapped ‘to’ node

 

Table 5-3 – Intrinsic Variables to Access Node Numbers

Branch Current

The current flowing in a given branch can be monitored as follows:

 

Variable Name

Description

CBR(BRN,SS)

Gives the value of current in a particular branch with the direction of positive current being from the ‘from’ node to the ‘to’ node.  

 

Table 5-4 – Intrinsic Variable to Access Branch Current

 

The voltage at a given node can be monitored as follows:

 

Variable Name

Description

VDC(NN,SS)

Gives the value of voltage at node NN in subsystem SS.

 

Table 5-5 – Intrinsic Variable to Access Node Voltage

Electric Network Interface Variables

These variables may be used for direct control of the electric network interface:

 

Variable Name

Description

EBR(BRN,SS)

Sets the value of branch voltage

CCBR(BRN,SS)

Current source representing the history current when inductors and/or capacitors are used in an interface branch

GEQ(BRN,SS)

Sets the value of the branch equivalent conductance.

CCIN(NN,SS)

An ideal current source that sets the value of current injected into the node NN from ground.

GGIN(NN,SS)

Sets a conductance value between node NN and ground

 

Table 5-6 – Intrinsic Variables for Control of an Interface to the Electric Network

NOTE: See the section entitled Interfacing to the Electric Network later in this chapter for more details.