API Reference

Public API

The functions and types below form the supported public interface of TulipaEnergyModel.jl.

TulipaEnergyModel.EnergyProblemType
EnergyProblem

Structure to hold all parts of an energy problem. It is a wrapper around various other relevant structures. It hides the complexity behind the energy problem, making the usage more friendly, although more verbose.

Fields

  • db_connection: A DuckDB connection to the input tables in the model.
  • variables: A dictionary of TulipaVariables containing the variables of the model.
  • expressions: A dictionary of TulipaExpressions containing the expressions of the model attached to tables.
  • constraints: A dictionary of TulipaConstraints containing the constraints of the model.
  • profiles: Holds the profiles per rep_period or inter_period in dictionary format. See ProfileLookup.
  • model: A JuMP.Model object representing the optimization model.
  • solved: A boolean indicating whether the model has been solved or not.
  • objective_value: The objective value of the solved problem (Float64).
  • termination_status: The termination status of the optimization model.

Constructor

  • EnergyProblem(connection): Constructs a new EnergyProblem object with the given connection.

The constraints_partitions field is computed from the representative_periods, and the other fields are initialized with default values.

See the basic example tutorial to see how these can be used.

source
TulipaEnergyModel.add_flow_variables!Method
add_flow_variables!(connection, model, variables)

Adds flow variables to the optimization model based on data from the variables. The flow variables are created using the @variable macro for each row in the :flow table.

source
TulipaEnergyModel.add_objective!Method
add_objective!(connection, model, variables, expressions, model_parameters)

Build all objective components, register them in obj_breakdown, and set the model objective to minimization of their sum.

source
TulipaEnergyModel.add_ramping_constraints!Method
add_ramping_constraints!(
    connection,
    model,
    variables,
    expressions,
    constraints,
    profiles
)

Adds the ramping constraints for producer and conversion assets where ramping = true in assets_data

source
TulipaEnergyModel.add_scenario_tail_excess_constraints!Method
add_scenario_tail_excess_constraints!(
    connection,
    model,
    variables,
    expressions,
    constraints,
)

Add the scenario tail-excess constraints for the conditional value at risk (CVaR) feature.

For each scenario row s in cons_scenario_tail_excess, this function adds the constraint xi[s] >= total_cost_per_scenario[s] - mu.

If tail_excess_slack_xi is empty, no constraints are attached.

source
TulipaEnergyModel.add_start_up_and_shut_down_variables!Method
add_start_up_and_shut_down_variables!(model, variables)

Adds 3var UC variables to the optimization model based on the :start_up and :shut_down indices. Additionally, variables are constrained to be integers based on the unit_commitment_integer property.

source
TulipaEnergyModel.add_storage_variables!Method
add_storage_variables!(connection, model, variables)

Adds storage-related variables to the optimization model, including storage levels for both within rep-period and inter-period, as well as charging state variables. The function also optionally sets binary constraints for certain charging variables based on storage methods.

source
TulipaEnergyModel.add_unit_commitment_variables!Method
add_unit_commitment_variables!(model, variables)

Adds unit commitment variables to the optimization model based on the :units_on indices. Additionally, variables are constrained to be integers based on the unit_commitment_integer property.

source
TulipaEnergyModel.attach_coefficient!Method
attach_coefficient!(cons, name, container)

Attach a coefficient named name stored in container. This checks that the container length matches the stored indices number of rows.

source
TulipaEnergyModel.attach_constraint!Method
attach_constraint!(model, cons, name, container)

Attach a constraint named name stored in container, and set model[name] = container. This checks that the container length matches the stored indices number of rows.

source
TulipaEnergyModel.attach_expression!Method
attach_expression!(cons_or_expr, name, container)
attach_expression!(model, cons_or_expr, name, container)

Attach a expression named name stored in container, and optionally set model[name] = container. This checks that the container length matches the stored indices number of rows.

source
TulipaEnergyModel.create_modelMethod
model, expressions = create_model(
    connection,
    variables,
    constraints,
    profiles;
    optimizer = HiGHS.Optimizer,
    optimizer_parameters = default_parameters(optimizer),
    model_file_name = "",
    enable_names = true
    direct_model = false,
)

Create the energy model manually. We recommend using create_model! instead.

The optimizer argument should be an MILP solver from the JuMP list of supported solvers. By default we use HiGHS.

The keyword argument optimizer_parameters should be passed as a dictionary of key => value pairs. These can be created manually, obtained using default_parameters, or read from a file using read_parameters_from_file.

parameters = Dict{String,Any}("presolve" => "on", "time_limit" => 60.0, "output_flag" => true)
solve_model(model; optimizer = HiGHS.Optimizer, optimizer_parameters = parameters)

Set enable_names = false to avoid assigning names to variables and constraints, which improves speed but reduces the readability of log messages. For more information, see JuMP.set_string_names_on_creation.

Set direct_model = true to create a JuMP direct_model using optimizer_with_attributes, which has memory improvements. For more information, see JuMP.direct_model.

source
TulipaEnergyModel.default_parametersMethod
default_parameters(Val(optimizer_name_symbol))
default_parameters(optimizer)
default_parameters(optimizer_name_symbol)
default_parameters(optimizer_name_string)

Returns the default parameters for a given JuMP optimizer. Falls back to Dict() for undefined solvers.

Arguments

There are four ways to use this function:

  • Val(optimizer_name_symbol): This uses type dispatch with the special Val type. Pass the solver name as a Symbol (e.g., Val(:HiGHS)).
  • optimizer: The JuMP optimizer type (e.g., HiGHS.Optimizer).
  • optimizer_name_symbol or optimizer_name_string: Pass the name in Symbol or String format and it will be converted to Val.

Using Val is necessary for the dispatch. All other cases will convert the argument and call the Val version, which might lead to type instability.

Examples

using HiGHS
default_parameters(HiGHS.Optimizer)

# output

Dict{String, Any} with 1 entry:
  "output_flag" => false

Another case

default_parameters(Val(:Cbc))

# output

Dict{String, Any} with 1 entry:
  "logLevel" => 0
default_parameters(:Cbc) == default_parameters("Cbc") == default_parameters(Val(:Cbc))

# output

true
source
TulipaEnergyModel.populate_with_defaults!Method
populate_with_defaults!(connection)

Overwrites all tables expected by TulipaEnergyModel appending columns that have defaults. The expected columns and their defaults are obtained from TulipaEnergyModel.schema.

This should be called when you have enough data for a TulipaEnergyModel, but doesn't want to fill out all default columns by hand.

source
TulipaEnergyModel.read_parameters_from_fileMethod
read_parameters_from_file(filepath)

Parse the parameters from a file into a dictionary. The keys and values are NOT checked to be valid parameters for any specific solvers.

The file should contain a list of lines of the following type:

key = value

The file is parsed as TOML, which is intuitive. See the example below.

Example

# Creating file
filepath, io = mktemp()
println(io,
  """
    true_or_false = true
    integer_number = 5
    real_number1 = 3.14
    big_number = 6.66E06
    small_number = 1e-8
    string = "something"
  """
)
close(io)
# Reading
read_parameters_from_file(filepath)

# output

Dict{String, Any} with 6 entries:
  "string"         => "something"
  "integer_number" => 5
  "small_number"   => 1.0e-8
  "true_or_false"  => true
  "real_number1"   => 3.14
  "big_number"     => 6.66e6
source
TulipaEnergyModel.run_rolling_horizonMethod
energy_problem = run_rolling_horizon(
    connection,
    move_forward,
    opt_window_length;
    save_rolling_solution = false,
    compute_duals = true,
    kwargs...
)

Run the scenario in the given connection as a rolling horizon and return the energy problem.

Our implementation of rolling horizon uses a moving window with size opt_window_length that is moved ahead each iteration by move_forward. The solution of the variables in the move_forward window are saved between iterations.

We implement a model with fixed size given by the opt_window_length. The EnergyProblem with this internal model is stored internally inside the returned EnergyProblem on field rolling_horizon_energy_problem.

The termination status of the returned EnergyProblem is the same as the termination status of the last solved window. In other words, it is OPTIMAL if all windows were solved optimally. Otherwise, the last solved window will be non-optimal, and the issue will be returned.

The table rolling_horizon_window stores the window information.

If save_rolling_solution is true, the tables rolling_solution_var_% will be created for each non-empty variable. These can be used for debugging purposes.

If compute_duals is true, then the duals are computed for each internal problem and the dual solutions are copied for the full problem.

The parameters associated with the profiles are stored in rolling_horizon_energy_problem.profiles, in the respective rolling_horizon_variables.

The other rolling parameters are stored in tables param_% and rolling_horizon_energy_problem.variables under the same name.

This function also accepts other keyword arguments also accepted by run_scenario.

source
TulipaEnergyModel.run_scenarioMethod
energy_problem = run_scenario(
    connection;
    output_folder,
    optimizer,
    optimizer_parameters,
    model_file_name,
    enable_names,
    log_file,
    show_log)

Run the scenario in the given connection and return the energy problem.

The optimizer and optimizer_parameters keyword arguments can be used to change the optimizer (the default is HiGHS) and its parameters. The arguments are passed to the create_model function.

Set model_file_name = "some-name.lp" to export the problem that is sent to the solver to a file for viewing (.lp or .mps). Set enable_names = false to turn off variable and constraint names (faster model creation). Set direct_model = true to create a JuMP direct model (faster & less memory). Set show_log = false to silence printing the log while running.

Specify a output_folder name to export the solution to CSV files. Specify a log_file name to export the log to a file.

source
TulipaEnergyModel.save_solution!Method
save_solution!(connection, model, variables, constraints; compute_duals = true)

Saves the primal and dual variables values, in the following way:

  • For each variable in variables, get the solution value and save it in a

column named solution in the corresponding dataset.

  • For each constraint in constraints, get the dual of each attached

constraint listed in constraint.constraint_names and save it to the dictionary constraint.duals with the key given by the name.

Notice that the duals are only computed if compute_duals is true.

source

Internal implementation details

Internal helper functions (such as names starting with _) are not part of the public API and are intentionally omitted from this page.