Skip to content

Patterns

A time pattern is a named list of multipliers. The engine steps through the list as the run advances. It applies one multiplier per interval to each base value that points at the pattern. The project keeps all the patterns in one library. Everything in the model that varies through the day names a pattern to do it:

  • Demand
  • A reservoir’s head
  • A pump’s speed
  • A source’s strength
  • The price of electricity

For what a multiplier does to the solution, see the EPANET 2.2 manual.

A twenty-four hour domestic demand pattern, its multipliers and its graph

Patterns have an effect only on an extended period run. If Total duration is zero, the engine solves the network once and ignores every multiplier. A new model gets nothing from its patterns until you set the duration. See Simulation settings.

Press Operational data in the toolbar, then Patterns. Panel rows that take a pattern also carry Open patterns…. It opens the library on the matching section and keeps the asset behind it. You can build a pattern at the moment you need it, and choose it as soon as you are back.

The Pattern column in a junction’s Demands grid is the exception. It lists the demand patterns that exist, but it gives no way into the library. You must build a demand pattern before the demands that use it. See Junctions.

The patterns library with a demand pattern selected

A pattern belongs to one category. The category is not a description. It decides where you can use the pattern. Each selector offers patterns of its own category and no others. A pattern built under Demand never appears in a pump’s speed list.

Category What it multiplies Where it is chosen
Demand a base demand, on a junction or a customer point the Pattern column of a Demands grid, on either
Reservoir head a reservoir’s Head Head pattern on a reservoir
Pump speed a pump’s Initial speed Speed pattern, when Variable speed is Pattern based
Quality source strength a node’s Source strength Source pattern, in the Quality section
Energy price the cost of a pump’s energy Price pattern on a pump, or Global energy price pattern in Simulation settings

Two consequences of this rule are worth knowing before you start:

  • Global energy price pattern stays disabled and reads No patterns yet until an energy price pattern exists. If you built the pattern under the wrong heading, the setting looks broken.
  • A pattern for two different jobs must exist twice, once under each category. There is no way to share one.

For the rows themselves, see Junctions, Reservoirs, Pumps, Water quality and Energy.

A sixth heading, Uncategorized, appears only when the project holds patterns with no category at all. An INP import produces such patterns. The menu of one of these patterns offers Set as Demand, Set as Reservoir head, Set as Pump speed, Set as Quality source strength and Set as Energy price. This is how you file the pattern where it belongs. Until you do, no selector in the app offers it, and the pattern has no effect on anything.

Down the left is one section per category. Each section shows the number of patterns in it and a button to add one: Add demand pattern, Add reservoir head pattern, and so on. The button puts a new pattern straight into that section.

Each pattern has a menu with Rename, Duplicate and Delete. The app refuses a name that another pattern already uses. The field stays open and marks itself in error until you type a free name. Duplicate copies the multipliers into a new pattern in the same section. This is the quickest way to make a variant of a profile that you tuned already.

When you select a pattern, the app opens a two-column table beside a graph.

The multiplier table, with the peak hour selected

  • Timestep is read-only. It is the time from the start of the run, counted in Pattern time step intervals. With the usual one-hour step, the rows read 00:00, 01:00, 02:00 and so on.
  • Multiplier is what you type. It is a factor, not a value. 1 leaves the base value alone, and 1.7 is a peak of seventy percent above it.

Add timestep at the foot of the table adds a row. Each row has a menu with Delete, Insert row above and Insert row below. The times renumber themselves afterwards. A new row in the middle of a twenty-four hour profile moves everything under it by one interval, and leaves no gap.

A new pattern arrives with enough rows to cover the run. The count is Total duration divided by Pattern time step, and every multiplier is 1. A twenty-four hour run with a one-hour pattern step gives twenty-four rows of 1. A model whose duration is still zero gives a single row. A later change to Pattern time step re-times the rows, but it never adds or removes them. You must rewrite a profile by hand for another step.

The graph is one bar per interval, and it is the fastest check that a profile does what you meant. When you click a bar, the app selects its row in the table. When you select rows in the table, the graph shows the matching bars as selected.

A demand pattern’s graph, one bar per hour

The graph also draws what happens past the end of the table. Bars after the pattern’s own last value are the repeats that EPANET applies, in a lighter shade. For example, a twelve-hour profile on a twenty-four hour run shows twelve solid bars and twelve pale ones.

Bars past the end of the run are gray instead. The run never reaches these multipliers. They are the sign that a pattern is longer than the duration you use it for.

A reservoir head pattern is the one exception to the shape of the graph. Its vertical axis does not start at zero. As a result, a narrow band of multipliers fills the graph, and the bars do not flatten against a zero baseline.

Save stays disabled until something changes. The whole edit lands as one step in the undo history. If you press Cancel with unsaved work, the app offers Discard changes or Keep editing.

The library opens read-only in two cases: while the app plays a run back, and on Main whenever a scenario exists. Main is locked for as long as one exists. A read-only library has a single Close button, no add buttons and no editable cells.

Inside a scenario you can edit the library. The edit stays on the branch and leaves Main as it was, like every other change on a branch. If you mean to keep a pattern on Main, you build it after you delete the scenarios. See Scenario work.

The library builds a pattern. Something else must point at it. For more assets than you would want to open one at a time, the fastest route is the grid in Data tables:

  1. Set the Pattern cell on the first row.
  2. Copy the cell.
  3. Click the Pattern column header to select the whole column.
  4. Paste.

A single copied cell repeats down the whole selection. A network’s worth of customer points takes the pattern in one step and one undo.

The Pattern column of the customer points table, filled in one paste

The library refuses to delete a pattern that is in use. It says Cannot delete a pattern that is in use. Free the pattern first: change the assets that point at it to another pattern, or to none. Then the delete goes through.

Import, in the toolbar of the dialog, reads a .csv or .xlsx file and merges its patterns into the library. The file has a header row and four columns: Pattern name, Type, Interval and Multipliers. Each pattern takes one row. Its multipliers run along the row from the fourth column, one per cell. This is the shape that Export writes, so the shortest way to a correct file is to export one and edit it.

Type is the category as the library shows it: Demand, Reservoir head, Pump speed, Quality source strength or Energy price. The match ignores case. A blank or unrecognized type lands the pattern in Uncategorized, and you file it from there.

You can leave Interval blank. If you type one, it is a time in hours, 1:00 or 1. The app compares it with the project’s Pattern time step. When the two differ, the multipliers still arrive one per step, exactly as the file has them. The app never re-times them. The result card then reads Found issues while importing. Its Issues entry carries Interval value differs from project settings. Ignored. This line says that the app set the interval in the file aside.

The import matches each pattern by name against the library. The match ignores case.

  • A name the library does not hold becomes a new pattern.
  • A name it holds, with the same multipliers and category, stays as it is. The import counts it as identical.
  • A name it holds, with other multipliers, replaces the multipliers of that pattern. The pattern keeps its identity, and every asset that points at it keeps pointing. A blank type in the file does not take the category off a pattern. A type in the file gives a category to an uncategorized one.
  • A name it holds under a different category becomes a second pattern with a generated label. An import never overwrites a pattern with one of another category.

The dialog then clears the selection and shows a result card in its place. The card reads Patterns imported, then the counts, for example 3 added, 1 updated, 2 identical, 4 not modified. Only the counts that are not zero appear. The last one is the number of patterns already in the library that the import left as they were. When the file changed nothing, the card reads Nothing was imported instead. The card stays until you dismiss it or select a pattern.

The app skips rows it cannot use. The card then reads Found issues while importing. The counts gain the number of rows ignored, and an Issues entry sits under them. The entry opens to one line per problem, with the rows the problem happened on:

The result card after an import with a pattern ignored, its Issues entry open on the row at fault

Message What it means
Missing pattern name. Pattern ignored a row with no name
Duplicate pattern name. Pattern ignored a name that appears twice in the file (the app keeps the first row)
Invalid interval. Pattern ignored an interval the app cannot read as a time
Invalid multiplier. Pattern ignored a multiplier cell that is not a number
Missing multiplier. Pattern ignored an empty cell between two multipliers

When more than half of the rows are unusable, the app decides that this is not a patterns file and imports nothing. It says This does not look like a patterns file. Expected columns are Pattern name, Type, Interval and Multipliers. A file with another extension reports Only .csv and .xlsx files can be imported. A file the app cannot open reports Failed to read file.

An import changes the dialog, not the model. Nothing reaches the assets until you press Save. The whole import then lands as one step in the undo history. Cancel leaves the library as it was. A read-only library still offers Export, but Import stays disabled.

Export writes the library as Comma-Separated Values (.csv) or Microsoft Excel spreadsheet (.xlsx). The file takes the project’s name, with -Patterns on the end. It holds every pattern in the library, one row each: the name, the category, the project’s Pattern time step as the interval, and the multipliers. An uncategorized pattern goes out with a blank type. This is how a set of profiles moves between models. You export them from the model where you built them, then import the file into the next model.

Patterns are part of the model. The project file holds them with their categories, and they come back exactly as you left them. See Projects.

An INP is a lossier round trip:

  • Export writes every pattern in the library, whether anything uses it or not. The file has nowhere to record a category.
  • A run hands the engine only the patterns that something references. A pattern in the library that nothing points at has no effect on results, and it never appears in the report.
  • Import works the categories out from use. A pattern goes under the first thing that names it. A pattern used for two different jobs is imported twice, and the second copy gets a generated label. For a pattern that the file defines and never uses, the app reads the comment on the line above its first row. If that comment names a kind, the pattern goes under it. If there is no such comment, the pattern lands in Uncategorized.

See Opening an existing model and Import and export.

  • Junctions — demand categories, and the Pattern column that chooses from this library.
  • Curves — the other shared library, for relationships rather than time.
  • Simulation settings — Total duration and Pattern time step, which decide how much of a pattern the run uses.