Note: This is documentation for version 5.4 of Source. For a different version of Source, select the relevant space by using the Spaces menu in the toolbar above

Types of functions and variables

Context variables are not available in Source (public version).

Using functions is one of several ways of adding data in a Source model. Used in conjunction with variables, they provide a robust and flexible way of data input. There are six types of variables available in Source:

  • Pattern variable - creates a dataset of repeating time-dependent values (eg. daily or monthly pattern). Value used is based on the current simulation date and time;
  • Time series variable - uses a time series data source as input. Value used is based on the current simulation date and time;
  • Piecewise linear variable - creates a lookup table that interpolates a Y value based on an X value. 
  • Bilinear variable - similar to a piecewise linear variable, but allows you to look up and interpolate between values in two dimensions;
  • Modelled variable - uses a model output, eg. the downstream flow of an inflow node; and
  • Context variable - for applying the same function in a number of locations that use modelled variables.

There are also built-in Input Sets and Custom Functions.

Pattern variables

To define a new pattern variable (as shown in Figure 1):

  • Create a new Pattern variable as described in Adding a new variable or function
  • Specify either a daily or monthly time step; and
  • Enter the amount per time period specified, eg. monthly accepts 12 values; daily accepts 366 values. You can also import a *.csv text file. 

Source evaluates the day or month for the current time step and returns the appropriate value.

Note: When using monthly pattern demand models, a discrepancy between leap and non-leap years occurs because of the difference in number of days for February. To avoid this, set up a time series demand model with a time series variable and assign a function as input. Refer to the Time Series Demand model for details.


Figure 1. Pattern variable

For example, you want to use mean monthly inflows for every time step in a monthly model simulation. In the Function Editor, define a pattern variable modelling monthly mean flows, $MonthlyFlowPattern (Figure 1). Then, in the Inflow node's feature editor, select the Function Editor and, create a function, $MonthlyInflow, that refers to the pattern variable (Figure 2). 


Figure 2. Pattern variable - example

Time series variables

To work with a time series variable:

  • Create a new time series variable as described in Adding a new variable or function;
  • In the Configuration pane, assign a time series (using the Data Sources panel) to the variable; and
  • Specify the Result Units using the drop down menu - this will be assigned depending on the time series. The function system will convert the time series value each time step from the units of the time series, to the Result Units of the time series variable.

Figure 3 shows an example of a Time series variable. Refer to Loading data for information on working with the Data Sources panel.


Figure 3. Time Series variable

Piecewise Linear variable

A bilinear variable allows you to interpolate in two dimensions, whereas a piecewise linear variable allows you to look up a value in one dimension.

To define a new piecewise linear relationship (Figure 4):

  • Create a new Piecewise Linear variable as described in Adding a new variable or function; and
  • Define your lookup and result values by entering them manually or you can import a *.csv text file.

Refer to User Interface - About piecewise linear editors for more information on constructing relations.

Figure 4. Piecewise Linear variable

Once defined, a piecewise variable can be accessed using lookup($var, x), in a similar manner to bilinear variables.

Bilinear variables

Bilinear variables (Figure 5) allow you to look up and interpolate values in two dimensions. In the top half of the screen, you name the variables; the table below allows you to define the relationship. 

To configure a new bilinear variable in the Function editor:

  • Add a bilinear variable, as described in Adding a variable or function;
  • In the relationship table, use the contextual menu to add a row or column in the table;
  • Double click in the individual cell to edit the values. Alternatively import a *.csv text file (Table 1); and
  • Re-name the X Axis, Y Axis and Result names using their respective Name fields (by default, these are called 'X',  'Y' and 'Value' respectively). This is useful to remind you what the bilinear variable defines, but is not used elsewhere in Source.
Table 1. Bilinear variable (data file format)
RowColumn (comma-separated)
12 … n
1descx
2 … nyvalue

where:

desc is a title, it is ignored during import. In exported *.csv files it will have the text 'X across Y down'

x and y are look up values

value is the result that will be returned for the corresponding x and y

In Figure 5, the X values (row headers) are volumes, the Y values (column headers) are years, and the results are the pumping costs per ML. 

Figure 5. Bilinear variable

Once defined, a bilinear variable can be accessed using lookup($var, x, y), as shown in Figure 6. In this instance, the function $PumpingCost is looking up the bilinear variable $BiLinear_Cost (defined in Figure 5). The x value used for the lookup is the modelled variable $ExtractedVolume, which is the extracted volume from a supply point; the y value used is $Now.Year, which is the year of the current time-step.

Figure 6. Accessing a bilinear variable

Timestep Variables

Timestep variables (modelled and context variables) are designed to read data from models at different Time of Evaluation phases during a timestep, and then used as part of an equation in a function. Both modelled variables and context variables can return single or multiple values by specifying different date ranges.

Modelled variables

Modelled variables point to model results and allow them to be called by functions as the model runs. To configure a new modelled variable:

  • Add a modelled variable, as described in Adding a variable or function;
  • Using the disclosure triangles, choose the appropriate recorder that you wish to be associated with the variable;
  • Depending on the recorder you choose, you can also specify the following:
    • Result Units - units of the results;  
    • The variable's Initial Value - this defines the value that the variable takes on between the start of the first time-step and the point during that time-step when the corresponding model variable acquires a defined value;
    • Date Range - the date range that the Function manager uses as a filter when obtaining data during each time-step. For example, you can choose to use the value from the current time-step or the previous time-step. You can also use values like the average of the last 100 time-steps. See Date ranges for more information; and 
    • Time of Evaluation - specifies when the variable will be evaluated. See Functions Time of Evaluation for more information.

Figure 7 shows an example of a modelled variable.

Note: Because functions can be recorded, combining functions with modelled variables allows you to create iterative functions, where a function can use the result of itself from a previous time step. See Using Restriction Curves for a worked example of this usage.


Figure 7. Modelled variable

Context variables

Context variables are defined and operate in a similar way to modelled variables. As their name suggests, they operate in the context of the function usage they are attached to. Whereas modelled variables point to an instance of a model component eg. Storage 1, context variables change what they are referring to based on where the function is used. For example, if a context variable points to Storage Downstream Flow, the function can be used by multiple storages. However, in each case the context variable will refer to that storage's Downstream flow. 

Currently, functions with context variables can't be recorded.

One application of context variables is in rainfall runoff modelling, an example is provided next.

Example

As an example, you can use a context variable when specifying a function for rainfall runoff models. Consider a geographic scenario with rainfall input as a time series. For this exercise, the Catchment surface runoff is a function of Rainfall. This function scales the rainfall (one context variable) according to a parameter (the second context variable). Table 1 shows details of the variables.

Table 1. Context variables setup, example
Context variableModel typeAssigned parameter
$RainfallRainfall Runoff ModelRainfall
$ParamFunction-basedParam

In the Rainfall Runoff Configuration Model dialog, choose Function based as the model type (refer to Working with rainfall runoff models for more information). Click on the Catchment surface runoff link to specify the input parameters. Define the context variables and function using the Function Editor, as shown in Figure 13.

Figure 13. Context variable


Date ranges

Date ranges apply to modelled variables and context variables. The default date range is a single value for the current time step. You can choose to set up variables to be a specific timestep in the past or a list of values from previous time steps or time spans. Tables 10 and 11 here define the options which are available by default. 

If none of the default options is appropriate, you can define your own date ranges using one of the options from the Date Ranges toolbar (Figure 8). To calculate a particular date in the water year using the calendar date functions, you can use $now.dayofyear+184 (to indicate the next calendar year) for example, or $now.dayofyear-181 (represents the current calendar year).

Figure 8. Date Ranges toolbar


Date ranges fall into four categories:

  • Previous year date range - static  (Figure 9) allows you to define a precise start and end date during which the model variable is considered to be valid. Enabling the Is Recurring checkbox ignores the years. In other words, the period between Start Date and End Date is valid for every year during model execution;
  • Current year date range - progressive (Figure 10);
  • Period (Figure 11) allows you to specify the date range in terms of a period of time that is relative to the current time-step. Period is commonly used with models that are not daily time step models. A period can range from six minutes to one year and is controlled via the Period drop down list. The Period must be equal to or larger than the run timestep. Sub-timestep periods are not supported and will result in a fatal error when running the scenario. When using a Period greater than the run timestep and accessing the current period, the running total for the period so far will be returned.
    The number of periods included in the range is controlled by the X Periods Ago (start) and Y Periods Ago (end) fields, where end ≥ start. A value of zero refers to the current period.
    Examples:
    • Daily period where start=0 and end=0 refers to the current day, a single value;
    • Daily period where start=1 and end=1 refers to the previous day, a single value;
    • A Weekly period where start=0 and end=2 refers to the current and previous two weeks, a set of three values; for a Daily timestep the current week entry will contain the running total for the week so far;
  • Time Step (Figure 12) allows you to specify the date range in terms of time-steps. The functionality of this date range is the same as the Period date range when the period and run timesteps are the same (e.g. Daily period and Daily run timestep).
    The number of time-steps included in the range is controlled by the X Timesteps Ago (Start) and Y Timesteps Ago (End) fields where end ≥ start. A value of zero refers to the current time-step.
    Examples:
    • If start = 0 and end = 0, this refers to the current timestep, a single value;
    • If start = 1 and end = 1, this refers to the previous timestep, a single value;
    • If start = 0 and end = 6, this refers to the current timestep and 6 previous timesteps, a set of seven values;

Also note the additional parameters:

  • The Update Frequency drop down list offers a choice of Once Per Time Step or Once Per Iteration. The latter setting is only applicable to NetLP.
  • The Return set drop down list controls the granularity of the returned result:
    • If the range represents a single value, that value is returned regardless of this setting.
    • Table 2 summarises what is returned if the range represents more than one value for example observed values.
Table 2. Date range return sets
OptionSummaryObserved valuesResult values
Simple setReturns the set of observations without modification.

[1,2,3,4,5]

[2,3,1,5,4]

[1,2,3,4,5]

[2,3,1,5,4]

Set of averagesReturns a set of the same size where each member is the average of all of the members of the observed values set.

[1,2,3,4,5]

[2,3,1,5,4]

[3,3,3,3,3]

[3,3,3,3,3]

Set of progressive averagesReturns a set of the same size where each member is the average of the current member and all preceding members of the observed values set.

[1,2,3,4,5]

[2,3,1,5,4]

[1,1.5,2,2.5,3]

[2,2.5,2,2.75,3]

Note: While the interface uses the word set to refer to the concept of returning multiple values, because the values are both ordered and can be repeated, these can be thought of as lists or arrays.

Time of Evaluation considerations

Values are queued into a date range buffer at the specified Time of Evaluation (ToE) for the variable. Values are queued at the end of the buffer and indexed from 0 (e.g. in a date range with 7 periods, start=0, end=6, index 6 will be the current value and index 0 will be the value from 6 periods prior). For date ranges which don't start from 0, the indexes are offset by the start value (e.g. in a date range with 2 periods, start=2, end=3, index 1 will be the value from 2 periods ago and index 0 will be the value from 3 periods ago).
When accessing values from a variable from a function the ToE of the function must also be considered as the value returned from a variable will be different depending on the when it is accessed. The current value (the last index in the array) is only valid on the current timestep (or period) after the variable has been evaluated. Thus, functions should only use current values in the same timestep the variable is evaluated. If the variable is used by a function in the next timestep the current value will not have been evaluated yet. In the case of a Timestep date range (or a Period date range with period equal to the run timestep) the current value will be NaN if accessed in the next timestep. Similarly, for a Period date range with period greater that the run timestep, the running total for the current period will be set to NaN at the beginning of the timestep when a new period starts (e.g. for a Weekly period and Daily run timestep the current value will be set to NaN at the beginning of the first day of the week). The required index for using the inbuilt LOOKUP function, and the results of other inbuilt functions which work with sets will similarly be affected.

Figure 9. Date Range, previous year

Figure 10. Date range, current year

Figure 11. Date Range, Period

Figure 12. Date Range, time-step

Upgrading older Source projects

The implementation of Period and Timestep date ranges was significantly changed in Source version 4.13.0. When upgrading older projects to work in new versions of Source a Scenario Option will be enabled to use the legacy implementation of data ranges. Results should thus not change between versions. New projects and scenarios created in Source version 4.13.0 and above will use the new date ranges implementation which behaves as outlined above. The legacy implementation will produce different results.
The key limitations of the legacy implementation are:

  • Current periods did not produce a running total of values. The returned value would continue to be the previous value up until the end of the period.
    • For example, using a period date range with start=0, end=0, period=Weekly, and variable's initial value of zero, with observed daily values of {1,2,3,4,5,6,7,8}, the legacy results are {0,0,0,0,0,0,28,28}, and the new results are {1,3,6,10,15,21,28,8}.
    • Due to this problem the built in Current Month and Current Calendar Year date ranges do not work as expected, instead the previous month and previous year values are returned.
  • The returned value for the period would continue to be the initial value for the variable up until the end of all periods within the buffer. A result would only be produced when all values had been queued.
    • For example, using a timestep date range with start=0, end=6, and variable's initial value of zero, with observed values of {1,2,3,4,5,6,7,8}, the sum of the variable set was previously {0,0,0,0,0,0,28,35}, and is now {1,3,6,10,15,21,28,35}.
  • Current and previous timestep and period values were the same.
    • For example start=1 and end=1, produced the same value as start=0 and end=0.
  • Using a variable in the current timestep (after it had been evaluated) gave the same value as in the next timestep (prior to the variable being evaluated). The new implementation requires the use of different date ranges for access to current and previous values. Accessing the current value in the next timestep is likely to cause a run error due to the variable having a NaN value.
  • Using a variable on the last timestep of the period would give results for the entire period as the buffer would then be filled. This required work arounds to set the ToE of variables at the end of the timestep and referencing functions use a ToE to before the variable evaluation time.
  • It was not possible to use date ranges starting from values greater than 0.
    • For example start=4 and end=6, produced the same results as start=0 and end=2. The values would be the last three evaluated values.
  • Period date ranges using a period shorter than the run timestep would use an average value for all entries in the period. The new implementation does not allow this as disaggregation of values using an average will produce unrealistic values. This now will produce an error at the start of the run.

It is recommended to change old projects to use the new date ranges implementation by changing the Use Legacy Date Ranges Scenario Option. Changing to the new implementation will in most cases require modification to the project: changing which date ranges are used by variables, and the Time of Evaluation of variables and functions modified. In some cases it will not be possible to produce the same results using the new implementation as the legacy implementation.

The legacy implementation will be removed from Source in a future version.


Custom Functions

Allows you to create your own function and then import it for use in the Function manager. Refer to /wiki/spaces/SD54/pages/53739752 and /wiki/spaces/SD54/pages/53739913. The Parameter count column refers to the number of arguments used in the function.

Figure 14. Function Editor, Custom Functions