Performance tips

NEMO is designed to provide robust performance for a wide variety of models and scenarios. However, it is certainly possible to build a NEMO model that calculates slowly. Most often, this is due to a long solve time (i.e., the solver takes a long time to find a solution), which in turn is driven by model complexity.

If your model isn't calculating as quickly as you'd like, there are several steps to consider.

1. Only save the output variables you need. Saving unnecessary variables increases disk operations and may result in a longer solve time (because additional constraints are needed to calculate the variables).

2. Don't save zeros. If you set the reportzeros argument for calculatescenario to false (the default), NEMO won't save output variable values that are equal to zero. This can substantially reduce the time and disk space needed to write scenario outputs.

3. Check restrictvars. The restrictvars argument for calculatescenario can have an important effect on performance. This option tells NEMO to make a greater effort to eliminate unnecessary variables from the model it provides to the solver. This filtering process requires a little time, but it can considerably reduce the solver's work load. In general, the trade-off is advisable for large models (you should set restrictvars to true in these cases) but may not be for very small models (set restrictvars to false in these cases).

4. Use parallel processing. NEMO can parallelize certain operations, reducing their run time by spreading the load across multiple processors. NEMO utilizes Julia's multi-threading system for parallelization, so parallel processing is activated whenever you run NEMO in a Julia session with multiple threads enabled. To start a Julia session with multiple threads, use the -t or --threads argument on the command line, or set the JULIA_NUM_THREADS operating system environment variable. If you install NEMO with the Windows installer program, the installer sets JULIA_NUM_THREADS to a reasonable default value. In general, NEMO performs best when it has 1-2 times as many threads as your computer has logical processors (however, certain models may benefit from more or fewer threads).

Note that the number of Julia threads affects parallelization in NEMO's Julia code, but it doesn't control what happens with the solver. For maximum performance with large models, it's also helpful to use a solver that supports parallelization, such as CPLEX, Gurobi, or Cbc.

5. Simplify the scenario. Substantial performance gains can be realized by reducing the number of dimensions in a scenario - for example, decreasing the number of regions, technologies, time slices, years, or nodes. You can also speed up calculations by forgoing nodal transmission modeling. Of course, this approach generally requires trade-offs: a simpler model may not respond as well to the analytic questions you are asking. The goal is to find a reasonable balance between your model's realism and its performance.

6. Relax the transmission simulation. If you're simulating transmission, there are some other performance tuning options to consider beyond reducing your model's dimensions. You can change the simulation method with the TransmissionModelingEnabled parameter or use this parameter to model transmission only in selected years. The calculatescenario function also has an argument (continuoustransmission) that determines whether NEMO uses binary or continuous variables to represent the construction of candidate transmission lines. With binary variables (continuoustransmission = false) candidate lines may only be built in their entirety, while with continuous variables (continuoustransmission = true) partial line construction is allowed. Continuous simulations are generally faster but may not be as realistic.

7. Use CapacityOfOneTechnologyUnit selectively. This parameter sets the minimum increment for endogenously determined capacity additions for a technology. When it's specified, NEMO uses integer variables to solve for capacity, which increases model solve time. If you don't define CapacityOfOneTechnologyUnit, NEMO solves for technology capacity with continuous variables. This approach assumes that any increment of new capacity is permissible (subject to limits on minimum and maximum capacity and capacity investment - see TotalAnnualMinCapacity, TotalAnnualMaxCapacity, TotalAnnualMinCapacityInvestment, and TotalAnnualMaxCapacityInvestment).

8. Try a different solver. The open-source solvers delivered with NEMO (GLPK and Cbc) may struggle with sizeable models. If you have access to one of the commercial solvers NEMO supports (currently, CPLEX, Gurobi, Mosek, and Xpress), it will usually be a better option. If you're choosing between Cbc and GLPK, test both of them to see which performs better for your scenario.

9. Consider calculating selected years rather than all years. Calculating selected years in a scenario is a quick way to get results from complex models, but the results may differ from those you would get if you calculated all years. NEMO uses several methods to reduce the differences - see the documentation on calculating selected years for details.