gtopt namespace

This file defines the Collection class, which is a central data structure for managing indexed collections of elements. It makes extensive use of move semantics for efficient memory management, particularly for container operations.

Namespaces

namespace cli
namespace detail
namespace input
namespace line_losses
namespace sddp_file
File naming patterns for per-scene cut files.

Classes

struct ActiveTask
class AdaptiveWorkPool
Default work pool using int64_t priority key with std::less semantics (smaller key → higher priority).
struct Aperture
One backward-pass opening referencing a source scenario.
struct ApertureCutResult
Result of a single aperture task (clone + update + solve + cut).
class ApertureDataCache
In-memory cache for aperture-specific schedule data.
struct ApertureEntry
struct ArrayIndexBase
template<typename Type, typename Map Map, typename FSched, typename... Uid>
struct ArrayIndexTraits
template<typename Uid Uid>
struct ArrowTraits
template<>
struct ArrowTraits<double>
template<>
struct ArrowTraits<int>
template<>
struct ArrowTraits<int16_t>
template<>
struct ArrowTraits<int8_t>
template<typename... Uids>
struct ArrowUidTraits
struct BackwardPassOutcome
Outcome of running the backward pass across all scenes.
template<typename Key = int64_t>
struct BasicTaskRequirements
Task requirements with a generic priority key.
template<typename Key = int64_t, typename KeyCompare KeyCompare = std::less<Key>>
class BasicWorkPool
Adaptive thread pool with generic priority key.
struct Battery
Represents a battery energy storage system (BESS)
class BatteryLP
Linear programming representation of a battery energy storage system.
class BendersCut
Class-based interface for Benders cut construction with work-pool support and infeasibility monitoring.
struct Block
Smallest time unit in the optimization horizon.
class BlockLP
struct Bus
Electrical busbar (node) in the power network.
class BusLP
struct Capacity
Complete capacity entity with identification and attributes.
struct CapacityObjectBase
Base class providing capacity constraint logic for LP objects.
template<typename Object Object>
struct CapacityObjectLP
A linear programming representation of an object with capacity constraints.
struct CascadeLevel
One cascade level configuration.
struct CascadeLevelMethod
Solver options for one cascade level.
struct CascadeLevelStats
Statistics collected for each cascade level after solving.
struct CascadeOptions
Cascade solver configuration: variable number of levels.
class CascadePlanningMethod
Multi-level solver with configurable LP formulations per level.
struct CascadeTransition
Transition configuration: how a cascade level receives information from the previous level.
struct ColLabelTag
Tag types for dispatching lp_label to col or row variant.
template<CopyMove Type, typename VectorType VectorType = std::vector<Type>, typename IndexType IndexType = ElementIndex<Type>>
class Collection
A container for managing typed elements with efficient lookup by name, UID, or index.
struct ConstraintDomain
Domain over which a constraint is instantiated.
struct ConstraintExpr
Complete parsed constraint expression.
class ConstraintParser
Parser for AMPL-inspired user constraint expressions.
struct ConstraintTerm
A single term in a constraint expression.
struct Converter
Couples a battery to a generator (discharge) and a demand (charge)
class ConverterLP
class CostHelper
Handles cost calculations with time discounting for optimization problems.
class CPUMonitor
struct CutLoadResult
Result of a cut load operation.
struct Demand
Represents an electrical demand (load) at a bus.
struct DemandAttrs
Technical and economic attributes shared by demand objects.
class DemandLP
struct DemandProfile
Time-varying load-shape profile for a demand element.
class DemandProfileLP
class DisjointSetUnion
Disjoint Set Union (Union-Find) with path compression and union by rank.
struct ElasticSolveResult
template<typename SystemLP_Type SystemLP_Type>
class ElementContext
Provides a context for interacting with elements within a SystemLP.
template<typename Element Element>
struct ElementIndex
struct ElementRef
Reference to a gtopt element and one of its LP attributes.
template<typename SystemContext SystemContext, typename Element Element>
struct ElementTraits
Defines default traits for element access and manipulation.
template<typename SystemContext SystemContext>
struct ElementTraits<SystemContext, BusLP>
Specialization of ElementTraits for BusLP elements.
template<typename E E>
struct EnumEntry
Name-value pair for an enumerator.
template<typename IndexType IndexType = std::size_t>
struct enumerate_adapter
struct Error
struct FeasibilityCutResult
Result structure for feasibility cut building.
class FlatHelper
Converts multi-dimensional optimization data into flat vectors for LP formulation.
struct FlatLinearProblem
Represents a linear problem in column-major flat representation.
struct Flow
Exogenous water flow at a hydraulic junction.
class FlowLP
struct FlowRight
Flow-based water right (derechos de caudal)
class FlowRightLP
struct ForwardPassOutcome
Outcome of running the forward pass across all scenes.
struct Generator
Represents a generation unit (thermal, renewable, hydro) at a bus.
struct GeneratorAttrs
Core technical and economic attributes shared by generator objects.
class GeneratorLP
struct GeneratorProfile
Time-varying capacity-factor profile for a generator.
class GeneratorProfileLP
Linear programming representation of a generator profile.
struct IndexRange
Specifies a set of index values for a time dimension.
class InputContext
struct InputTraits
Input data access traits.
template<typename T T>
class IotaRange
struct Iteration
Per-iteration control flags for the SDDP solver.
class IterationLP
LP-side wrapper for an Iteration control entry.
struct Junction
Hydraulic node in a hydro cascade network.
class JunctionLP
Linear programming formulation for power system junctions.
class LabelMaker
struct Line
Represents a transmission line (branch) connecting two buses.
class LinearInterface
class LinearParser
class LinearProblem
Main class for building and manipulating linear planning problems.
class LineLP
struct LPClassName
class LpDebugWriter
struct LPKey
struct LpMatrixOptions
Configuration options for converting to flat LP representation.
struct LPVariable
struct MainOptions
All command-line options consumed by gtopt_main().
struct ModelOptions
Power system model configuration for LP construction.
struct MonitorPoint
A single real-time sample point (CPU load, active workers, timestamp).
class MonolithicMethod
Solves each (scene, phase) LP independently using a work pool.
struct MonolithicOptions
Monolithic solver configuration parameters.
template<typename T T>
class MultiArray2D
Minimal 2D array wrapper around std::vector.
template<typename Type, typename Tuple Tuple, std::size_t Depth>
struct mvector_traits
template<typename Type, typename Tuple Tuple>
struct mvector_traits<Type, Tuple, 1U>
struct NamedStateTarget
State variable target for cross-LP transfer (using variable names).
struct Object
Base object type providing common identification functionality.
struct ObjectAttrs
Basic attributes common to all objects in the system.
template<typename Object Object>
struct ObjectId
template<typename ObjectType ObjectType>
class ObjectLP
Wrapper class that adds LP capabilities to objects.
template<typename Object Object>
struct ObjectSingleId
class ObjectUtils
Provides common utility methods for objects in the optimization framework.
template<typename Type, typename... Uid>
class OptSchedule
class OutputContext
template<typename... Ts>
struct Overload
class PamplParser
Parser for pseudo-AMPL constraint files (.pampl)
struct PamplParseResult
Result of parsing a PAMPL file or string.
struct ParseResult
struct Phase
Groups consecutive planning stages into a higher-level period.
class PhaseLP
Linear programming phase containing multiple stages.
struct PhaseStateInfo
Per-phase SDDP state: a variable, outgoing links, forward-pass cost.
struct Planning
Represents a complete power planning model.
class PlanningLP
Linear programming model for power system planning.
class PlanningMethod
Abstract interface for planning problem solvers.
struct PlanningOptions
Global configuration parameters for the optimization model.
class PlanningOptionsLP
Wrapper for PlanningOptions with default value handling.
struct ProductionFactorSegment
One segment of the piecewise-linear efficiency curve.
template<typename ProfileType ProfileType, typename ElementLPType ElementLPType>
class ProfileObjectLP
Base class for profile-based LP objects.
struct RelaxedVarInfo
struct ReserveProvision
Generator contribution to spinning-reserve zone(s)
class ReserveProvisionLP
struct ReserveZone
Regional spinning-reserve requirement zone.
class ReserveZoneLP
struct Reservoir
Water reservoir in a hydro cascade system.
struct ReservoirDischargeLimit
Volume-dependent discharge limit for a reservoir.
struct ReservoirDischargeLimitCoeffs
LP constraint coefficients for the drawdown limit.
class ReservoirDischargeLimitLP
LP wrapper for ReservoirDischargeLimit constraints.
struct ReservoirDischargeLimitSegment
One segment of the piecewise-linear drawdown limit curve.
class ReservoirLP
Linear programming representation of a water reservoir.
struct ReservoirProductionFactor
Reservoir-dependent turbine efficiency (PLP "rendimiento")
class ReservoirProductionFactorLP
LP representation of a ReservoirProductionFactor element.
struct ReservoirSeepage
Piecewise-linear seepage model between a waterway and a reservoir.
struct ReservoirSeepageCoeffs
LP constraint coefficients for volume-dependent seepage.
class ReservoirSeepageLP
LP wrapper for ReservoirSeepage systems.
struct ReservoirSeepageSegment
One segment of the piecewise-linear seepage curve.
struct ResolvedCol
struct RightBoundRule
Volume-dependent bound rule for water rights.
struct RightBoundSegment
One segment of a piecewise-linear bound function.
struct RowLabelTag
struct RowTypeStats
Per-row-type coefficient statistics.
class ScaledView
struct Scenario
One possible future realization in stochastic planning.
class ScenarioLP
struct Scene
class SceneLP
Represents a logical scene with linear programming scenario elements.
struct ScenePhaseLPStats
Label + stats for a single scene/phase LP.
template<typename Type, typename... Uid>
class Schedule
class SDDPClonePool
class SDDPCutStore
struct SDDPIterationResult
Result of a single SDDP iteration (forward + backward pass)
class SDDPMethod
Iterative SDDP solver for multi-phase power system planning.
struct SDDPOptions
Configuration options for the SDDP iterative solver.
struct SddpOptions
SDDP-specific solver configuration parameters.
class SDDPPlanningMethod
Adapter that wraps SDDPMethod behind the PlanningMethod interface.
struct SDDPStatusSnapshot
class SDDPWorkPool
Work pool specialised for the SDDP solver with tuple priority key.
struct Simulation
Complete time-structure of a planning simulation.
class SimulationLP
Linear programming representation of a power system simulation.
class SolverBackend
Abstract interface for LP/MIP solver backends.
class SolverMonitor
Background thread that samples workpool statistics and writes JSON.
struct SolverOptions
Configuration options for linear programming solvers.
class SolverRegistry
Singleton registry for dynamically loaded solver plugins.
struct SolverTestReport
Aggregated results for all tests run against one solver.
struct SolverTestResult
Result of running one named test against one solver.
class SparseCol
Represents a variable column in a linear program.
class SparseRow
Represents a constraint row in a linear program with sparse coefficients.
struct Stage
Investment period grouping consecutive time blocks.
class StageLP
A class representing a stage in a linear programming planning problem.
class StateVariable
struct StateVarLink
Describes one state-variable linkage between consecutive phases.
struct STBUids
template<typename Object Object>
class StorageLP
struct StorageOptions
Options controlling storage LP behaviour for a single add_to_lp call.
struct StoredCut
A serialisable representation of a Benders cut.
template<typename Index Index, typename T T>
class StrongIndexVector
struct STUids
struct SumElementRef
Aggregation over multiple elements of the same type.
struct System
Complete physical power system model.
class SystemContext
class SystemLP
Central coordinator for power system LP formulation.
template<typename T T = void, typename Key = int64_t, typename KeyCompare KeyCompare = std::less<Key>>
class Task
Generic task wrapper with type-erased key type.
struct TUids
struct Turbine
Hydroelectric turbine converting water flow into electrical power.
class TurbineLP
Linear programming representation of a hydroelectric turbine.
struct UidColumn
template<typename Value Value, typename... Uids>
struct UidMapTraits
template<typename... Uids>
struct UidToArrowIdx
template<>
struct UidToArrowIdx<ScenarioUid, StageUid>
template<>
struct UidToArrowIdx<ScenarioUid, StageUid, BlockUid>
template<>
struct UidToArrowIdx<StageUid>
template<>
struct UidToArrowIdx<StageUid, BlockUid>
template<typename... Uids>
struct UidToVectorIdx
template<>
struct UidToVectorIdx<ScenarioUid, StageUid>
template<>
struct UidToVectorIdx<ScenarioUid, StageUid, BlockUid>
template<>
struct UidToVectorIdx<StageUid>
template<>
struct UidToVectorIdx<StageUid, BlockUid>
struct UidTraits
Traits for UID-based data access patterns.
struct UserConstraint
Stores a user-defined linear constraint expression.
class UserConstraintLP
LP element wrapping a single user-defined constraint.
struct UserParam
struct ValidationResult
Result of semantic validation.
struct VariableScale
Scale definition for an LP variable.
class VariableScaleMap
Lookup table for variable scales built from an array of VariableScale.
struct VolumeRight
Volume-based water right (derechos de volumen)
class VolumeRightLP
LP representation of a volume-based water right.
struct Waterway
Water channel connecting two hydraulic junctions.
class WaterwayLP
struct WorkPoolConfig

Enums

enum class BoundaryCutsMode: uint8_t { noload = 0, separated = 1, combined = 2 }
How boundary (future-cost) cuts are loaded for the last phase.
enum class BoundaryCutsValuation: uint8_t { end_of_horizon = 0, present_value = 1 }
Valuation basis for boundary (future-cost) cut coefficients and RHS.
enum class CompressionCodec: uint8_t { uncompressed = 0, gzip = 1, zstd = 2, lz4 = 3, bzip2 = 4, xz = 5, snappy = 6, brotli = 7, lzo = 8 }
Compression codec for output files (Parquet / CSV).
enum class ConstraintMode: uint8_t { normal = 0, strict = 1, debug = 2 }
Controls error handling and verbosity for user constraint resolution.
enum class ConstraintScaleType: uint8_t { Power = 0, Energy, Raw }
How the LP dual of a user constraint row is scaled for output.
enum class ConstraintType: std::uint8_t { LESS_EQUAL, EQUAL, GREATER_EQUAL, RANGE }
enum class ConvergenceMode: uint8_t { gap_only = 0, gap_stationary = 1, statistical = 2 }
SDDP convergence criterion selection.
enum class CutCoeffMode: uint8_t { reduced_cost = 0, row_dual = 1 }
How Benders cut coefficients are extracted from solved subproblems.
enum class CutSharingMode: uint8_t { none = 0, expected = 1, accumulate = 2, max = 3 }
SDDP cut sharing mode across scenes in the backward pass.
enum class CutType: uint8_t { Optimality = 0, Feasibility }
Type of Benders cut: optimality (standard) or feasibility (elastic filter)
enum class DataFormat: uint8_t { parquet = 0, csv = 1 }
File format for input/output data files.
enum class ElasticFilterMode: uint8_t { single_cut = 0, multi_cut = 1, backpropagate = 2 }
How the elastic filter handles feasibility issues in the backward pass.
enum class EnergyScaleMode: uint8_t { manual = 0, auto_scale = 1 }
How the LP energy-variable scaling factor is determined for storage elements (reservoirs, batteries).
enum class ErrorCode: uint8_t { Success = 0, SolverError, InternalError, InvalidInput, FileIOError }
enum class HotStartMode: uint8_t { none = 0, keep = 1, append = 2, replace = 3 }
How the SDDP solver handles hot-start and the output cut file.
enum class KappaWarningMode: uint8_t { none = 0, warn = 1, save_lp = 2 }
Controls warnings when the LP condition number (kappa) exceeds a threshold.
enum class LineLossesMode: uint8_t { none = 0, linear = 1, piecewise = 2, bidirectional = 3, adaptive = 4, dynamic = 5 }
Selects the mathematical model for transmission line losses.
enum class LossAllocationMode: uint8_t { receiver = 0, sender = 1, split = 2 }
How transmission losses are allocated between sender and receiver buses in the nodal power balance equation.
enum class LPAlgo: uint8_t { default_algo = 0, primal = 1, dual = 2, barrier = 3, last_algo = 4 }
Enumeration of linear programming solution algorithms.
enum class LpEquilibrationMethod: uint8_t { none = 0, row_max = 1, ruiz = 2 }
LP matrix equilibration method for numerical conditioning.
enum class LpNamesLevel: uint8_t { minimal = 0, only_cols = 1, cols_and_rows = 2 }
LP variable/constraint naming level for matrix assembly.
enum class MethodType: uint8_t { monolithic = 0, sddp = 1, cascade = 2 }
Top-level solver selection: monolithic LP, SDDP, or cascade.
enum class MissingCutVarMode: uint8_t { skip_coeff = 0, skip_cut = 1 }
How to handle boundary/named cut rows that reference state variables not present in the current model.
enum class MonthType: uint8_t { january = 1, february = 2, march = 3, april = 4, may = 5, june = 6, july = 7, august = 8, september = 9, october = 10, november = 11, december = 12 }
Calendar month (1-based: january=1, december=12).
enum class ProbabilityRescaleMode: uint8_t { none = 0, build = 1, runtime = 2 }
Controls when scenario/scene probabilities are rescaled to sum 1.0.
enum class RecoveryMode: uint8_t { none = 0, cuts = 1, full = 2 }
Controls what is recovered from a previous SDDP run.
enum class SDDPPassDirection: int { forward = 0, backward = 1 }
Pass direction for the is_backward field of SDDPTaskKey. Forward (0) has higher priority than backward (1) in lexicographic order.
enum class SDDPTaskKind: int { lp = 0, non_lp = 1 }
Task kind for the is_nonlp field of SDDPTaskKey. LP solves (0) have higher priority than non-LP tasks (1).
enum class SolveMode: uint8_t { monolithic = 0, sequential = 1 }
Monolithic solver execution mode.
enum class SolverLogMode: uint8_t { nolog = 0, detailed = 1 }
Controls whether and how solver log files are written.
enum class SolverScaling: uint8_t { none = 0, automatic = 1, aggressive = 2 }
Solver-internal scaling strategy.
enum class StateVariableLookupMode: uint8_t { warm_start = 0, cross_phase = 1 }
How update_lp elements obtain reservoir/battery volume between phases.
enum class TaskPriority: uint8_t { Low = 0, Medium = 1, High = 2, Critical = 3 }
enum class TaskStatus: uint8_t { Success, Failed, Cancelled }

Typedefs

using Active = IntBoolFieldSched
using ActiveSched = Schedule<IntBool, StageUid>
using ApertureIndex = StrongIndexType<Aperture>
using ApertureSubmitFunc = std::function<std::future<ApertureCutResult>(const std::function<ApertureCutResult()>&task)>
using ApertureUid = StrongUidType<Aperture>
using ApertureValueFn = std::function<std::optional<double>(StageUid, BlockUid)>
template<typename Type>
using Array = std::vector<Type>
Array type template for consistent vector usage.
using ArrowArray = std::shared_ptr<arrow::Array>
using ArrowChunkedArray = std::shared_ptr<arrow::ChunkedArray>
using ArrowColumnResult = arrow::Result<ArrowChunkedArray>
using ArrowField = std::shared_ptr<arrow::Field>
using ArrowIndex = int64_t
using ArrowTable = std::shared_ptr<arrow::Table>
using BatteryLPId = ObjectId<class BatteryLP>
using BatteryLPSId = ObjectSingleId<class BatteryLP>
template<typename Value = Index>
using BIndexHolder = IndexHolder0<BlockUid, Value>
using block_factor_matrix_t = gtopt::MultiArray2D<std::vector<double>>
using BlockIndex = StrongIndexType<Block>
using BlockUid = StrongUidType<struct Block>
using Bool = bool
Boolean type for logical conditions.
using BoolFieldSched = FieldSched<Bool>
using BusLPId = ObjectId<class BusLP>
using BusLPSId = ObjectSingleId<class BusLP>
using ColIndex = StrongIndexType<SparseCol>
Type alias for column index.
using DemandLPId = ObjectId<DemandLP>
using DemandLPSId = ObjectSingleId<DemandLP>
template<typename Type, typename Vector = std::vector<Type>>
using FieldSched = std::variant<Type, Vector, FileSched>
template<typename Type, typename Vector2 = std::vector<std::vector<Type>>>
using FieldSched2 = FieldSched<Type, Vector2>
template<typename Type, typename Vector3 = std::vector<std::vector<std::vector<Type>>>>
using FieldSched3 = FieldSched<Type, Vector3>
using FileSched = String
template<typename key_type, typename value_type>
using flat_map = std::map<key_type, value_type>
using FlowLPSId = ObjectSingleId<class FlowLP>
Single-ID alias for referencing a FlowLP in other LP elements.
using FlowRightLPSId = ObjectSingleId<class FlowRightLP>
using GeneratorLPId = ObjectId<GeneratorLP>
using GeneratorLPSId = ObjectSingleId<GeneratorLP>
template<typename Value = Index>
using GSTBIndexHolder = tuple_map_t<std::tuple<ScenarioUid, StageUid, BlockUid>, Value>
template<typename Value = Index>
using GSTIndexHolder = tuple_map_t<std::tuple<ScenarioUid, StageUid>, Value>
using Id = std::pair<Uid, Name>
Combined identifier with both numeric ID and name.
using Index = std::int32_t
Index type for large-scale sparse matrices and arrays.
template<typename key_type, typename value_type>
using index_map_t = gtopt::flat_map<key_type, value_type>
template<typename FirstIndex, typename Value = Index>
using IndexHolder0 = gtopt::flat_map<FirstIndex, Value>
template<typename FirstIndex, typename Value = Index>
using IndexHolder1 = index_map_t<FirstIndex, Value>
template<typename FirstIndex, typename SecondIndex, typename Value = Index>
using IndexHolder2 = tuple_map_t<std::tuple<FirstIndex, SecondIndex>, Value>
template<typename FirstIndex, typename SecondIndex, typename ThirdIndex, typename Value = Index>
using IndexHolder3 = tuple_map_t<std::tuple<FirstIndex, SecondIndex>, IndexHolder0<ThirdIndex, Value>>
using IniData = std::map<std::string, std::map<std::string, std::string>>
Parsed INI sections: section name → {key → value}.
using Int = int
Integer type for counting and discrete quantities.
using IntBool = std::int32_t
Integer boolean for space-efficient storage.
using IntBoolFieldSched = FieldSched<IntBool>
using IntFieldSched = FieldSched<Int>
using IterationIndex = StrongIndexType<IterationTag>
Strongly-typed index for SDDP iterations.
using JunctionLPId = ObjectId<class JunctionLP>
using JunctionLPSId = ObjectSingleId<class JunctionLP>
using lp_collection_ptrs_t = std::array<const void*, lp_type_count_v>
Array of const void* pointers, one slot per LP element type.
using lp_element_types_t = std::tuple<BusLP, DemandLP, GeneratorLP, LineLP, GeneratorProfileLP, DemandProfileLP, BatteryLP, ConverterLP, ReserveZoneLP, ReserveProvisionLP, JunctionLP, WaterwayLP, FlowLP, ReservoirLP, ReservoirSeepageLP, ReservoirDischargeLimitLP, TurbineLP, ReservoirProductionFactorLP, FlowRightLP, VolumeRightLP, UserConstraintLP>
Ordered tuple of all LP element types.
template<typename Type, typename Tuple>
using mvector_traits_auto = mvector_traits<Type, Tuple, std::tuple_size_v<Tuple>>
using Name = std::string
Name type for entity identification.
using NameView = std::string_view
String view type for non-owning name references.
using OptActive = OptIntBoolFieldSched
using OptActiveSched = OptSchedule<IntBool, StageUid>
using OptBool = std::optional<Bool>
Optional boolean type.
using OptBoolFieldSched = std::optional<BoolFieldSched>
using OptInt = std::optional<Int>
Optional integer type.
using OptIntBool = std::optional<IntBool>
Optional integer boolean type.
using OptIntBoolFieldSched = std::optional<IntBoolFieldSched>
using OptIntFieldSched = std::optional<IntFieldSched>
using Options = PlanningOptions
Backward-compatibility alias (deprecated — use PlanningOptions)
using OptionsLP = PlanningOptionsLP
Backward-compatibility alias (deprecated — use PlanningOptionsLP)
using OptName = std::optional<Name>
Optional name type.
using OptReal = std::optional<Real>
Optional real number type.
using OptRealFieldSched = std::optional<RealFieldSched>
using OptRealFieldSched2 = std::optional<RealFieldSched2>
using OptRealFieldSched3 = std::optional<RealFieldSched3>
using OptSceneIndex = std::optional<SceneIndex>
using OptSingleId = std::optional<SingleId>
using OptStageIndex = std::optional<StageIndex>
using OptSTBRealFieldSched = OptRealFieldSched3
using OptSTBRealSched = OptSchedule<Real, ScenarioUid, StageUid, BlockUid>
using OptSTRealFieldSched = OptRealFieldSched2
using OptSTRealSched = OptSchedule<Real, ScenarioUid, StageUid>
using OptTBRealFieldSched = OptRealFieldSched2
using OptTBRealSched = OptSchedule<Real, StageUid, BlockUid>
using OptTRealFieldSched = OptRealFieldSched
using OptTRealSched = OptSchedule<Real, StageUid>
using OptUid = std::optional<Uid>
Optional unique identifier type.
using PhaseIndex = StrongIndexType<Phase>
Strongly-typed index for Phase objects in collections.
using PhaseUid = StrongUidType<Phase>
Strongly-typed unique identifier for Phase objects.
using Real = double
Real number type for physical quantities and costs.
using RealFieldSched = FieldSched<Real>
using RealFieldSched2 = FieldSched2<double>
using RealFieldSched3 = FieldSched3<double>
using ReservoirLPId = ObjectId<class ReservoirLP>
using ReservoirLPSId = ObjectSingleId<class ReservoirLP>
using RowIndex = StrongIndexType<SparseRow>
Type alias for row index.
using scenario_stage_factor_matrix_t = gtopt::MultiArray2D<double>
using ScenarioIndex = StrongIndexType<struct Scenario>
using ScenarioUid = StrongUidType<struct Scenario>
using SceneIndex = StrongIndexType<Scene>
using SceneUid = StrongUidType<Scene>
using SDDPIterationCallback = std::function<bool(const SDDPIterationResult&result)>
using SDDPTaskKey = std::tuple<int, int, int, int>
SDDP solver task priority key.
using SingleId = std::variant<Uid, Name>
using Size = std::size_t
Size type for container dimensions and indices.
using solver_backend_factory_fn = SolverBackend*(*)(const char*solver_name)
Plugin entry-point function type: creates a SolverBackend by solver name.
using solver_plugin_abi_version_fn = int(*)()
using solver_plugin_name_fn = const char*(*)()
Plugin name function type: returns the plugin name.
using solver_plugin_names_fn = const char*const *(*)()
Plugin solver-list function type: returns null-terminated array of names.
using stage_factor_matrix_t = std::vector<double>
using StageIndex = StrongIndexType<Stage>
using StageUid = StrongUidType<Stage>
template<typename Value = Index>
using STBIndexHolder = IndexHolder3<ScenarioUid, StageUid, BlockUid, Value>
using STBRealFieldSched = RealFieldSched3
using STBRealSched = Schedule<Real, ScenarioUid, StageUid, BlockUid>
template<typename Value = Index>
using STIndexHolder = IndexHolder2<ScenarioUid, StageUid, Value>
using STRealFieldSched = RealFieldSched2
using STRealSched = Schedule<Real, ScenarioUid, StageUid>
using String = std::string
String type for general textual data.
template<typename Type>
using StrongIndexType = strong::type<Index, Type, strong::formattable, strong::regular, strong::hashable, strong::arithmetic, strong::bicrementable, strong::implicitly_convertible_to<Index>>
Strong type for indices with additional type safety and operations.
template<typename Type>
using StrongUidType = strong::type<uid_t, Type, strong::formattable, strong::regular, strong::hashable, strong::arithmetic, strong::implicitly_convertible_to<uid_t>>
Strong type for unique identifiers with additional type safety.
using TaskRequirements = BasicTaskRequirements<>
using TBRealFieldSched = RealFieldSched2
using TBRealSched = Schedule<Real, StageUid, BlockUid>
template<typename Value = Index>
using TIndexHolder = IndexHolder1<StageUid, Value>
using TRealFieldSched = RealFieldSched
using TRealSched = Schedule<Real, StageUid>
template<typename key_type, typename value_type>
using tuple_map_t = gtopt::flat_map<key_type, value_type>
using TurbineLPSId = ObjectSingleId<class TurbineLP>
Single-ID alias for referencing a TurbineLP in other LP elements.
using Uid = uid_t
Unique identifier type.
using uid_t = std::int32_t
Base type for unique identifiers.
using UserParamMap = std::unordered_map<Name, UserParam>
A collection of named parameters, keyed by name for fast lookup.
using VolumeRightLPId = ObjectId<class VolumeRightLP>
using VolumeRightLPSId = ObjectSingleId<class VolumeRightLP>
using WaterwayLPId = ObjectId<class WaterwayLP>
using WaterwayLPSId = ObjectSingleId<class WaterwayLP>

Functions

auto accumulate_benders_cuts(const std::vector<SparseRow>& cuts, std::string_view name) -> SparseRow -> auto
template<std::ranges::range Range>
auto active(Range&& range) -> constexpr auto noexcept
template<std::ranges::range Range, typename Pred>
auto all_of(Range&& range, Pred&& pred) -> constexpr bool noexcept(…)
Checks if all elements in range satisfy predicate.
auto annual_discount_factor(double annual_discount_rate, double time_hours) -> constexpr double noexcept
auto apply_cli_options(Planning& planning, const MainOptions& opts) -> void
Apply command-line options from a MainOptions struct to a Planning object.
auto apply_cli_options(Planning& planning, const std::optional<bool>& use_single_bus, const std::optional<bool>& use_kirchhoff, const std::optional<LpNamesLevel>& lp_names_level, const std::optional<std::string>& input_directory, const std::optional<std::string>& input_format, const std::optional<std::string>& output_directory, const std::optional<std::string>& output_format, const std::optional<std::string>& output_compression, const std::optional<std::string>& cut_directory = {}, const std::optional<std::string>& log_directory = {}, const std::optional<int>& sddp_max_iterations = {}, const std::optional<double>& sddp_convergence_tol = {}, const std::optional<double>& sddp_elastic_penalty = {}, const std::optional<std::string>& sddp_elastic_mode = {}, const std::optional<std::string>& sddp_cut_coeff_mode = {}, const std::optional<int>& sddp_num_apertures = {}, const std::optional<bool>& lp_debug = {}, const std::optional<std::string>& lp_compression = {}, const std::optional<double>& lp_coeff_ratio_threshold = {}) -> void
Apply command-line options to a Planning object.
template<char sep = '_'>
auto as_label() -> constexpr auto noexcept
Creates an empty label string.
template<char sep = '_', typename... Args>
auto as_label(Args && ... args) -> std::string noexcept(…)
Creates a concatenated label from multiple arguments.
template<char sep = '_'>
auto as_label_into(std::string& result) -> constexpr void noexcept
Clears and writes a label into an existing string buffer.
template<char sep = '_', typename... Args>
auto as_label_into(std::string& result, Args && ... args) -> void noexcept(…)
Writes a concatenated label into an existing string buffer.
template<typename... Args>
auto as_string(const std::tuple<Args...>& t) -> std::string
auto average_benders_cut(const std::vector<SparseRow>& cuts, std::string_view name) -> SparseRow -> auto
Compute an average cut from a collection of cuts (for Expected sharing)
auto build_benders_cut(ColIndex alpha_col, std::span<const StateVarLink> links, std::span<const double> reduced_costs, double objective_value, std::string_view name, double scale_alpha = 1.0, double cut_coeff_eps = 0.0) -> SparseRow -> auto
auto build_benders_cut_from_row_duals(ColIndex alpha_col, std::span<const StateVarLink> links, std::span<const double> row_duals, double objective_value, std::string_view name, double scale_alpha = 1.0, double cut_coeff_eps = 0.0) -> SparseRow -> auto
auto build_effective_apertures(std::span<const Aperture> aperture_defs, std::span<const Uid> phase_apertures) -> std::vector< ApertureEntry > -> auto
auto build_feasibility_cut(const LinearInterface& li, ColIndex alpha_col, std::span<const StateVarLink> links, double penalty, const SolverOptions& opts, std::string_view name, double scale_alpha = 1.0) -> std::optional< FeasibilityCutResult > -> auto
auto build_multi_cuts(const ElasticSolveResult& elastic, std::span<const StateVarLink> links, std::string_view name_prefix, double slack_tol = 1e-6) -> std::vector< SparseRow > -> auto
auto build_phase_uid_map(const PlanningLP& planning_lp) -> flat_map< PhaseUid, PhaseIndex > -> auto
auto build_scene_uid_map(const PlanningLP& planning_lp) -> flat_map< SceneUid, SceneIndex > -> auto
auto build_synthetic_apertures(std::span<const ScenarioLP> all_scenarios, int n_apertures) -> Array< Aperture > -> auto
auto build_table_path(std::string_view input_dir, std::string_view cname, std::string_view fname) -> std::filesystem::path
Build the filesystem path for an input table.
auto cast_to_double_array(const std::shared_ptr<arrow::Array>& chunk) -> std::shared_ptr< arrow::DoubleArray > -> auto
Cast an Arrow array chunk to DoubleArray, handling float32 widening.
auto cast_to_int32_array(const std::shared_ptr<arrow::Array>& chunk) -> std::shared_ptr< arrow::Int32Array > -> auto
auto check_all_solvers(bool verbose = false) -> int
Run the test suite against every solver known to SolverRegistry.
auto classify_error_exit_code(std::string_view error) -> int noexcept
Classify an error string into an exit code.
auto col_scale_cost(double scale) -> constexpr auto noexcept
auto col_scale_sol(double scale) -> constexpr auto noexcept
auto collect_sum_cols(const SystemContext& sc, const ScenarioLP& scenario, const StageLP& stage, const BlockLP& block, const SumElementRef& sum_ref, double base_coeff, SparseRow& row, const LinearProblem& lp) -> void
Collect (coefficient, ColIndex) pairs for a SumElementRef.
auto compute_convergence_gap(double upper_bound, double lower_bound) -> double noexcept
auto compute_scene_weights(std::span<const SceneLP> scenes, std::span<const uint8_t> scene_feasible, ProbabilityRescaleMode rescale_mode = ProbabilityRescaleMode::runtime) -> std::vector<double> noexcept
template<typename Collections>
auto count_all_elements(Collections&& collections) -> constexpr auto
Counts the total number of active elements across all collections.
auto csv_read_table(const std::filesystem::path& fpath) -> std::expected< ArrowTable, std::string > -> auto
Read an Arrow table from a CSV file.
auto detect_islands_and_fix_references(Array<Bus>& buses, const Array<Line>& lines, const PlanningOptionsLP& options) -> std::size_t -> auto
Detect bus islands and assign a reference bus per island.
auto elastic_filter_solve(const LinearInterface& li, std::span<const StateVarLink> links, double penalty, const SolverOptions& opts, std::span<const double> forward_col_sol = {}, std::span<const double> forward_row_dual = {}) -> std::optional< ElasticSolveResult > -> auto
template<typename Map, typename BHolder>
auto emplace_bholder(const ScenarioLP& scenario, const StageLP& stage, Map& map, BHolder&& holder, bool empty_insert = false) -> constexpr auto
template<typename Map, typename Value = Map::value_type>
auto emplace_value(const ScenarioLP& scenario, const StageLP& stage, Map& map, Value&& value) -> constexpr auto
auto enum_entries(BoundaryCutsMode) -> constexpr auto noexcept
auto enum_entries(BoundaryCutsValuation) -> constexpr auto noexcept
auto enum_entries(CompressionCodec) -> constexpr auto noexcept
auto enum_entries(ConstraintMode) -> constexpr auto noexcept
auto enum_entries(ConstraintScaleType) -> constexpr auto noexcept
auto enum_entries(ConvergenceMode) -> constexpr auto noexcept
auto enum_entries(CutCoeffMode) -> constexpr auto noexcept
auto enum_entries(CutSharingMode) -> constexpr auto noexcept
auto enum_entries(CutType) -> constexpr auto noexcept
auto enum_entries(DataFormat) -> constexpr auto noexcept
auto enum_entries(ElasticFilterMode) -> constexpr auto noexcept
auto enum_entries(EnergyScaleMode) -> constexpr auto noexcept
auto enum_entries(HotStartMode) -> constexpr auto noexcept
auto enum_entries(KappaWarningMode) -> constexpr auto noexcept
auto enum_entries(LineLossesMode) -> constexpr auto noexcept
auto enum_entries(LossAllocationMode) -> constexpr auto noexcept
auto enum_entries(LPAlgo) -> constexpr auto noexcept
ADL customization point for NamedEnum concept.
auto enum_entries(LpEquilibrationMethod) -> constexpr auto noexcept
auto enum_entries(LpNamesLevel) -> constexpr auto noexcept
auto enum_entries(MethodType) -> constexpr auto noexcept
auto enum_entries(MissingCutVarMode) -> constexpr auto noexcept
auto enum_entries(MonthType) -> constexpr auto noexcept
auto enum_entries(ProbabilityRescaleMode) -> constexpr auto noexcept
auto enum_entries(RecoveryMode) -> constexpr auto noexcept
auto enum_entries(SolveMode) -> constexpr auto noexcept
auto enum_entries(SolverLogMode) -> constexpr auto noexcept
ADL customization point for NamedEnum concept.
auto enum_entries(SolverScaling) -> constexpr auto noexcept
ADL customization point for NamedEnum concept.
auto enum_entries(StateVariableLookupMode) -> constexpr auto noexcept
template<typename E, std::size_t N>
auto enum_from_name(std::span<const EnumEntry<E>, N> entries, std::string_view name) noexcept -> std::optional< E > -> constexpr auto
Look up an enumerator by its canonical name (span overload).
template<NamedEnum E>
auto enum_from_name(std::string_view name) noexcept -> std::optional< E > -> constexpr auto
Look up a NamedEnum value by name (ADL-based).
template<NamedEnum E>
auto enum_name(E value) noexcept -> std::string_view -> constexpr auto
Return the canonical name of a NamedEnum value (ADL-based).
template<typename E, std::size_t N>
auto enum_name(std::span<const EnumEntry<E>, N> entries, E value) noexcept -> std::string_view -> constexpr auto
Return the canonical name of an enumerator (span overload).
template<typename IndexType = std::size_t, std::ranges::range R, std::ranges::range... Rs>
auto enumerate(R&& range, Rs && ... ranges) -> constexpr auto noexcept(…)
template<typename IndexType = size_t, typename Range>
auto enumerate_active(const Range& range) -> constexpr auto noexcept
template<typename IndexType = size_t, std::ranges::range Range, typename Op>
auto enumerate_if(Range&& range, Op&& op) -> constexpr auto noexcept(…)
auto evaluate_bound_rule(const RightBoundRule& rule, Real volume) noexcept -> Real -> auto
Evaluate the piecewise-linear bound function.
auto evaluate_production_factor(const std::vector<ProductionFactorSegment>& segments, Real volume) noexcept -> Real -> auto
Evaluate the piecewise-linear concave efficiency function.
auto evaluate_seepage(const std::vector<ReservoirSeepageSegment>& segments, Real volume) noexcept -> Real -> auto
Evaluate the piecewise-linear seepage function.
auto filter_cut_coefficients(SparseRow& row, ColIndex alpha_col, double eps) -> void
auto find_active_bound_segment(const std::vector<RightBoundSegment>& segments, Real volume) noexcept -> const RightBoundSegment * -> auto
Find the active segment for a given reservoir volume.
auto find_active_rdl_segment(const std::vector<ReservoirDischargeLimitSegment>& segments, Real volume) noexcept -> const ReservoirDischargeLimitSegment * -> auto
Find the active segment for a given reservoir volume.
auto find_active_segment(const std::vector<ReservoirSeepageSegment>& segments, Real volume) noexcept -> const ReservoirSeepageSegment * -> auto
Find the active segment for a given reservoir volume.
auto find_config_file() -> std::filesystem::path
Find the .gtopt.conf file following the standard search order.
template<typename Element, typename SystemContext SystemContext, template<typename> class Id>
auto get_element(SystemContext& sc, const Id<Element>& id) -> constexpr auto&&
Free function to get a reference to an element by its ID.
template<typename Element, typename SystemContext SystemContext, template<typename> class Id>
auto get_element_index(SystemContext& sc, const Id<Element>& id) -> constexpr auto
Free function to get the index of an element by its ID.
template<typename Element, typename SystemContext SystemContext>
auto get_elements(SystemContext& sc) -> constexpr auto&& noexcept
Free function to get a container of all elements of a specific type.
template<typename Obj>
auto get_name(const Obj& obj) -> constexpr auto
template<>
auto get_name<Id>(const Id& obj) -> constexpr auto
template<typename T>
auto get_opt(const po::variables_map& vm, const std::string& name) -> std::optional<T>
Extract an optional value from a variables_map.
template<typename T, typename K = T::key_type>
auto get_optiter(const T& map, K&& key) -> constexpr auto noexcept
Finds key in map and returns optional iterator.
template<typename T, typename K>
auto get_optvalue(const T& map, K&& key) -> constexpr auto
template<typename T, typename K>
auto get_optvalue_optkey(const T& map, const std::optional<K>& key) -> constexpr auto
template<typename Obj>
auto get_uid(const Obj& obj) -> Uid -> constexpr auto
template<>
auto get_uid<Id>(const Id& obj) -> Uid -> constexpr auto
auto GetColumn(const ArrowTable& table, std::string_view name) -> ArrowColumnResult -> auto
Get column by name with explicit error checking.
auto gtopt_main(const MainOptions& raw_opts) -> std::expected<int, std::string>
Run the gtopt power-system optimizer.
template<typename Obj>
auto id(const Obj& obj) noexcept -> Id -> constexpr auto
Creates an Id from an object's attributes.
auto in_lp_debug_range(int scene_uid, int phase_uid, OptInt scene_min, OptInt scene_max, OptInt phase_min, OptInt phase_max) -> constexpr bool noexcept
template<typename IndexType, typename A, typename B>
auto iota_range(A first, B last) -> IotaRange< IndexType > -> constexpr auto
template<typename T>
auto iota_range(T first, T last) -> IotaRange< T > -> constexpr auto
Create an IotaRange [first, last) with deduced type.
auto is_compatible_double_type(arrow::Type::type type_id) -> bool -> constexpr auto
Check if an Arrow type is a compatible floating-point type that can be cast to double.
auto is_compatible_int32_type(arrow::Type::type type_id) -> bool -> constexpr auto
Check if an Arrow type is a compatible integer type that can be cast to int32.
auto load_boundary_cuts_csv(PlanningLP& planning_lp, const std::string& filepath, const SDDPOptions& options, const LabelMaker& label_maker, StrongIndexVector<SceneIndex, StrongIndexVector<PhaseIndex, PhaseStateInfo>>& scene_phase_states) -> std::expected< CutLoadResult, Error > -> auto
auto load_cuts_csv(PlanningLP& planning_lp, const std::string& filepath, const LabelMaker& label_maker) -> std::expected< CutLoadResult, Error > -> auto
auto load_gtopt_config() -> MainOptions
Load a MainOptions from the [gtopt] section of .gtopt.conf.
auto load_named_cuts_csv(PlanningLP& planning_lp, const std::string& filepath, const SDDPOptions& options, const LabelMaker& label_maker, StrongIndexVector<SceneIndex, StrongIndexVector<PhaseIndex, PhaseStateInfo>>& scene_phase_states) -> std::expected< CutLoadResult, Error > -> auto
auto load_scene_cuts_from_directory(PlanningLP& planning_lp, const std::string& directory, const LabelMaker& label_maker) -> std::expected< CutLoadResult, Error > -> auto
auto load_state_csv(PlanningLP& planning_lp, const std::string& filepath) -> std::expected< void, Error > -> auto
auto log_diagnostic_lines(std::string_view level, std::string_view header, std::string_view diag) -> void
Log a multi-line diagnostic string line-by-line via spdlog.
auto log_lp_stats_summary(const std::vector<ScenePhaseLPStats>& entries, double ratio_threshold = 1e7) -> void
Log a summary of LP coefficient statistics.
template<typename Type, typename Map, typename FieldSched, typename... Uid>
auto make_array_index(const SystemContext& system_context, std::string_view class_name, Map& array_table_map, const FieldSched& sched, const Id& id) -> constexpr auto
auto make_lp_matrix_options(const std::optional<LpNamesLevel>& lp_names_level, const std::optional<double>& matrix_eps, bool compute_stats = false, const std::optional<std::string>& lp_solver = {}, std::optional<LpEquilibrationMethod> equilibration_method = {}) -> LpMatrixOptions
Build LpMatrixOptions from command-line parameters.
auto make_options_description() -> po::options_description
Create the command-line options description for the gtopt application.
auto make_planning_method(const PlanningOptionsLP& options, size_t num_phases = 0) -> std::unique_ptr<PlanningMethod>
Create a solver instance based on options.
auto make_sddp_task_key(IterationIndex iteration, SDDPPassDirection direction, PhaseIndex phase, SDDPTaskKind kind) noexcept -> SDDPTaskKey -> constexpr auto
Build an SDDPTaskKey from strongly-typed SDDP parameters.
auto make_sddp_work_pool(double cpu_factor = 1.25) -> std::unique_ptr<SDDPWorkPool>
Create and start an SDDPWorkPool configured for the SDDP solver.
auto make_solver_work_pool(double cpu_factor = 1.25) -> std::unique_ptr<AdaptiveWorkPool>
Create and start an AdaptiveWorkPool configured for solver use.
template<typename Map, typename Iterator>
auto map_insert_sorted_unique(Map& map, Iterator first, Iterator last) -> void
Insert from a pre-sorted, deduplicated range [first, last) using the most efficient API for each backend.
template<typename Map, typename Size>
auto map_reserve(Map& map, Size n) -> void
Reserve capacity in a flat_map for n elements.
template<typename T>
auto merge(std::vector<T>& dest, std::vector<T>&& src) -> constexpr bool noexcept(…)
Efficiently merges two vectors using move semantics.
template<typename T>
auto merge(std::vector<T>& dest, std::vector<T>& src) -> constexpr bool noexcept(…)
auto merge_config_defaults(MainOptions& opts, const MainOptions& defaults) -> void
Merge config-file defaults into a MainOptions struct.
template<typename OptA, typename OptB>
auto merge_opt(OptA& a, OptB&& b) -> constexpr auto& noexcept(…)
Merges two optionals, keeping value if source has value.
auto parquet_read_table(const std::filesystem::path& fpath) -> std::expected< ArrowTable, std::string > -> auto
Read an Arrow table from a Parquet file.
auto parse_cut_sharing_mode(std::string_view name) -> CutSharingMode
auto parse_elastic_filter_mode(std::string_view name) -> ElasticFilterMode
auto parse_ini_file(const std::filesystem::path& path) -> IniData
Parse a simple INI file.
auto parse_lp_algorithm(const std::string& s) -> int
Parse an LP algorithm value from a string (name or integer).
auto parse_lp_names_level(const std::string& s) -> LpNamesLevel
Parse an LP names level from a string (name or integer).
auto parse_main_options(const po::variables_map& vm, std::vector<std::string> system_files) -> MainOptions
Build a MainOptions struct from a parsed CLI variables_map.
auto probe_parquet_codec(std::string_view requested) -> std::string
auto propagate_trial_values(std::span<StateVarLink> links, std::span<const double> source_solution, LinearInterface& target_li) -> void noexcept
auto propagate_trial_values_row_dual(std::span<StateVarLink> links, std::span<const double> source_solution, LinearInterface& target_li) -> void noexcept
template<typename Element, typename SystemContext SystemContext, typename E>
auto push_back(SystemContext& sc, E&& element) -> auto
Free function to add a new element to the system.
auto relax_fixed_state_variable(LinearInterface& li, const StateVarLink& link, PhaseIndex phase, double penalty) -> RelaxedVarInfo
auto rescale_benders_cut(SparseRow& row, ColIndex alpha_col, double cut_coeff_max) -> bool
auto resolve_planning_args(MainOptions opts) -> std::expected<MainOptions, std::string>
Resolve planning file arguments and directory context.
auto resolve_single_col(const SystemContext& sc, const ScenarioLP& scenario, const StageLP& stage, const BlockLP& block, const ElementRef& ref, const LinearProblem& lp) -> std::optional<ResolvedCol>
Try to look up the LP ColIndex for one element reference.
auto resolve_single_param(const SystemContext& sc, const ScenarioLP& scenario, const StageLP& stage, const BlockLP& block, const ElementRef& ref) -> std::optional<double>
Try to look up a data parameter value for one element reference.
auto run_check_json_info(const std::vector<std::string>& json_files, int timeout_seconds = 30) -> std::string
Run gtopt_check_json --info on one or more JSON files and return the captured output.
auto run_check_lp_diagnostic(const std::string& lp_file, int timeout_seconds = 10, const SolverOptions& solver_opts = {}) -> std::string
Run gtopt_check_lp on an LP file and return the diagnostic output.
auto run_solver_tests(std::string_view solver_name, bool verbose = false) -> SolverTestReport
Run the full LinearInterface test suite against solver_name.
auto save_cuts_csv(std::span<const StoredCut> cuts, const PlanningLP& planning_lp, const std::string& filepath, bool append_mode = false) -> std::expected< void, Error > -> auto
auto save_scene_cuts_csv(std::span<const StoredCut> cuts, SceneIndex scene, int scene_uid_val, const PlanningLP& planning_lp, const std::string& directory) -> std::expected< void, Error > -> auto
auto save_state_csv(const PlanningLP& planning_lp, const std::string& filepath, IterationIndex iteration) -> std::expected< void, Error > -> auto
auto select_rdl_coeffs(const std::vector<ReservoirDischargeLimitSegment>& segments, Real volume) noexcept -> ReservoirDischargeLimitCoeffs -> auto
Select the active segment and return LP coefficients.
auto select_seepage_coeffs(const std::vector<ReservoirSeepageSegment>& segments, Real volume) noexcept -> ReservoirSeepageCoeffs -> auto
Select the active seepage segment and return LP coefficients.
auto share_cuts_for_phase(PhaseIndex phase, const StrongIndexVector<SceneIndex, std::vector<SparseRow>>& scene_cuts, CutSharingMode mode, PlanningLP& planning, std::string_view label_prefix = {}) -> void
auto solve_apertures_for_phase(SceneIndex scene, PhaseIndex phase, const PhaseStateInfo& src_state, const ScenarioLP& base_scenario, std::span<const ScenarioLP> all_scenarios, std::span<const Aperture> aperture_defs, std::span<const Uid> phase_apertures, int total_cuts, SystemLP& sys, const PhaseLP& phase_lp, const SolverOptions& opts, const LabelMaker& label_maker, const std::string& log_directory, SceneUid scene_uid, PhaseUid phase_uid, const ApertureSubmitFunc& submit_fn, double aperture_timeout = 0.0, bool save_aperture_lp = false, const ApertureDataCache& aperture_cache = {}, std::span<const double> forward_col_sol = {}, std::span<const double> forward_row_dual = {}, LinearInterface* pooled_clone = nullptr, IterationIndex iteration = {}, CutCoeffMode cut_coeff_mode = CutCoeffMode::reduced_cost, double scale_alpha = 1.0, double cut_coeff_eps = 0.0, double cut_coeff_max = 0.0) -> std::optional< SparseRow > -> auto
auto strip_cr(std::string& s) -> void noexcept
Strip trailing carriage-return left by std::getline on DOS text files.
template<std::ranges::range Range, typename Transform = decltype([](const auto& x) { return x; }), typename RRef = decltype(*std::ranges::begin(std::declval<Range>()))>
auto to_vector(Range&& range, Transform&& transform = {}) -> auto
Converts range to vector, optionally transforming elements.
auto try_read_table(const std::filesystem::path& fpath, std::string_view format) -> std::expected< ArrowTable, std::string > -> auto
Try to read a table, preferring format and falling back to the other format on failure.
auto validate_planning(Planning& planning) -> ValidationResult
Validate a Planning object for semantic correctness.
template<typename Collections, typename Op, typename... Args>
auto visit_elements(Collections&& collections, Op op, Args && ... args) -> constexpr auto
auto warn_deprecated_cli(const std::optional<bool>& opt, std::string_view cli_flag, std::string_view set_path) -> void
Specialisation for bool (prints true/false instead of 1/0).
auto warn_deprecated_cli(const std::optional<std::string>& opt, std::string_view cli_flag, std::string_view set_path) -> void
Overload for string options — no conversion needed.
template<typename T>
auto warn_deprecated_cli(const std::optional<T>& opt, std::string_view cli_flag, std::string_view set_path) -> void
Emit a deprecation warning for a CLI option replaceable by –set.
auto weighted_average_benders_cut(const std::vector<SparseRow>& cuts, const std::vector<double>& weights, std::string_view name) -> SparseRow -> auto
auto write_sddp_api_status(const std::string& filepath, const std::vector<SDDPIterationResult>& results, double elapsed_seconds, const SDDPStatusSnapshot& snapshot, const SolverMonitor& monitor) -> void

Variables

constexpr auto active_fnc
Predicate that checks if element has is_active() member returning true.
constexpr auto boundary_cuts_mode_entries
constexpr auto boundary_cuts_valuation_entries
constexpr ColLabelTag col_label_tag
constexpr auto compression_codec_entries
constexpr auto constraint_mode_entries
constexpr auto constraint_scale_type_entries
constexpr auto convergence_mode_entries
constexpr auto cut_coeff_mode_entries
constexpr auto cut_sharing_mode_entries
constexpr auto cut_type_entries
constexpr auto data_format_entries
constexpr double days_per_year
Days in a standard year (non-leap)
constexpr double DblMax
Maximum representable double value used for unbounded variable bounds.
constexpr auto elastic_filter_mode_entries
Includes "cut" as a backward-compatible alias for "single_cut".
constexpr auto energy_scale_mode_entries
constexpr IntBool False
False value for integer boolean.
constexpr auto has_value_fnc
Predicate that checks if element exists (not nullopt)
constexpr auto hot_start_mode_entries
constexpr double hours_per_day
Hours in a standard day.
constexpr double hours_per_year
Hours in a standard year.
constexpr auto is_true_fnc
constexpr int k_solver_abi_version
ABI version for the SolverBackend plugin interface.
constexpr auto kappa_warning_mode_entries
constexpr int kDiagMaxLines
constexpr int kDiagTailLines
Number of trailing lines to keep when truncating diagnostic output.
constexpr int kZstdCompressionLevel
constexpr auto line_losses_mode_entries
constexpr auto log_mode_entries
constexpr auto loss_allocation_mode_entries
constexpr auto lp_algo_entries
Compile-time table mapping each LPAlgo enumerator to its name.
constexpr auto lp_equilibration_method_entries
constexpr auto lp_names_level_entries
constexpr std::size_t lp_type_count_v
Total number of LP element types.
template<typename T>
constexpr std::size_t lp_type_index_v
Compile-time index of LP element type T in lp_element_types_t.
constexpr auto method_type_entries
constexpr auto missing_cut_var_mode_entries
constexpr auto month_type_entries
constexpr auto probability_rescale_mode_entries
constexpr auto recovery_mode_entries
constexpr RowLabelTag row_label_tag
constexpr auto solve_mode_entries
constexpr auto solver_scaling_entries
constexpr auto state_variable_lookup_mode_entries
constexpr IntBool True
True value for integer boolean.
constexpr auto true_fnc
Predicate that always returns true.
constexpr Index unknown_index
constexpr Uid unknown_uid

Compression utility functions (detail — exposed for testing)

auto gzip_lp_file_inline(const std::string& src_path) -> std::string
Inline gzip compression via zlib. Returns .gz path or empty on failure.
auto zstd_lp_file_inline(const std::string& src_path) -> std::string
Inline zstd compression via libzstd. Returns .zst path or empty on failure.
auto compress_lp_file(const std::string& src_path, const std::string& lp_compression = {}) -> std::string

Enum documentation

enum class gtopt::BoundaryCutsMode: uint8_t

How boundary (future-cost) cuts are loaded for the last phase.

  • noload: Do not load boundary cuts even if a file is given.
  • separated: Load cuts per scene (scene UID matching; default).
  • combined: Broadcast all cuts into all scenes.
Enumerators
noload

Skip loading boundary cuts.

separated

Per-scene cut assignment (default)

combined

Broadcast all cuts to all scenes.

enum class gtopt::BoundaryCutsValuation: uint8_t

Valuation basis for boundary (future-cost) cut coefficients and RHS.

Determines whether the effective discount factor of the last stage (combining the annual discount rate and the stage discount_factor) is applied when loading boundary cuts into the LP.

  • end_of_horizon: Cuts are valued at the end of the last stage. No discount factor is applied (default).
  • present_value: Cuts are expressed in present-value terms. The effective discount factor of the last stage is applied to the RHS and coefficients so that the future cost is discounted back to the planning horizon's reference time.
Enumerators
end_of_horizon

No discounting; cuts valued at last stage (default)

present_value

Apply last-stage effective discount factor.

enum class gtopt::CompressionCodec: uint8_t

Compression codec for output files (Parquet / CSV).

Enumerators
uncompressed

No compression.

gzip

gzip compression

zstd

Zstandard compression (default)

lz4

LZ4 compression.

bzip2

bzip2 compression

xz

xz/LZMA compression

snappy

Snappy compression (Arrow/Parquet)

brotli

Brotli compression (Arrow/Parquet)

lzo

LZO compression (Arrow/Parquet)

enum class gtopt::ConstraintMode: uint8_t

Controls error handling and verbosity for user constraint resolution.

During LP construction, user constraint expressions reference LP columns (variables), data parameters, and named user parameters. When a reference cannot be resolved (unknown element, attribute, or parameter name), this option controls whether the solver logs a warning and skips the term or raises a fatal error.

  • normal: Log warnings for unresolved references and skip the affected terms. Suitable for development and exploratory modeling.
  • strict: Treat any unresolved reference as a fatal error (default). Ensures no constraint terms are silently dropped.
  • debug: Like strict, but additionally logs detailed info about every resolved variable, parameter, and constraint row added to the LP. Useful for verifying constraint assembly.
Enumerators
normal

Warn and skip unresolved references.

strict

Fail on any unresolved reference (default)

debug

Strict + verbose logging of every resolved term.

enum class gtopt::ConstraintScaleType: uint8_t

How the LP dual of a user constraint row is scaled for output.

The LP objective accumulates cost as prob × discount × duration / scale_obj per unit. The LP dual of a row therefore carries a factor that must be inverted to recover the physical shadow price. The ConstraintScaleType determines which factors are removed:

EnumAccepted stringsInverse scale
Power"power" (default)see below
Energy"energy"see below
Raw"raw", "unitless"see below

Inverse scale formulas:

  • Power/Energy: scale_obj / (prob × discount × Δt)
  • Raw: scale_obj / discount
  • Power — constraint on an instantaneous-power (MW) variable such as generator output, load, or line flow. Dual unit: $/MW.
  • Energy — constraint on an energy (MWh) variable such as battery SoC. Dual unit: $/MWh. Uses the same block_cost_factors scaling as Power.
  • Raw / Unitless — constraint has no physical unit (e.g. a dimensionless coefficient matrix). The dual is scaled back only by the stage discount factor; probability and block duration are NOT removed. Dual unit: scale_obj / discount.
Enumerators
Power

Default — power (MW) constraint.

Energy

Energy (MWh) constraint.

Raw

Raw / unitless — only discount scaling.

enum class gtopt::ConstraintType: std::uint8_t

enum class gtopt::ConvergenceMode: uint8_t

SDDP convergence criterion selection.

All modes respect min_iterations and max_iterations.

  • gap_only: Converge only when the deterministic gap closes.
  • gap_stationary: Also declare convergence when the gap stops improving.
  • statistical: Full PLP-style criterion (default). Adds a confidence-interval test for multi-scene problems.
Enumerators
gap_only

Deterministic gap test only.

gap_stationary

Gap + stationary gap detection.

statistical

Gap + stationary + CI (default, PLP-style)

enum class gtopt::CutCoeffMode: uint8_t

How Benders cut coefficients are extracted from solved subproblems.

  • reduced_cost (default): Uses reduced costs of the dependent (fixed) columns.
  • row_dual: Adds explicit equality constraint rows to fix each dependent column and reads the row duals of those coupling constraints.
Enumerators
reduced_cost

Reduced costs of fixed dependent columns (default)

row_dual

Row duals of explicit coupling constraint rows (PLP)

enum class gtopt::CutSharingMode: uint8_t

SDDP cut sharing mode across scenes in the backward pass.

When a sharing mode other than none is selected, the backward pass is synchronized per-phase: all scenes complete a phase before cuts are shared and the next phase is processed.

Enumerators
none

No sharing; scenes solved independently (default)

expected

Average cuts within each scene, then sum across scenes.

accumulate

Sum all cuts directly (LP objectives pre-weighted)

max

All cuts from all scenes added to all scenes.

enum class gtopt::CutType: uint8_t

Type of Benders cut: optimality (standard) or feasibility (elastic filter)

Enumerators
Optimality

Standard Benders optimality cut.

Feasibility

Feasibility cut from elastic filter.

enum class gtopt::DataFormat: uint8_t

File format for input/output data files.

Enumerators
parquet

Apache Parquet columnar format (default)

csv

Comma-separated values.

enum class gtopt::ElasticFilterMode: uint8_t

How the elastic filter handles feasibility issues in the backward pass.

  • single_cut (default): Build a single Benders feasibility cut.
  • multi_cut: Build a Benders cut + per-slack bound cuts.
  • backpropagate: Update source bounds to elastic trial values (PLP).
Enumerators
single_cut

Build a single Benders feasibility cut (default)

multi_cut

Build a Benders cut + per-slack bound cuts.

backpropagate

Update source bounds to elastic trial values (PLP)

enum class gtopt::EnergyScaleMode: uint8_t

How the LP energy-variable scaling factor is determined for storage elements (reservoirs, batteries).

  • manual (0): Use the explicit energy_scale field (default 1.0 if unset). This is the legacy behaviour.
  • auto_scale (1, default): Compute energy_scale by rounding emax/1000 up to the next power of 10, so LP variables stay in a well-conditioned range regardless of physical reservoir size. Formula: energy_scale = 10^ceil(log10(emax / 1000)) when emax > 1000, else 1.0. Matches PLP practice where ScaleVol values (Escala/1e6, 10^(FEscala-6)) are powers of 10. An explicit energy_scale field on the element overrides auto.
Enumerators
manual

Use explicit energy_scale field (legacy, 1.0 default)

auto_scale

Compute from emax: max(1.0, emax / 1000) (default)

enum class gtopt::ErrorCode: uint8_t

enum class gtopt::HotStartMode: uint8_t

How the SDDP solver handles hot-start and the output cut file.

Controls both whether to load cuts from a previous run and how to handle the combined output file (sddp_cuts.csv) at the end of the solve.

Enumerators
none

Cold start — no cuts loaded (default)

keep

Hot-start; keep original output file unchanged.

append

Hot-start; append new cuts to original file.

replace

Hot-start; replace original file with all cuts.

enum class gtopt::KappaWarningMode: uint8_t

Controls warnings when the LP condition number (kappa) exceeds a threshold.

After each LP solve (forward, backward, aperture, and monolithic), the solver checks the basis condition number. When kappa exceeds kappa_threshold (default 1e9), this option controls the response.

  • none: No kappa checking or warnings.
  • warn: Log a warning with scene, phase, and iteration (default).
  • save_lp: Log a warning AND save the culprit LP file for debugging.
Enumerators
none

No kappa checking.

warn

Log a warning when kappa exceeds threshold (default)

save_lp

Warn and save the LP file.

enum class gtopt::LineLossesMode: uint8_t

Selects the mathematical model for transmission line losses.

Each mode trades off accuracy, LP size, and solver compatibility:

  • none (0): No losses. Flow balance: P_send = P_recv. Simplest model; suitable when losses are negligible or handled externally.
  • linear (1): Lumped linear loss factor λ. P_loss = λ · |f|. If the line has resistance > 0 and voltage > 0 but no explicit lossfactor, one is auto-computed as λ = R · f_max / V² (linearization at rated flow of the quadratic curve P_loss = R · f² / V²). Zero extra LP rows; loss enters as bus-balance coefficients. Ref: Wood & Wollenberg, "Power Generation, Operation and Control", Ch. 13, incremental transmission losses.
  • piecewise (2): Single-direction piecewise-linear approximation of P_loss = R · f² / V². One set of K segments covers the absolute flow range [0, f_max], producing K segment variables, 1 linking row, and 1 loss-tracking row per block. Segment k (1-based) has loss coefficient (f_max/K) · R · (2k−1) / V². This is the PLP/PSR approach and produces half the rows of the bidirectional mode. Ref: Macedo, Vallejos, Fernández, "A Dynamic Piecewise Linear Model for DC Transmission Losses in Optimal Scheduling Problems", IEEE Trans. Power Syst., vol. 26, no. 1, 2011.
  • bidirectional (3): Two independent piecewise-linear models, one per flow direction (A→B and B→A). Each direction gets its own K segment variables + linking + loss-tracking rows. Produces 2× the rows and columns of piecewise but explicitly prevents simultaneous bidirectional flow through non-negative variable bounds. Ref: FERC Staff Paper, "Optimal Power Flow Paper 2: Linearization", December 2012.
  • adaptive (4): Automatically selects piecewise for lines with fixed capacity (no expansion modules) and bidirectional for expandable lines. Fixed-capacity lines can encode f ≤ tmax in segment variable bounds, so a single-direction model suffices. Expandable lines need explicit capacity rows (cap − f ≥ 0) per direction, requiring the bidirectional decomposition. This is the recommended default for mixed networks.
  • dynamic (5): Iteratively adjusted piecewise-linear segments that track the current operating point. Achieves higher accuracy with fewer segments than static PWL. Currently a placeholder that falls back to piecewise with a log warning. Ref: Macedo et al. (2011), §III — dynamic cut adjustment.
Enumerators
none

No losses modeled.

linear

Lumped linear loss factor.

piecewise

Single-direction piecewise-linear (PLP-style)

bidirectional

Two-direction piecewise-linear (gtopt legacy)

adaptive

Piecewise if fixed capacity, bidirectional if expandable.

dynamic

Dynamic piecewise-linear (future; falls back to piecewise)

enum class gtopt::LossAllocationMode: uint8_t

How transmission losses are allocated between sender and receiver buses in the nodal power balance equation.

The total loss is always λ·f (conserving energy). The allocation determines which bus "absorbs" the loss in the KCL equation via emission (PerdEms) and reception (PerdRec) fractions where PerdEms + PerdRec = 1:

  • receiver (0, default): sender = −f, receiver = +(1 − λ)f. PerdEms=0, PerdRec=1.
  • sender (1): sender = −(1 + λ)f, receiver = +f. PerdEms=1, PerdRec=0. (PLP FPerdLin = 'E')
  • split (2): sender = −(1 + λ/2)f, receiver = +(1 − λ/2)f. PerdEms=0.5, PerdRec=0.5. (PLP FPerdLin = 'M')
Enumerators
receiver

100% losses at receiving bus (default)

sender

100% losses at sending bus (PLP 'E')

split

50/50 between sender and receiver (PLP 'M')

enum class gtopt::LPAlgo: uint8_t

Enumeration of linear programming solution algorithms.

Enumerators
default_algo

Use the solver's default algorithm.

primal

Use the primal simplex algorithm.

dual

Use the dual simplex algorithm.

barrier

Use the interior point (barrier) algorithm.

last_algo

Sentinel value for iteration/validation.

enum class gtopt::LpEquilibrationMethod: uint8_t

LP matrix equilibration method for numerical conditioning.

Controls how the constraint matrix is scaled before being sent to the LP solver. Better-conditioned matrices produce more accurate solutions and reduce solver iterations.

  • none: No equilibration (default).
  • row_max: Per-row max-abs normalization. Each row is divided by its largest |coefficient| so that every row's infinity-norm becomes 1.0.
  • ruiz: Ruiz geometric-mean iterative scaling. Alternately normalizes rows and columns by sqrt(infinity-norm) until convergence. Produces a better-conditioned matrix than single-pass row_max, especially for problems with heterogeneous variable scales. Ref: Ruiz, D. (2001) "A scaling algorithm to equilibrate both rows and columns norms in matrices".
Enumerators
none

No equilibration (default)

row_max

Per-row max-abs normalization.

ruiz

Ruiz geometric-mean iterative scaling.

enum class gtopt::LpNamesLevel: uint8_t

LP variable/constraint naming level for matrix assembly.

Controls how much naming information is generated during LP construction. Higher levels provide better diagnostics but consume more memory.

  • minimal: State-variable column names only (for internal use, e.g. cascade solver state transfer). Smallest footprint.
  • only_cols: All column names + name-to-index maps.
  • cols_and_rows: Column + row names + maps. Warns on duplicate names.
Enumerators
minimal

State-variable column names only (default)

only_cols

All column names + name maps.

cols_and_rows

Column + row names + maps + warn on duplicates.

enum class gtopt::MethodType: uint8_t

Top-level solver selection: monolithic LP, SDDP, or cascade.

Enumerators
monolithic

Single monolithic LP/MIP (default)

sddp

Stochastic Dual Dynamic Programming decomposition.

cascade

Cascade: Benders -> guided SDDP -> free SDDP.

enum class gtopt::MissingCutVarMode: uint8_t

How to handle boundary/named cut rows that reference state variables not present in the current model.

  • skip_coeff: Drop the missing variable's coefficient from the cut but still load the cut (default).
  • skip_cut: Skip the entire cut if any missing variable has a non-zero coefficient.
Enumerators
skip_coeff

Drop the coefficient, load the cut.

skip_cut

Skip the entire cut.

enum class gtopt::MonthType: uint8_t

Calendar month (1-based: january=1, december=12).

Used in Stage to tag each planning period with its calendar month, enabling seasonal parameter lookups (e.g., irrigation schedules).

enum class gtopt::ProbabilityRescaleMode: uint8_t

Controls when scenario/scene probabilities are rescaled to sum 1.0.

Scenario probability_factor values within each scene should sum to 1.0. When they do not, a warning is always emitted. This option controls whether (and when) the solver normalizes the values automatically.

  • none: No rescaling. Warn about mismatched probabilities but leave values unchanged. This may produce incorrect expected-cost computations if probabilities do not sum to 1.0.
  • build: Rescale at build time (during validation, before LP construction). Probabilities are normalized to sum 1.0 per scene and across all scenes.
  • runtime: Rescale at build time AND at runtime. In addition to build-time normalization, scene weights are re-normalized during SDDP when a scene becomes infeasible, so the remaining feasible scenes' probabilities still sum to 1.0. This is the default.
Enumerators
none

No rescaling, warn only.

build

Rescale at build/validation time.

runtime

Rescale at build time and at runtime (default)

enum class gtopt::RecoveryMode: uint8_t

Controls what is recovered from a previous SDDP run.

  • none: No recovery — cold start.
  • cuts: Recover only Benders cuts from previous run.
  • full: Recover Benders cuts AND state variable solutions (default).
Enumerators
none

No recovery — cold start.

cuts

Recover only Benders cuts.

full

Recover cuts + state variable solutions (default)

enum class gtopt::SDDPPassDirection: int

Pass direction for the is_backward field of SDDPTaskKey. Forward (0) has higher priority than backward (1) in lexicographic order.

enum class gtopt::SDDPTaskKind: int

Task kind for the is_nonlp field of SDDPTaskKey. LP solves (0) have higher priority than non-LP tasks (1).

enum class gtopt::SolveMode: uint8_t

Monolithic solver execution mode.

Enumerators
monolithic

Solve all phases in a single LP (default)

sequential

Solve phases sequentially.

enum class gtopt::SolverLogMode: uint8_t

Controls whether and how solver log files are written.

  • nolog: No solver log files are written (default).
  • detailed: Separate log files per scene/phase/aperture, using the naming pattern <solver>_sc<N>_ph<N>[_ap<N>].log. Each thread writes to its own file – no locking required.
Enumerators
nolog

No solver log files (default)

detailed

Separate log files per scene/phase/aperture.

enum class gtopt::SolverScaling: uint8_t

Solver-internal scaling strategy.

Controls whether and how the LP solver applies matrix scaling before solving. Each backend maps these values to its native parameter:

SolverScalingCPLEX CPX_PARAM_SCAINDHiGHS scale_strategyCLP
none-10 (off)0
automatic0 (equilibration)4 (default)3
aggressive1 (aggressive)1 (forced)2
Enumerators
none

Disable solver-internal scaling.

automatic

Solver's default/auto strategy (recommended)

aggressive

Aggressive equilibration (for high-kappa LPs)

enum class gtopt::StateVariableLookupMode: uint8_t

How update_lp elements obtain reservoir/battery volume between phases.

  • warm_start (default): volume comes from the previous iteration's warm-start solution, a recovered state file, or the element's vini.
  • cross_phase: volume is taken from the previous phase's efin within the same forward pass.
Enumerators
warm_start

Warm solution / recovery / vini (default, no cross-phase)

cross_phase

Previous phase's efin within the same forward pass.

enum class gtopt::TaskPriority: uint8_t

enum class gtopt::TaskStatus: uint8_t

Typedef documentation

using gtopt::ApertureSubmitFunc = std::function<std::future<ApertureCutResult>(const std::function<ApertureCutResult()>&task)>

Callback for submitting a complete aperture task to the work pool.

Accepts a task function that returns an ApertureCutResult and submits it to the SDDP work pool. Returns a future for the result. The caller submits all apertures first, then collects all futures, enabling parallel execution.

using gtopt::ApertureValueFn = std::function<std::optional<double>(StageUid, BlockUid)>

Value-provider signature: (StageUid, BlockUid) -> std::optional<double>. Returns the aperture value for the given stage/block, or std::nullopt if the value is unavailable (keeps the forward-pass value unchanged).

template<typename Type>
using gtopt::Array = std::vector<Type>

Array type template for consistent vector usage.

Template parameters
Type The element type to store in the array

using gtopt::ArrowArray = std::shared_ptr<arrow::Array>

using gtopt::ArrowChunkedArray = std::shared_ptr<arrow::ChunkedArray>

using gtopt::ArrowColumnResult = arrow::Result<ArrowChunkedArray>

using gtopt::ArrowField = std::shared_ptr<arrow::Field>

using gtopt::ArrowIndex = int64_t

using gtopt::ArrowTable = std::shared_ptr<arrow::Table>

template<typename Value = Index>
using gtopt::BIndexHolder = IndexHolder0<BlockUid, Value>

using gtopt::Bool = bool

Boolean type for logical conditions.

using gtopt::BusLPId = ObjectId<class BusLP>

using gtopt::ColIndex = StrongIndexType<SparseCol>

Type alias for column index.

template<typename Type, typename Vector = std::vector<Type>>
using gtopt::FieldSched = std::variant<Type, Vector, FileSched>

template<typename Type, typename Vector2 = std::vector<std::vector<Type>>>
using gtopt::FieldSched2 = FieldSched<Type, Vector2>

template<typename Type, typename Vector3 = std::vector<std::vector<std::vector<Type>>>>
using gtopt::FieldSched3 = FieldSched<Type, Vector3>

using gtopt::FileSched = String

template<typename key_type, typename value_type>
using gtopt::flat_map = std::map<key_type, value_type>

using gtopt::FlowLPSId = ObjectSingleId<class FlowLP>

Single-ID alias for referencing a FlowLP in other LP elements.

template<typename Value = Index>
using gtopt::GSTBIndexHolder = tuple_map_t<std::tuple<ScenarioUid, StageUid, BlockUid>, Value>

template<typename Value = Index>
using gtopt::GSTIndexHolder = tuple_map_t<std::tuple<ScenarioUid, StageUid>, Value>

using gtopt::Id = std::pair<Uid, Name>

Combined identifier with both numeric ID and name.

using gtopt::Index = std::int32_t

Index type for large-scale sparse matrices and arrays.

template<typename key_type, typename value_type>
using gtopt::index_map_t = gtopt::flat_map<key_type, value_type>

template<typename FirstIndex, typename Value = Index>
using gtopt::IndexHolder0 = gtopt::flat_map<FirstIndex, Value>

template<typename FirstIndex, typename Value = Index>
using gtopt::IndexHolder1 = index_map_t<FirstIndex, Value>

template<typename FirstIndex, typename SecondIndex, typename Value = Index>
using gtopt::IndexHolder2 = tuple_map_t<std::tuple<FirstIndex, SecondIndex>, Value>

template<typename FirstIndex, typename SecondIndex, typename ThirdIndex, typename Value = Index>
using gtopt::IndexHolder3 = tuple_map_t<std::tuple<FirstIndex, SecondIndex>, IndexHolder0<ThirdIndex, Value>>

using gtopt::IniData = std::map<std::string, std::map<std::string, std::string>>

Parsed INI sections: section name → {key → value}.

using gtopt::Int = int

Integer type for counting and discrete quantities.

using gtopt::IntBool = std::int32_t

Integer boolean for space-efficient storage.

using gtopt::IterationIndex = StrongIndexType<IterationTag>

Strongly-typed index for SDDP iterations.

using gtopt::lp_collection_ptrs_t = std::array<const void*, lp_type_count_v>

Array of const void* pointers, one slot per LP element type.

Each slot stores a pointer to the corresponding Collection<T> inside a SystemLP. The slot for type T is at index lp_type_index_v<T>. Populated in SystemContext::SystemContext() via std::apply.

using gtopt::lp_element_types_t = std::tuple<BusLP, DemandLP, GeneratorLP, LineLP, GeneratorProfileLP, DemandProfileLP, BatteryLP, ConverterLP, ReserveZoneLP, ReserveProvisionLP, JunctionLP, WaterwayLP, FlowLP, ReservoirLP, ReservoirSeepageLP, ReservoirDischargeLimitLP, TurbineLP, ReservoirProductionFactorLP, FlowRightLP, VolumeRightLP, UserConstraintLP>

Ordered tuple of all LP element types.

The position of each type in this tuple determines its index in the m_collection_ptrs_ array inside SystemContext (see lp_type_index_v). The order matches SystemLP::collections_t for readability, but correctness does not depend on that — the indices are always looked up via lp_type_index_v<T>, never assumed to match positionally.

UserConstraintLP is always the LAST type so that user constraints are added to the LP after all other elements (user constraints reference columns created by the earlier elements).

template<typename Type, typename Tuple>
using gtopt::mvector_traits_auto = mvector_traits<Type, Tuple, std::tuple_size_v<Tuple>>

using gtopt::Name = std::string

Name type for entity identification.

using gtopt::NameView = std::string_view

String view type for non-owning name references.

using gtopt::OptBool = std::optional<Bool>

Optional boolean type.

using gtopt::OptBoolFieldSched = std::optional<BoolFieldSched>

using gtopt::OptInt = std::optional<Int>

Optional integer type.

using gtopt::OptIntBool = std::optional<IntBool>

Optional integer boolean type.

using gtopt::OptIntBoolFieldSched = std::optional<IntBoolFieldSched>

using gtopt::OptIntFieldSched = std::optional<IntFieldSched>

using gtopt::Options = PlanningOptions

Backward-compatibility alias (deprecated — use PlanningOptions)

using gtopt::OptionsLP = PlanningOptionsLP

Backward-compatibility alias (deprecated — use PlanningOptionsLP)

using gtopt::OptName = std::optional<Name>

Optional name type.

using gtopt::OptReal = std::optional<Real>

Optional real number type.

using gtopt::OptRealFieldSched = std::optional<RealFieldSched>

using gtopt::OptRealFieldSched2 = std::optional<RealFieldSched2>

using gtopt::OptRealFieldSched3 = std::optional<RealFieldSched3>

using gtopt::OptSceneIndex = std::optional<SceneIndex>

using gtopt::OptSingleId = std::optional<SingleId>

using gtopt::OptStageIndex = std::optional<StageIndex>

using gtopt::OptUid = std::optional<Uid>

Optional unique identifier type.

using gtopt::PhaseIndex = StrongIndexType<Phase>

Strongly-typed index for Phase objects in collections.

using gtopt::PhaseUid = StrongUidType<Phase>

Strongly-typed unique identifier for Phase objects.

using gtopt::Real = double

Real number type for physical quantities and costs.

using gtopt::RowIndex = StrongIndexType<SparseRow>

Type alias for row index.

using gtopt::SceneUid = StrongUidType<Scene>

using gtopt::SDDPIterationCallback = std::function<bool(const SDDPIterationResult&result)>

Callback invoked after each SDDP iteration. If the callback returns true, the solver stops after this iteration.

using gtopt::SDDPTaskKey = std::tuple<int, int, int, int>

SDDP solver task priority key.

A 4-tuple (iteration_index, is_backward, phase_index, is_nonlp):

  • iteration_index: SDDP iteration number (0, 1, …)
  • is_backward: 0 = forward pass, 1 = backward pass
  • phase_index: phase within the iteration (0, 1, …)
  • is_nonlp: 0 = LP solve/resolve, 1 = other (e.g. write_lp)

With the default std::less<SDDPTaskKey> comparator, the tuple is compared lexicographically: lower iteration → lower is_backward → lower phase → lower is_nonlp → higher execution priority.

using gtopt::SingleId = std::variant<Uid, Name>

using gtopt::Size = std::size_t

Size type for container dimensions and indices.

using gtopt::solver_backend_factory_fn = SolverBackend*(*)(const char*solver_name)

Plugin entry-point function type: creates a SolverBackend by solver name.

using gtopt::solver_plugin_abi_version_fn = int(*)()

Plugin ABI version function type: returns the ABI version the plugin was built against. SolverRegistry rejects plugins whose version differs from k_solver_abi_version.

using gtopt::solver_plugin_name_fn = const char*(*)()

Plugin name function type: returns the plugin name.

using gtopt::solver_plugin_names_fn = const char*const *(*)()

Plugin solver-list function type: returns null-terminated array of names.

using gtopt::stage_factor_matrix_t = std::vector<double>

using gtopt::StageUid = StrongUidType<Stage>

template<typename Value = Index>
using gtopt::STBIndexHolder = IndexHolder3<ScenarioUid, StageUid, BlockUid, Value>

template<typename Value = Index>
using gtopt::STIndexHolder = IndexHolder2<ScenarioUid, StageUid, Value>

using gtopt::String = std::string

String type for general textual data.

template<typename Type>
using gtopt::StrongIndexType = strong::type<Index, Type, strong::formattable, strong::regular, strong::hashable, strong::arithmetic, strong::bicrementable, strong::implicitly_convertible_to<Index>>

Strong type for indices with additional type safety and operations.

Template parameters
Type The tag type for compile-time type checking

template<typename Type>
using gtopt::StrongUidType = strong::type<uid_t, Type, strong::formattable, strong::regular, strong::hashable, strong::arithmetic, strong::implicitly_convertible_to<uid_t>>

Strong type for unique identifiers with additional type safety.

Template parameters
Type The tag type for compile-time type checking

using gtopt::TaskRequirements = BasicTaskRequirements<>

Backward-compatible alias: TaskRequirements is BasicTaskRequirements<int64_t>.

template<typename Value = Index>
using gtopt::TIndexHolder = IndexHolder1<StageUid, Value>

template<typename key_type, typename value_type>
using gtopt::tuple_map_t = gtopt::flat_map<key_type, value_type>

using gtopt::TurbineLPSId = ObjectSingleId<class TurbineLP>

Single-ID alias for referencing a TurbineLP in other LP elements.

using gtopt::Uid = uid_t

Unique identifier type.

using gtopt::uid_t = std::int32_t

Base type for unique identifiers.

Used for entity identification in the power system model

using gtopt::UserParamMap = std::unordered_map<Name, UserParam>

A collection of named parameters, keyed by name for fast lookup.

Function documentation

auto gtopt::accumulate_benders_cuts(const std::vector<SparseRow>& cuts, std::string_view name) -> SparseRow

Parameters
cuts Collection of Benders optimality cuts (SparseRow)
name Name for the resulting accumulated cut row

Accumulate (sum) all cuts into a single combined cut.

When LP subproblem objectives already include probability factors, the correct "expected cut" is the sum of all individual cuts rather than a weighted average. Each cut's coefficients and RHS are assumed to be pre-weighted by the scenario probability.

The resulting cut has: lowb = Σ_i cuts[i].lowb coefficients = Σ_i cuts[i].coefficients (for each column) uppb = DblMax (unchanged)

template<std::ranges::range Range>
constexpr auto gtopt::active(Range&& range) noexcept

template<std::ranges::range Range, typename Pred>
constexpr bool gtopt::all_of(Range&& range, Pred&& pred) noexcept(…)

Checks if all elements in range satisfy predicate.

Template parameters
Range Input range type
Pred Predicate type
Parameters
range Input range
pred Predicate to test
Returns true if all elements satisfy predicate, false otherwise

constexpr double gtopt::annual_discount_factor(double annual_discount_rate, double time_hours) noexcept

void gtopt::apply_cli_options(Planning& planning, const MainOptions& opts)

Apply command-line options from a MainOptions struct to a Planning object.

Parameters
planning The Planning object to update
opts The MainOptions containing the option overrides

Convenience overload that takes a MainOptions struct directly, delegating to the individual-parameter overload.

void gtopt::apply_cli_options(Planning& planning, const std::optional<bool>& use_single_bus, const std::optional<bool>& use_kirchhoff, const std::optional<LpNamesLevel>& lp_names_level, const std::optional<std::string>& input_directory, const std::optional<std::string>& input_format, const std::optional<std::string>& output_directory, const std::optional<std::string>& output_format, const std::optional<std::string>& output_compression, const std::optional<std::string>& cut_directory = {}, const std::optional<std::string>& log_directory = {}, const std::optional<int>& sddp_max_iterations = {}, const std::optional<double>& sddp_convergence_tol = {}, const std::optional<double>& sddp_elastic_penalty = {}, const std::optional<std::string>& sddp_elastic_mode = {}, const std::optional<std::string>& sddp_cut_coeff_mode = {}, const std::optional<int>& sddp_num_apertures = {}, const std::optional<bool>& lp_debug = {}, const std::optional<std::string>& lp_compression = {}, const std::optional<double>& lp_coeff_ratio_threshold = {})

Apply command-line options to a Planning object.

Parameters
planning The Planning object to update
use_single_bus Optional single-bus mode flag
use_kirchhoff Optional Kirchhoff mode flag
lp_names_level Optional LP naming level (minimal/only_cols/cols_and_rows)
input_directory Optional input directory path
input_format Optional input format string
output_directory Optional output directory path
output_format Optional output format string
output_compression Optional compression codec string
cut_directory Optional directory for SDDP cut files
log_directory Optional directory for log/debug LP files
sddp_max_iterations Optional SDDP max iterations
sddp_convergence_tol Optional SDDP convergence tolerance
sddp_elastic_penalty Optional elastic penalty coefficient
sddp_elastic_mode Optional elastic filter mode string
sddp_cut_coeff_mode Optional SDDP cut coefficient mode string
sddp_num_apertures Optional number of SDDP apertures
lp_debug Optional flag to enable LP debug output
lp_compression Optional LP output compression codec string
lp_coeff_ratio_threshold Optional threshold for LP coefficient ratio

Updates the planning options based on parsed command-line values.

template<char sep = '_'>
constexpr auto gtopt::as_label() noexcept

Creates an empty label string.

Template parameters
sep Separator character (default '_')
Returns constexpr std::string Empty string

template<char sep = '_', typename... Args>
std::string gtopt::as_label(Args && ... args) noexcept(…)

Creates a concatenated label from multiple arguments.

Template parameters
sep Separator character between components (default '_')
Args Argument types (automatically deduced)
Parameters
args Values to concatenate into label
Returns constexpr std::string Concatenated label string
Exceptions
Nothing if all arguments can be converted to string without throwing

Example:

auto label = as_label("config", "value", 42); // "config_value_42"

template<char sep = '_'>
constexpr void gtopt::as_label_into(std::string& result) noexcept

Clears and writes a label into an existing string buffer.

Template parameters
sep Separator character (default '_')
Returns constexpr void

template<char sep = '_', typename... Args>
void gtopt::as_label_into(std::string& result, Args && ... args) noexcept(…)

Writes a concatenated label into an existing string buffer.

Template parameters
sep Separator character between components (default '_')
Args Argument types (automatically deduced)
Parameters
result String buffer to write into (cleared, not deallocated)
args Values to concatenate into label

Like as_label(), but reuses the buffer's existing capacity to avoid repeated heap allocations across calls. The buffer is cleared (not deallocated) on each call, so its capacity grows monotonically to the high-water mark.

template<typename... Args>
std::string gtopt::as_string(const std::tuple<Args...>& t)

auto gtopt::average_benders_cut(const std::vector<SparseRow>& cuts, std::string_view name) -> SparseRow

Compute an average cut from a collection of cuts (for Expected sharing)

auto gtopt::build_benders_cut(ColIndex alpha_col, std::span<const StateVarLink> links, std::span<const double> reduced_costs, double objective_value, std::string_view name, double scale_alpha = 1.0, double cut_coeff_eps = 0.0) -> SparseRow

Parameters
alpha_col Column index of the α (future-cost) variable.
links State-variable linkage descriptors.
reduced_costs Reduced costs of dependent columns from the LP solve.
objective_value Optimal objective value of the sub-problem.
name Name tag for the resulting cut row.
scale_alpha Scale divisor for α (PLP varphi scale; default 1.0).
cut_coeff_eps Threshold below which state-var coefficients are dropped (default 0.0 = keep all). Returns the cut as a SparseRow ready to add to the source phase.

Build a Benders optimality cut from reduced costs of dependent columns.

scale_alpha · α_lp ≥ z_t + Σ_i rc_i · (x_{t-1,i} − v̂_i)

auto gtopt::build_benders_cut_from_row_duals(ColIndex alpha_col, std::span<const StateVarLink> links, std::span<const double> row_duals, double objective_value, std::string_view name, double scale_alpha = 1.0, double cut_coeff_eps = 0.0) -> SparseRow

Parameters
alpha_col Column index of the α (future-cost) variable.
links State-variable linkage descriptors.
row_duals Row duals from the LP solve (indexed by RowIndex).
objective_value Optimal objective value of the sub-problem.
name Name tag for the resulting cut row.
scale_alpha Scale divisor for α (PLP varphi scale; default 1.0).
cut_coeff_eps Threshold below which state-var coefficients are dropped (default 0.0 = keep all). Requires that propagate_trial_values_row_dual() was called first so that each link has a valid coupling_row index.

Build a Benders optimality cut from row duals of coupling constraints (PLP-style).

scale_alpha · α_lp ≥ z_t + Σ_i π_i · (x_{t-1,i} − v̂_i)

where π_i = row_duals[link.coupling_row] is the dual of the explicit equality constraint that fixes the dependent column.

auto gtopt::build_effective_apertures(std::span<const Aperture> aperture_defs, std::span<const Uid> phase_apertures) -> std::vector< ApertureEntry >

Parameters
aperture_defs All aperture definitions from the simulation
phase_apertures Per-phase aperture UID set (may be empty)
Returns Deduplicated aperture entries with repetition counts

Build the effective (deduplicated) aperture list for a single phase.

When phase_apertures is empty, all active apertures from aperture_defs are used (each with count = 1). When phase_apertures is non-empty, UIDs are counted for duplicates and mapped to their definitions; order of first appearance is preserved for deterministic results.

auto gtopt::build_feasibility_cut(const LinearInterface& li, ColIndex alpha_col, std::span<const StateVarLink> links, double penalty, const SolverOptions& opts, std::string_view name, double scale_alpha = 1.0) -> std::optional< FeasibilityCutResult >

Parameters
li The LP to clone (not modified)
alpha_col α column in the source phase's LP
links Outgoing state-variable links from the source phase
penalty Elastic penalty coefficient
opts Solver options
name Name for the resulting cut row
scale_alpha
Returns A feasibility cut (SparseRow) and the ElasticSolveResult, or nullopt if the elastic solve fails.

Build a Benders feasibility cut from a solved elastic clone.

This wraps the common pattern: clone → relax → solve → extract cut. The function calls elastic_filter_solve() internally.

auto gtopt::build_multi_cuts(const ElasticSolveResult& elastic, std::span<const StateVarLink> links, std::string_view name_prefix, double slack_tol = 1e-6) -> std::vector< SparseRow >

Parameters
elastic The solved elastic clone and per-link slack info
links Outgoing state-variable links (same order as elastic)
name_prefix Prefix for generated cut names
slack_tol Minimum slack magnitude to consider "active"
Returns Vector of bound-constraint cuts (may be empty)

Build per-slack bound-constraint cuts from a solved elastic clone.

For each outgoing link whose slack was activated (non-zero) in the elastic-clone solution, this function generates one or two bound-cut rows on the source column:

  • sup > ε ⟹ source_col ≤ dep_val (upper-bound cut)
  • sdn > ε ⟹ source_col ≥ dep_val (lower-bound cut)

auto gtopt::build_phase_uid_map(const PlanningLP& planning_lp) -> flat_map< PhaseUid, PhaseIndex >

Build a phase UID -> PhaseIndex lookup from a SimulationLP. Uses flat_map for cache-friendly sorted lookup.

auto gtopt::build_scene_uid_map(const PlanningLP& planning_lp) -> flat_map< SceneUid, SceneIndex >

Build a scene UID -> SceneIndex lookup from a SimulationLP. Uses flat_map for cache-friendly sorted lookup.

auto gtopt::build_synthetic_apertures(std::span<const ScenarioLP> all_scenarios, int n_apertures) -> Array< Aperture >

Parameters
all_scenarios All scenario LP objects
n_apertures Number of apertures to create (capped at all_scenarios.size())
Returns Array of synthetic Aperture objects

Build synthetic aperture definitions from the first N scenarios.

Creates one aperture per scenario with equal probability (1/N). Used when no explicit aperture_array is provided in the simulation and the solver falls back to the legacy num_apertures-based behaviour.

std::filesystem::path gtopt::build_table_path(std::string_view input_dir, std::string_view cname, std::string_view fname)

Build the filesystem path for an input table.

Parameters
input_dir Root input directory.
cname Class name (used as sub-directory when '@' is absent).
fname Field name, possibly containing an '@' separator.
Returns Resolved path (without file extension).

If fname contains '@', the part before '@' is treated as an override class directory; otherwise cname is used.

auto gtopt::cast_to_double_array(const std::shared_ptr<arrow::Array>& chunk) -> std::shared_ptr< arrow::DoubleArray >

Cast an Arrow array chunk to DoubleArray, handling float32 widening.

Parameters
chunk The Arrow array chunk to cast
Returns A shared pointer to a DoubleArray, or nullptr if the type is incompatible

auto gtopt::cast_to_int32_array(const std::shared_ptr<arrow::Array>& chunk) -> std::shared_ptr< arrow::Int32Array >

int gtopt::check_all_solvers(bool verbose = false)

Run the test suite against every solver known to SolverRegistry.

Parameters
verbose Forward to run_solver_tests.
Returns 0 if all tests for all solvers pass, 1 otherwise.

Calls run_solver_tests() for each available solver in the order returned by SolverRegistry::available_solvers() and prints a summary to stdout.

int gtopt::classify_error_exit_code(std::string_view error) noexcept

Classify an error string into an exit code.

Returns 2 for input errors (missing file, parse error, invalid JSON), 3 for internal/solver errors.

Examines error for keywords indicating input-related errors vs internal/solver errors.

constexpr auto gtopt::col_scale_cost(double scale) noexcept

Returns a lambda that rescales LP reduced costs to physical units. rc_physical = rc_LP / scale (inverse of primal rescaling).

Usage in add_to_output: out.add_col_cost(cname, "theta", pid, theta_cols, col_scale_cost(scale));

constexpr auto gtopt::col_scale_sol(double scale) noexcept

Returns a lambda that rescales LP primal values to physical units. physical_value = LP_value × scale.

Usage in add_to_output: out.add_col_sol(cname, "theta", pid, theta_cols, col_scale_sol(scale));

void gtopt::collect_sum_cols(const SystemContext& sc, const ScenarioLP& scenario, const StageLP& stage, const BlockLP& block, const SumElementRef& sum_ref, double base_coeff, SparseRow& row, const LinearProblem& lp)

Collect (coefficient, ColIndex) pairs for a SumElementRef.

When sum_ref.all_elements is true, iterates over every element in the collection of the matching type. Otherwise iterates over the explicit ID list. The base_coeff is multiplied into each term's coefficient.

double gtopt::compute_convergence_gap(double upper_bound, double lower_bound) noexcept

Compute relative convergence gap: (UB - LB) / max(1.0, |UB|). Always returns a non-negative value.

std::vector<double> gtopt::compute_scene_weights(std::span<const SceneLP> scenes, std::span<const uint8_t> scene_feasible, ProbabilityRescaleMode rescale_mode = ProbabilityRescaleMode::runtime) noexcept

Parameters
scenes The scene objects from SimulationLP
scene_feasible Per-scene feasibility flag (0 = infeasible); output size equals scene_feasible.size()
rescale_mode When runtime, normalize weights over feasible scenes to sum 1.0. When build or none, use raw probability weights (no re-normalization).
Returns Weight vector of size scene_feasible.size()

Compute normalised per-scene probability weights.

For each scene: weight = sum of scenario probability_factors if positive, else 1.0. Infeasible scenes (scene_feasible[si]==0) get weight 0. Weights are normalised to sum to 1 across feasible scenes. Falls back to equal weights when no positive probabilities are found.

template<typename Collections>
constexpr auto gtopt::count_all_elements(Collections&& collections)

Counts the total number of active elements across all collections.

Parameters
collections Tuple of collections to count
Returns Total number of active elements

auto gtopt::csv_read_table(const std::filesystem::path& fpath) -> std::expected< ArrowTable, std::string >

Read an Arrow table from a CSV file.

Configures the CSV reader to use typed columns for Scenario, Stage and Block UIDs. Returns an error string on failure.

auto gtopt::detect_islands_and_fix_references(Array<Bus>& buses, const Array<Line>& lines, const PlanningOptionsLP& options) -> std::size_t

Detect bus islands and assign a reference bus per island.

Parameters
buses Mutable bus array — reference_theta may be set.
lines Transmission lines (read-only).
options Resolved planning options.
Returns Number of islands detected (0 when Kirchhoff is disabled).

Builds a Union-Find over buses connected by lines that have a non-null reactance (i.e. lines participating in Kirchhoff constraints). For each resulting connected component (island) that lacks a user-specified reference_theta, the first bus in that island is assigned reference_theta = 0.

Self-loop lines (bus_a == bus_b) are silently ignored.

When Kirchhoff is disabled or only one bus exists, this function is a no-op and returns 0.

auto gtopt::elastic_filter_solve(const LinearInterface& li, std::span<const StateVarLink> links, double penalty, const SolverOptions& opts, std::span<const double> forward_col_sol = {}, std::span<const double> forward_row_dual = {}) -> std::optional< ElasticSolveResult >

Parameters
li The LP to clone (not modified)
links Outgoing state-variable links from the previous phase
penalty Elastic penalty coefficient for slack variables
opts Solver options for the clone solve
forward_col_sol Optional warm-start column solution for the clone.
forward_row_dual Optional warm-start row duals for the clone.
Returns Solved elastic clone and per-link slack info, or nullopt if no columns were fixed or the clone solve failed.

Clone the LP, apply elastic relaxation on fixed state-variable columns, and solve the clone. The original LP is never modified.

template<typename Map, typename BHolder>
constexpr auto gtopt::emplace_bholder(const ScenarioLP& scenario, const StageLP& stage, Map& map, BHolder&& holder, bool empty_insert = false)

template<typename Map, typename Value = Map::value_type>
constexpr auto gtopt::emplace_value(const ScenarioLP& scenario, const StageLP& stage, Map& map, Value&& value)

constexpr auto gtopt::enum_entries(LPAlgo) noexcept

ADL customization point for NamedEnum concept.

constexpr auto gtopt::enum_entries(SolverLogMode) noexcept

ADL customization point for NamedEnum concept.

constexpr auto gtopt::enum_entries(SolverScaling) noexcept

ADL customization point for NamedEnum concept.

template<typename E, std::size_t N>
constexpr auto gtopt::enum_from_name(std::span<const EnumEntry<E>, N> entries, std::string_view name) noexcept -> std::optional< E >

Look up an enumerator by its canonical name (span overload).

Template parameters
E Enum type.
N Table size (deduced from the span extent).
Parameters
entries Compile-time table of name-value pairs.
name Case-sensitive name to search for.
Returns The matching enumerator, or std::nullopt if not found.

template<NamedEnum E>
constexpr auto gtopt::enum_from_name(std::string_view name) noexcept -> std::optional< E >

Look up a NamedEnum value by name (ADL-based).

Template parameters
E A type satisfying the NamedEnum concept.
Parameters
name Case-sensitive name to search for.
Returns The matching enumerator, or std::nullopt if not found.

Uses the ADL enum_entries(E{}) customization point to obtain the lookup table, then delegates to the span-based overload.

template<NamedEnum E>
constexpr auto gtopt::enum_name(E value) noexcept -> std::string_view

Return the canonical name of a NamedEnum value (ADL-based).

Parameters
value The enumerator to look up.
Returns The name string, or "unknown" for out-of-range values.

Uses the ADL enum_entries(value) customization point to obtain the lookup table, then delegates to the span-based overload.

template<typename E, std::size_t N>
constexpr auto gtopt::enum_name(std::span<const EnumEntry<E>, N> entries, E value) noexcept -> std::string_view

Return the canonical name of an enumerator (span overload).

Template parameters
E Enum type.
N Table size (deduced from the span extent).
Parameters
entries Compile-time table of name-value pairs.
value The enumerator to look up.
Returns The name string, or "unknown" for out-of-range values.

template<typename IndexType = std::size_t, std::ranges::range R, std::ranges::range... Rs>
constexpr auto gtopt::enumerate(R&& range, Rs && ... ranges) noexcept(…)

template<typename IndexType = size_t, typename Range>
constexpr auto gtopt::enumerate_active(const Range& range) noexcept

template<typename IndexType = size_t, std::ranges::range Range, typename Op>
constexpr auto gtopt::enumerate_if(Range&& range, Op&& op) noexcept(…)

auto gtopt::evaluate_bound_rule(const RightBoundRule& rule, Real volume) noexcept -> Real

Evaluate the piecewise-linear bound function.

Parameters
rule The bound rule with segments, cap, and floor
volume Current reservoir volume [hm3]
Returns The computed bound value (clamped)

Computes: result = constant_i + slope_i * volume for the active segment, then clamps to [floor, cap].

auto gtopt::evaluate_production_factor(const std::vector<ProductionFactorSegment>& segments, Real volume) noexcept -> Real

Evaluate the piecewise-linear concave efficiency function.

Parameters
segments The piecewise-linear segments
volume Current reservoir volume [hm³]
Returns Efficiency value (non-negative)

Implements the PLP FRendimientos function (plp-frendim.f):

result = min over all segments of
         { constant_i + slope_i × (volume − volume_breakpoint_i) }

Here constant_i is the efficiency at breakpoint_i (point-slope form). This is the concave-envelope minimum, matching the Fortran:

valfrendimientos = min(valfrendimientos,
    constantes(i) + pendientes(i) * (vol - bordes(i)))

Difference from seepage: ReservoirSeepageSegment.constant is the y-intercept (value at V = 0), while ProductionFactorSegment.constant is the value at the breakpoint. ReservoirSeepage uses range-based segment selection; efficiency uses concave-envelope minimum.

Returns at least 0.0 (efficiency cannot be negative).

auto gtopt::evaluate_seepage(const std::vector<ReservoirSeepageSegment>& segments, Real volume) noexcept -> Real

Evaluate the piecewise-linear seepage function.

Parameters
segments The piecewise-linear segments (sorted by volume breakpoint)
volume Current reservoir volume [hm³]
Returns ReservoirSeepage rate (non-negative) [m³/s]

Implements the PLP seepage model (matches Fortran FFiltracionesi):

Find the segment i where volume_i ≤ volume < volume_{i+1},
then compute:  result = constant_i + slope_i × volume

Here constant_i is the y-intercept at V = 0 for segment i's linear equation, matching the PLP file format (plpfilemb.dat Constante field).

Returns at least 0.0 (seepage rate cannot be negative).

void gtopt::filter_cut_coefficients(SparseRow& row, ColIndex alpha_col, double eps)

Parameters
row The cut row to filter in-place
alpha_col α column index (never filtered)
eps Absolute tolerance (coefficients with |value| < eps are removed)

Remove state-variable coefficients whose absolute value is below eps.

Unlike the eps filtering in build_benders_cut() (which skips tiny reduced costs before the RHS adjustment), this function filters the final cut coefficients and adjusts the RHS accordingly. Intended for post-rescale cleanup where previously significant coefficients may have become negligible.

auto gtopt::find_active_bound_segment(const std::vector<RightBoundSegment>& segments, Real volume) noexcept -> const RightBoundSegment *

Find the active segment for a given reservoir volume.

Returns a pointer to the last segment whose volume breakpoint is <= volume (range selection). Returns the first segment when volume is below all breakpoints.

auto gtopt::find_active_rdl_segment(const std::vector<ReservoirDischargeLimitSegment>& segments, Real volume) noexcept -> const ReservoirDischargeLimitSegment *

Find the active segment for a given reservoir volume.

Returns a pointer to the last segment whose volume breakpoint is ≤ volume.

Precondition: segments must be non-empty and sorted ascending by volume.

auto gtopt::find_active_segment(const std::vector<ReservoirSeepageSegment>& segments, Real volume) noexcept -> const ReservoirSeepageSegment *

Find the active segment for a given reservoir volume.

Parameters
segments The piecewise-linear segments (sorted by volume breakpoint)
volume Current reservoir volume [hm³]
Returns Pointer to the active ReservoirSeepageSegment (never null)

Returns a pointer to the last segment whose volume breakpoint is ≤ volume (range selection, matching PLP Fortran FFiltracionesi). Returns the first segment when volume is below all breakpoints.

Precondition: segments must be non-empty and sorted in ascending order by volume breakpoint. Results are undefined if this is violated.

std::filesystem::path gtopt::find_config_file()

Find the .gtopt.conf file following the standard search order.

Returns Path to the config file, or empty path if none found.
  1. $GTOPT_CONFIG (if set and file exists)
  2. ./.gtopt.conf (current directory)
  3. ~/.gtopt.conf (home directory)

template<typename Element, typename SystemContext SystemContext, template<typename> class Id>
constexpr auto&& gtopt::get_element(SystemContext& sc, const Id<Element>& id)

Free function to get a reference to an element by its ID.

Parameters
sc The system context.
id The ID of the element.
Returns A reference to the element.

template<typename Element, typename SystemContext SystemContext, template<typename> class Id>
constexpr auto gtopt::get_element_index(SystemContext& sc, const Id<Element>& id)

Free function to get the index of an element by its ID.

Parameters
sc The system context.
id The ID of the element.
Returns The ElementIndex for the given ID.

template<typename Element, typename SystemContext SystemContext>
constexpr auto&& gtopt::get_elements(SystemContext& sc) noexcept

Free function to get a container of all elements of a specific type.

Parameters
sc The system context.
Returns A reference to the container of elements.

template<typename Obj>
constexpr auto gtopt::get_name(const Obj& obj)

template<>
constexpr auto gtopt::get_name<Id>(const Id& obj)

template<typename T>
std::optional<T> gtopt::get_opt(const po::variables_map& vm, const std::string& name)

Extract an optional value from a variables_map.

Template parameters
T The type of the value to extract
Parameters
vm The variables map containing parsed options
name The name of the option to look up
Returns std::optional<T> containing the value if present, std::nullopt otherwise

template<typename T, typename K = T::key_type>
constexpr auto gtopt::get_optiter(const T& map, K&& key) noexcept

Finds key in map and returns optional iterator.

Template parameters
T Map type
K Key type (defaults to map's key_type)
Parameters
map Map to search
key Key to find
Returns std::optional containing iterator if found, nullopt otherwise
Exceptions
Nothing (noexcept)

template<typename T, typename K>
constexpr auto gtopt::get_optvalue(const T& map, K&& key)

template<typename T, typename K>
constexpr auto gtopt::get_optvalue_optkey(const T& map, const std::optional<K>& key)

template<typename Obj>
constexpr auto gtopt::get_uid(const Obj& obj) -> Uid

template<>
constexpr auto gtopt::get_uid<Id>(const Id& obj) -> Uid

auto gtopt::GetColumn(const ArrowTable& table, std::string_view name) -> ArrowColumnResult

Get column by name with explicit error checking.

std::expected<int, std::string> gtopt::gtopt_main(const MainOptions& raw_opts)

Run the gtopt power-system optimizer.

Parameters
raw_opts All runtime options; only set the fields you need.
Returns 0 on success, 1 on infeasibility, or an error string on failure.

Reads the planning files listed in raw_opts.planning_files, merges them into a single Planning object, applies CLI overrides, builds and solves the LP model, writes the solution output, and saves a copy of the merged planning as planning.json in the output directory.

template<typename Obj>
constexpr auto gtopt::id(const Obj& obj) noexcept -> Id

Creates an Id from an object's attributes.

Template parameters
Obj The object type (must have uid and name members)
Parameters
obj The object to get identification from
Returns Id containing the object's uid and name

constexpr bool gtopt::in_lp_debug_range(int scene_uid, int phase_uid, OptInt scene_min, OptInt scene_max, OptInt phase_min, OptInt phase_max) noexcept

Check whether a (scene_uid, phase_uid) pair falls inside the optional debug filter ranges. Empty optionals mean "no bound on that side".

template<typename IndexType, typename A, typename B>
constexpr auto gtopt::iota_range(A first, B last) -> IotaRange< IndexType >

Create an IotaRange [first, last) with explicit IndexType, similar to enumerate<IndexType>(...). Usage: iota_range<PhaseIndex>(0, num_phases)

template<typename T>
constexpr auto gtopt::iota_range(T first, T last) -> IotaRange< T >

Create an IotaRange [first, last) with deduced type.

constexpr auto gtopt::is_compatible_double_type(arrow::Type::type type_id) -> bool

Check if an Arrow type is a compatible floating-point type that can be cast to double.

Parameters
type_id The Arrow type id to check
Returns true if the type is float or double

constexpr auto gtopt::is_compatible_int32_type(arrow::Type::type type_id) -> bool

Check if an Arrow type is a compatible integer type that can be cast to int32.

Parameters
type_id The Arrow type id to check
Returns true if the type is int8, int16, int32, or int64

auto gtopt::load_boundary_cuts_csv(PlanningLP& planning_lp, const std::string& filepath, const SDDPOptions& options, const LabelMaker& label_maker, StrongIndexVector<SceneIndex, StrongIndexVector<PhaseIndex, PhaseStateInfo>>& scene_phase_states) -> std::expected< CutLoadResult, Error >

Parameters
planning_lp The PlanningLP to add cuts to
filepath Input CSV file path
options SDDP options (boundary mode, max iters)
label_maker Label maker for LP row names
scene_phase_states Per-scene phase state (for alpha columns)
Returns CutLoadResult with count and max iteration, or an error

Load boundary (future-cost) cuts from a named-variable CSV file.

The CSV header names the state variables (e.g. reservoir or battery names); subsequent rows provide {name, [iteration,] scene, rhs, coefficients}. Cuts are added only to the last phase, with an alpha column created if needed. Analogous to PLP's "planos de embalse".

auto gtopt::load_cuts_csv(PlanningLP& planning_lp, const std::string& filepath, const LabelMaker& label_maker) -> std::expected< CutLoadResult, Error >

Parameters
planning_lp The PlanningLP to add cuts to
filepath Input CSV file path
label_maker Label maker for LP row names
Returns CutLoadResult with count and max iteration, or an error

Load cuts from a CSV file and add to all scenes' phase LPs.

Cuts are broadcast to all scenes regardless of originating scene, since loaded cuts serve as warm-start approximations for the entire problem (analogous to PLP's cut sharing across scenarios).

MainOptions gtopt::load_gtopt_config()

Load a MainOptions from the [gtopt] section of .gtopt.conf.

Returns MainOptions with fields populated from the config file. Fields not present in the config file remain as nullopt.

Reads the config file found by find_config_file() and extracts values from the [gtopt] section. Keys use kebab-case matching the CLI flag names (e.g. output-format, sddp-max-iterations).

auto gtopt::load_named_cuts_csv(PlanningLP& planning_lp, const std::string& filepath, const SDDPOptions& options, const LabelMaker& label_maker, StrongIndexVector<SceneIndex, StrongIndexVector<PhaseIndex, PhaseStateInfo>>& scene_phase_states) -> std::expected< CutLoadResult, Error >

Parameters
planning_lp The PlanningLP to add cuts to
filepath Input CSV file path
options SDDP options (for alpha bounds)
label_maker Label maker for LP row names
scene_phase_states Per-scene phase state (for alpha columns)
Returns CutLoadResult with count and max iteration, or an error

Load named-variable cuts from a CSV file with a phase column.

Unlike boundary cuts (which load into the last phase only), these cuts include a phase column indicating which phase they belong to. The solver resolves named state-variable headers in each specified phase and adds the cuts to the corresponding phase LP.

auto gtopt::load_scene_cuts_from_directory(PlanningLP& planning_lp, const std::string& directory, const LabelMaker& label_maker) -> std::expected< CutLoadResult, Error >

Parameters
planning_lp The PlanningLP to add cuts to
directory Directory containing cut CSV files
label_maker Label maker for LP row names
Returns CutLoadResult with total count and max iteration, or an error

Load all per-scene cut files from a directory.

Files matching scene_<N>.csv and sddp_cuts.csv are loaded. Files with the error_ prefix (from infeasible scenes in a previous run) are skipped to prevent loading invalid cuts.

auto gtopt::load_state_csv(PlanningLP& planning_lp, const std::string& filepath) -> std::expected< void, Error >

Parameters
planning_lp The PlanningLP to inject warm solutions into
filepath Input CSV file path

Load state variable column solutions from a CSV file.

Reads the CSV and builds a warm column solution vector per (scene, phase) LinearInterface. After loading, physical_eini/physical_efin will use these warm values as fallback when the LP has not been solved yet.

void gtopt::log_diagnostic_lines(std::string_view level, std::string_view header, std::string_view diag)

Log a multi-line diagnostic string line-by-line via spdlog.

Parameters
level "error" → spdlog::error; any other value → spdlog::info.
header Description for the first line (e.g. the LP file path).
diag Multi-line diagnostic output to log line-by-line.

Each non-empty line is prefixed with the spdlog timestamp and level so that external-tool output (gtopt_check_lp, COIN-OR messages, etc.) is visually consistent with the rest of the log stream.

When the output exceeds kDiagMaxLines, only the last kDiagTailLines lines are printed to avoid flooding the log.

void gtopt::log_lp_stats_summary(const std::vector<ScenePhaseLPStats>& entries, double ratio_threshold = 1e7)

Log a summary of LP coefficient statistics.

Parameters
entries Per-scene/phase statistics.
ratio_threshold Ratio above which the detailed table is shown (default 1e7).

When the global coefficient ratio is below ratio_threshold a single summary line is emitted. Otherwise a per-scene/phase table is printed followed by the global aggregate.

template<typename Type, typename Map, typename FieldSched, typename... Uid>
constexpr auto gtopt::make_array_index(const SystemContext& system_context, std::string_view class_name, Map& array_table_map, const FieldSched& sched, const Id& id)

LpMatrixOptions gtopt::make_lp_matrix_options(const std::optional<LpNamesLevel>& lp_names_level, const std::optional<double>& matrix_eps, bool compute_stats = false, const std::optional<std::string>& lp_solver = {}, std::optional<LpEquilibrationMethod> equilibration_method = {})

Build LpMatrixOptions from command-line parameters.

Parameters
lp_names_level Optional LP naming level
matrix_eps Optional epsilon tolerance for matrix coefficients
compute_stats Whether to compute LP statistics (default false)
lp_solver Optional solver name to use
equilibration_method Optional equilibration method
Returns LpMatrixOptions configured according to the parameters

po::options_description gtopt::make_options_description()

Create the command-line options description for the gtopt application.

Returns po::options_description The options description containing all supported options

std::unique_ptr<PlanningMethod> gtopt::make_planning_method(const PlanningOptionsLP& options, size_t num_phases = 0)

Create a solver instance based on options.

Parameters
options The PlanningOptionsLP with all resolved SDDP configuration
num_phases Number of phases in the simulation (used to validate SDDP requirements; falls back to monolithic when < 2)
Returns Unique pointer to the selected solver

constexpr auto gtopt::make_sddp_task_key(IterationIndex iteration, SDDPPassDirection direction, PhaseIndex phase, SDDPTaskKind kind) noexcept -> SDDPTaskKey

Build an SDDPTaskKey from strongly-typed SDDP parameters.

Parameters
iteration SDDP iteration index
direction Forward or backward pass
phase Phase index within the iteration
kind LP solve or non-LP task

Centralises the int conversions in one place so that callers never need static_cast<int> when constructing task keys.

std::unique_ptr<SDDPWorkPool> gtopt::make_sddp_work_pool(double cpu_factor = 1.25)

Create and start an SDDPWorkPool configured for the SDDP solver.

Parameters
cpu_factor Over-commit factor applied to hardware_concurrency. Default 1.25.
Returns A started SDDPWorkPool (heap-allocated, non-movable).

Uses SDDPTaskKey (tuple) as the secondary priority key so that the SDDP forward/backward LP solves are ordered by (iteration, is_backward, phase, is_nonlp) with the default std::less<SDDPTaskKey> comparator (smaller tuple → higher priority).

std::unique_ptr<AdaptiveWorkPool> gtopt::make_solver_work_pool(double cpu_factor = 1.25)

Create and start an AdaptiveWorkPool configured for solver use.

Parameters
cpu_factor Over-commit factor applied to hardware_concurrency. Default 1.25 (25 % more threads than physical cores).
Returns A started AdaptiveWorkPool (heap-allocated, non-movable).

Both MonolithicMethod and SDDPMethod (auxiliary pool) use this factory.

template<typename Map, typename Iterator>
void gtopt::map_insert_sorted_unique(Map& map, Iterator first, Iterator last)

Insert from a pre-sorted, deduplicated range [first, last) using the most efficient API for each backend.

The range must be sorted in ascending key order and must contain no duplicate keys. For std::flat_map and boost::container::flat_map, violating this precondition is undefined behaviour. For std::map it is defined (first-seen key wins) but the deduplication is still recommended for consistency.

Backend behaviour:

  • std::flat_map : insert(std::sorted_unique, first, last) — O(n) bulk insert that skips per-element comparisons.
  • boost::flat_map: insert(ordered_unique_range, first, last) — same semantics using the Boost equivalent tag.
  • std::map : insert(first, last) — O(n log n) sequential insert; duplicate keys take the first-seen value.

template<typename Map, typename Size>
void gtopt::map_reserve(Map& map, Size n)

Reserve capacity in a flat_map for n elements.

For std::flat_map, extracts the underlying key/value containers, reserves capacity in both, then re-inserts them via replace(). For boost::container::flat_map, delegates to map.reserve(n). For std::map, this is intentionally a no-op (std::map does not support reserve()).

Calling with n == 0 is a no-op for all backends to avoid unnecessary allocations.

template<typename T>
constexpr bool gtopt::merge(std::vector<T>& dest, std::vector<T>&& src) noexcept(…)

Efficiently merges two vectors using move semantics.

Template parameters
T Type of elements (must be move-constructible)
Parameters
dest Destination vector (will receive elements)
src Source vector (will be emptied)
Exceptions
Nothing (noexcept)

Appends elements from source vector to destination vector. After the operation, the source vector will be empty but in a valid state. Handles self-merge safely.

template<typename T>
constexpr bool gtopt::merge(std::vector<T>& dest, std::vector<T>& src) noexcept(…)

Overload for lvalue source vector (converts to rvalue reference)

void gtopt::merge_config_defaults(MainOptions& opts, const MainOptions& defaults)

Merge config-file defaults into a MainOptions struct.

Parameters
opts The primary options (typically from CLI parsing).
defaults The fallback options (typically from config file).

For each field in opts that is not set (nullopt / empty), copies the value from defaults. CLI-set fields are never overwritten.

template<typename OptA, typename OptB>
constexpr auto& gtopt::merge_opt(OptA& a, OptB&& b) noexcept(…)

Merges two optionals, keeping value if source has value.

Template parameters
OptA Destination optional type
OptB Source optional type
Parameters
a Destination optional (modified in place)
b Source optional (rvalue reference)
Returns Reference to modified destination optional
Exceptions
Nothing (noexcept)

If source optional (b) has value, assigns it to destination (a). Otherwise leaves destination unchanged.

auto gtopt::parquet_read_table(const std::filesystem::path& fpath) -> std::expected< ArrowTable, std::string >

Read an Arrow table from a Parquet file.

Returns an error string on failure.

CutSharingMode gtopt::parse_cut_sharing_mode(std::string_view name)

Parse a cut-sharing mode from a string (backward-compatible wrapper). ("none", "expected", "accumulate", "max")

ElasticFilterMode gtopt::parse_elastic_filter_mode(std::string_view name)

Parse an elastic filter mode from a string (backward-compatible wrapper). Accepts "single_cut" / "cut" (= single_cut), "multi_cut", "backpropagate".

IniData gtopt::parse_ini_file(const std::filesystem::path& path)

Parse a simple INI file.

Parameters
path Path to the INI file.
Returns Parsed sections, or empty if the file cannot be opened.

Handles [section] headers, key = value pairs, # and ; comments, and blank lines. Keys are trimmed; values are trimmed. Keys outside any section are placed under the empty-string section.

int gtopt::parse_lp_algorithm(const std::string& s)

Parse an LP algorithm value from a string (name or integer).

Parameters
s The string to parse.
Returns The corresponding integer value for the algorithm.
Exceptions
cli::parse_error on unrecognised input.

Accepts either a numeric string ("0"–"3") or a case-sensitive algorithm name ("default", "primal", "dual", "barrier"). The name lookup is driven by lp_algo_entries – the same compile-time table used for logging – so the two are always in sync. With C++26 P2996 static reflection that table would itself be generated automatically from the LPAlgo enum, making this function fully reflection-driven.

LpNamesLevel gtopt::parse_lp_names_level(const std::string& s)

Parse an LP names level from a string (name or integer).

Parameters
s The string to parse.
Returns The corresponding LpNamesLevel value.
Exceptions
cli::parse_error on unrecognised input.

Accepts "0"–"2" or "minimal"/"only_cols"/"cols_and_rows".

MainOptions gtopt::parse_main_options(const po::variables_map& vm, std::vector<std::string> system_files)

Build a MainOptions struct from a parsed CLI variables_map.

Parameters
vm Parsed CLI variables map (from po::store/ponotify)
system_files Positional system-file arguments
Returns Fully populated MainOptions

Extracts every gtopt_main option from vm into a MainOptions value. system_files is taken from the positional arguments already pulled out by the caller (they are not stored in vm by default).

std::string gtopt::probe_parquet_codec(std::string_view requested)

Probe the Arrow/Parquet runtime to determine the best available codec for the requested name. Uses arrow::util::Codec::IsAvailable() — the correct runtime check — rather than parquet::IsCodecSupported(), which only validates the enum value and does not detect codecs that were absent when the Arrow library was compiled.

Falls back (with a WARN log) to "gzip", then to "" (uncompressed) when the requested codec is unavailable.

Call once at program startup (e.g. in gtopt_main() after loading options) and store the result in planning.options.output_compression so that every downstream write uses the same pre-validated codec without re-probing on each file.

void gtopt::propagate_trial_values(std::span<StateVarLink> links, std::span<const double> source_solution, LinearInterface& target_li) noexcept

Propagate trial values: fix dependent columns to source-column solution via column bounds (lo == hi). Used in reduced_cost mode.

void gtopt::propagate_trial_values_row_dual(std::span<StateVarLink> links, std::span<const double> source_solution, LinearInterface& target_li) noexcept

Propagate trial values using explicit coupling constraint rows (PLP-style).

Instead of fixing dependent columns via bounds, this function:

  1. Keeps the dependent column at its physical bounds (source_low..source_upp)
  2. Adds an explicit equality constraint: x_dep = trial_value
  3. Stores the constraint's row index in link.coupling_row

The row duals of these coupling constraints are then used by build_benders_cut_from_row_duals() to construct the Benders cut.

template<typename Element, typename SystemContext SystemContext, typename E>
auto gtopt::push_back(SystemContext& sc, E&& element)

Free function to add a new element to the system.

Parameters
sc The system context.
element The element to add.
Returns The ElementIndex of the newly added element.

RelaxedVarInfo gtopt::relax_fixed_state_variable(LinearInterface& li, const StateVarLink& link, PhaseIndex phase, double penalty)

Relax a single fixed state-variable column to its physical source bounds, adding penalised slack variables. Returns a RelaxedVarInfo with the relaxation status and slack column indices. Converts to bool (true iff relaxed) for backward compatibility.

bool gtopt::rescale_benders_cut(SparseRow& row, ColIndex alpha_col, double cut_coeff_max)

Parameters
row The cut row to rescale in-place
alpha_col α column index (to identify it for logging)
cut_coeff_max Maximum allowed absolute coefficient value (> 0)
Returns true if the row was rescaled, false if no rescaling was needed

Rescale a Benders cut row when the largest state-variable coefficient exceeds cut_coeff_max.

All terms (coefficients, α weight, and RHS) are divided uniformly by max_coeff / cut_coeff_max, preserving the constraint's feasible set. The α column at alpha_col is included in the scaling.

std::expected<MainOptions, std::string> gtopt::resolve_planning_args(MainOptions opts)

Resolve planning file arguments and directory context.

Parameters
opts A copy of the original MainOptions (modified in place).
Returns The resolved MainOptions, or an error string.

See the file-level documentation for the three features implemented.

std::optional<ResolvedCol> gtopt::resolve_single_col(const SystemContext& sc, const ScenarioLP& scenario, const StageLP& stage, const BlockLP& block, const ElementRef& ref, const LinearProblem& lp)

Try to look up the LP ColIndex for one element reference.

Returns std::nullopt when the element is not found, the block is not active in the requested (scenario, stage), or the attribute is unknown.

The returned ResolvedCol::scale converts the LP variable to physical units so that the caller can build correctly-scaled constraint rows.

When a column has a non-unit scale stored in SparseCol::scale (set at variable creation time), the scale is retrieved via lp.get_col_scale(col) – providing a uniform mechanism that works for all current and future scaled variables without hardcoding per-element logic.

std::optional<double> gtopt::resolve_single_param(const SystemContext& sc, const ScenarioLP& scenario, const StageLP& stage, const BlockLP& block, const ElementRef& ref)

Try to look up a data parameter value for one element reference.

Returns std::nullopt when the element is not found or the attribute is not a known parameter. Parameters are fixed data values (not LP columns) such as pmax, gcost, fmax, emin, etc.

For schedule-valued parameters the value is resolved for the given (scenario, stage, block) context. If the schedule has no value for the given context, std::nullopt is returned.

std::string gtopt::run_check_json_info(const std::vector<std::string>& json_files, int timeout_seconds = 30)

Run gtopt_check_json --info on one or more JSON files and return the captured output.

Parameters
json_files List of planning JSON file stems/paths.
timeout_seconds Maximum execution time in seconds (default: 30).
Returns Captured output, or an empty string if the tool is unavailable.

Searches PATH for the gtopt_check_json binary. If found, spawns it directly (without invoking a shell) via posix_spawn with:

gtopt_check_json --info --no-color <file1.json> [<file2.json> ...]

stdout and stderr are captured and returned as a string so the caller can forward every line through the spdlog INFO stream (instead of writing directly to the terminal). An optional timeout wrapper prevents indefinite hangs.

std::string gtopt::run_check_lp_diagnostic(const std::string& lp_file, int timeout_seconds = 10, const SolverOptions& solver_opts = {})

Run gtopt_check_lp on an LP file and return the diagnostic output.

Parameters
lp_file Full path to the LP file (may include or omit the .lp extension).
timeout_seconds Maximum execution time in seconds (default: 10).
solver_opts Solver options to forward to gtopt_check_lp so the diagnostic replicates the same algorithm and tolerance settings used by gtopt. Default-constructs to algorithm=barrier with no tolerance overrides.
Returns Captured diagnostic output, or an empty string if unavailable.

Searches PATH for the gtopt_check_lp binary. If found, spawns it directly (without invoking a shell) via posix_spawn with:

gtopt_check_lp --quiet --no-color --no-ai --timeout <timeout_seconds>
                [--algo <algo>]
                [--optimal-eps <v>] [--feasible-eps <v>]
                [--barrier-eps <v>]
                <lp_file>

If the binary is not on PATH or the file does not exist, an empty string is returned so callers can skip logging silently.

The --quiet flag ensures the child process never stalls waiting for input and always exits with code 0, even when no solver is available or NEOS is unreachable.

SolverTestReport gtopt::run_solver_tests(std::string_view solver_name, bool verbose = false)

Run the full LinearInterface test suite against solver_name.

Parameters
solver_name Solver identifier understood by SolverRegistry (e.g. "clp", "cbc", "highs").
verbose When true, print each test name as it executes to stdout (useful when running from a terminal).
Returns Aggregated pass/fail for all test cases.

The test suite covers:

  • construction (default, by-name, from FlatLinearProblem)
  • problem-name get/set
  • add_col / add_free_col / add_row / delete_rows
  • set/get objective coefficients, column bounds, row bounds
  • get_coeff / set_coeff (skipped when !supports_set_coeff())
  • set_continuous / set_integer / is_continuous / is_integer
  • lp_names_level and name maps (row_name_map, col_name_map)
  • load_flat from FlatLinearProblem
  • initial_solve with all LPAlgo variants (default, primal, dual, barrier)
  • get_obj_value / get_col_sol / get_row_dual / get_col_cost
  • is_optimal / is_prim_infeasible / is_dual_infeasible
  • get_kappa
  • resolve (warm re-solve after bound tightening)
  • clone (deep copy; independent solve)
  • set_warm_start_solution
  • save_base_numrows / reset_from
  • lp_stats_* fields after load_flat
  • write_lp (creates a temp file and verifies creation)

auto gtopt::save_cuts_csv(std::span<const StoredCut> cuts, const PlanningLP& planning_lp, const std::string& filepath, bool append_mode = false) -> std::expected< void, Error >

Parameters
cuts All stored cuts to save
planning_lp The PlanningLP (for scale and column names)
filepath Output CSV file path
append_mode When true, append rows without header (file must already exist with correct header)

Save accumulated cuts to a CSV file for hot-start.

Both RHS and coefficients are stored in fully physical space so that cuts are portable across runs with different scale_objective or variable scaling configurations.

auto gtopt::save_scene_cuts_csv(std::span<const StoredCut> cuts, SceneIndex scene, int scene_uid_val, const PlanningLP& planning_lp, const std::string& directory) -> std::expected< void, Error >

Parameters
cuts The scene's stored cuts
scene Scene index (for column name lookup)
scene_uid_val Scene UID value (for file naming)
planning_lp The PlanningLP (for scale and column names)
directory Output directory (file: scene_<UID>.csv)

Save cuts for a single scene to a per-scene CSV file.

auto gtopt::save_state_csv(const PlanningLP& planning_lp, const std::string& filepath, IterationIndex iteration) -> std::expected< void, Error >

Parameters
planning_lp The PlanningLP (for LP access and scaling)
filepath Output CSV file path
iteration Current iteration index (written as comment)

Save state variable column solutions and reduced costs to a CSV file.

Writes one row per state-variable column (efin, eini, sini, etc.) with name, phase UID, scene UID, LP value (in physical units), and reduced cost. The file is self-describing via column names, so it is portable across LP structure changes.

auto gtopt::select_rdl_coeffs(const std::vector<ReservoirDischargeLimitSegment>& segments, Real volume) noexcept -> ReservoirDischargeLimitCoeffs

Select the active segment and return LP coefficients.

auto gtopt::select_seepage_coeffs(const std::vector<ReservoirSeepageSegment>& segments, Real volume) noexcept -> ReservoirSeepageCoeffs

Select the active seepage segment and return LP coefficients.

Parameters
segments The piecewise-linear segments (sorted by volume breakpoint)
volume Current reservoir volume [hm³]
Returns ReservoirSeepageCoeffs with slope and intercept (y-intercept) for the active segment

Implements the PLP range-selection logic (matches Fortran FFiltracionesi): finds the segment i where segments[i].volume ≤ volume < segments[i+1].volume and returns its slope and constant (y-intercept) as LP coefficients.

The LP constraint becomes: filt_flow - slope*0.5*eini - slope*0.5*efin = constant where constant is the y-intercept at V = 0 for the active segment's linear equation: seepage = constant + slope × V.

void gtopt::share_cuts_for_phase(PhaseIndex phase, const StrongIndexVector<SceneIndex, std::vector<SparseRow>>& scene_cuts, CutSharingMode mode, PlanningLP& planning, std::string_view label_prefix = {})

Parameters
phase Phase index where cuts will be added
scene_cuts Per-scene optimality cuts for this phase
mode Cut sharing mode (none/accumulate/expected/max)
planning PlanningLP reference (for LP access)
label_prefix Label prefix for generated cuts (empty = no labels)

Share optimality cuts across scenes for a single phase.

auto gtopt::solve_apertures_for_phase(SceneIndex scene, PhaseIndex phase, const PhaseStateInfo& src_state, const ScenarioLP& base_scenario, std::span<const ScenarioLP> all_scenarios, std::span<const Aperture> aperture_defs, std::span<const Uid> phase_apertures, int total_cuts, SystemLP& sys, const PhaseLP& phase_lp, const SolverOptions& opts, const LabelMaker& label_maker, const std::string& log_directory, SceneUid scene_uid, PhaseUid phase_uid, const ApertureSubmitFunc& submit_fn, double aperture_timeout = 0.0, bool save_aperture_lp = false, const ApertureDataCache& aperture_cache = {}, std::span<const double> forward_col_sol = {}, std::span<const double> forward_row_dual = {}, LinearInterface* pooled_clone = nullptr, IterationIndex iteration = {}, CutCoeffMode cut_coeff_mode = CutCoeffMode::reduced_cost, double scale_alpha = 1.0, double cut_coeff_eps = 0.0, double cut_coeff_max = 0.0) -> std::optional< SparseRow >

Parameters
scene Scene index (for logging/labelling)
phase Target phase being solved
src_state Phase state of the source (previous) phase
base_scenario The scene's base scenario (for flow bound update)
all_scenarios All simulation scenarios (for aperture lookup)
aperture_defs Aperture definitions to use
phase_apertures Per-phase aperture UID set (may be empty)
total_cuts Running cut count (for label uniqueness)
sys SystemLP for the (scene, phase) pair
phase_lp PhaseLP for the target phase
opts Solver options
label_maker Label maker for LP row names
log_directory Directory for debug LP files (empty = no save)
scene_uid Scene UID (for logging)
phase_uid Phase UID (for logging)
submit_fn Callback to submit an aperture task to the work pool
aperture_timeout Timeout in seconds for each aperture LP solve; 0 = no timeout. When exceeded, the aperture is treated as infeasible and skipped.
save_aperture_lp If true, save each aperture LP to the log directory
aperture_cache Cache of pre-built aperture LP data
forward_col_sol Forward-pass primal solution (warm-start hint for aperture clones). Applied after update_aperture.
forward_row_dual Forward-pass dual solution (warm-start hint for aperture clones). Applied after update_aperture.
pooled_clone Optional pre-allocated LP clone from a work pool
iteration Current SDDP iteration index
cut_coeff_mode Mode for computing cut coefficients
scale_alpha Scaling factor applied to the cut alpha (RHS)
cut_coeff_eps Epsilon below which cut coefficients are zeroed
cut_coeff_max Maximum absolute cut coefficient (0 = no limit)

Solve all apertures for a single phase and return the expected cut.

For each effective aperture: clones the phase LP, updates flow column bounds to the aperture's source scenario, solves the clone, and builds a Benders cut from the reduced costs. The probability-weighted average of all feasible aperture cuts is returned as the expected cut.

Returns std::nullopt if all apertures are infeasible or skipped.

void gtopt::strip_cr(std::string& s) noexcept

Strip trailing carriage-return left by std::getline on DOS text files.

template<std::ranges::range Range, typename Transform = decltype([](const auto& x) { return x; }), typename RRef = decltype(*std::ranges::begin(std::declval<Range>()))>
auto gtopt::to_vector(Range&& range, Transform&& transform = {})

Converts range to vector, optionally transforming elements.

Template parameters
Range Input range type
Transform Unary transform operation (defaults to identity)
RRef
Parameters
range Input range
transform Transform operation (optional)
Returns std::vector containing transformed elements

auto gtopt::try_read_table(const std::filesystem::path& fpath, std::string_view format) -> std::expected< ArrowTable, std::string >

Try to read a table, preferring format and falling back to the other format on failure.

Parameters
fpath Path without extension.
format Preferred format: "parquet" or anything else (CSV).
Returns Loaded table or an error description.

ValidationResult gtopt::validate_planning(Planning& planning)

Validate a Planning object for semantic correctness.

Parameters
planning The parsed and merged Planning object (may be mutated if probability rescaling is enabled)
Returns ValidationResult with all errors and warnings

Checks performed:

  1. Referential integrity: cross-references between components (generator.bus, demand.bus, line.bus_a/bus_b, turbine.waterway, turbine.generator, flow.junction, waterway.junction_a/junction_b, converter.battery/generator/demand, reservoir.junction)
  2. Range checks: block duration > 0, stage count_block > 0, generator capacity non-negative
  3. Completeness: at least one bus, block, and stage
  4. Probability checks: scenario probability_factor values per scene should sum to 1.0; controlled by probability_check option.

All issues are collected (not short-circuited) so the user sees every problem in a single run.

When probability_check is rescale (default), probabilities that do not sum to 1.0 are normalized in-place (hence the non-const reference).

template<typename Collections, typename Op, typename... Args>
constexpr auto gtopt::visit_elements(Collections&& collections, Op op, Args && ... args)

Parameters
collections Tuple of collections to visit
op Operation to apply to each element
args Additional arguments to forward to the operation
Returns Count of successful operations

Visits each element in multiple collections and applies an operation to them. Uses perfect forwarding throughout to minimize copies and maximize performance.

This function is marked noexcept to enable compiler plannings and provide stronger exception safety guarantees.

void gtopt::warn_deprecated_cli(const std::optional<bool>& opt, std::string_view cli_flag, std::string_view set_path)

Specialisation for bool (prints true/false instead of 1/0).

void gtopt::warn_deprecated_cli(const std::optional<std::string>& opt, std::string_view cli_flag, std::string_view set_path)

Overload for string options — no conversion needed.

template<typename T>
void gtopt::warn_deprecated_cli(const std::optional<T>& opt, std::string_view cli_flag, std::string_view set_path)

Emit a deprecation warning for a CLI option replaceable by –set.

Parameters
opt The optional value to check (warning only if it has a value)
cli_flag The deprecated CLI flag name
set_path The –set key path that replaces it

auto gtopt::weighted_average_benders_cut(const std::vector<SparseRow>& cuts, const std::vector<double>& weights, std::string_view name) -> SparseRow

Parameters
cuts Collection of Benders optimality cuts (SparseRow)
weights Per-cut probability weights (must be same size as cuts)
name Name for the resulting averaged cut row

Compute a probability-weighted average cut from a collection of cuts.

Each cut is weighted by the corresponding element in weights. The weights are normalised internally so they need not sum to 1. If all weights are zero the function returns an empty SparseRow.

void gtopt::write_sddp_api_status(const std::string& filepath, const std::vector<SDDPIterationResult>& results, double elapsed_seconds, const SDDPStatusSnapshot& snapshot, const SolverMonitor& monitor)

Parameters
filepath Output JSON file path
results Vector of per-iteration results
elapsed_seconds Total elapsed time since solve() started
snapshot Current solver state snapshot
monitor SolverMonitor for real-time workpool stats

Write SDDP status JSON to a file.

Builds a JSON string with the solver's current state, per-iteration history, and real-time workpool statistics, then writes it atomically (via SolverMonitor::write_status()).

std::string gtopt::gzip_lp_file_inline(const std::string& src_path)

Inline gzip compression via zlib. Returns .gz path or empty on failure.

std::string gtopt::zstd_lp_file_inline(const std::string& src_path)

Inline zstd compression via libzstd. Returns .zst path or empty on failure.

std::string gtopt::compress_lp_file(const std::string& src_path, const std::string& lp_compression = {})

Parameters
src_path Path to the source file to compress.
lp_compression "none", "", "gzip", "zstd", "lz4", "bzip2", "xz"

Compress a file using the named codec or auto-cascade.

Variable documentation

constexpr auto gtopt::active_fnc

Predicate that checks if element has is_active() member returning true.

constexpr double gtopt::days_per_year

Days in a standard year (non-leap)

constexpr double gtopt::DblMax

Maximum representable double value used for unbounded variable bounds.

constexpr auto gtopt::elastic_filter_mode_entries

Includes "cut" as a backward-compatible alias for "single_cut".

constexpr IntBool gtopt::False

False value for integer boolean.

constexpr auto gtopt::has_value_fnc

Predicate that checks if element exists (not nullopt)

constexpr double gtopt::hours_per_day

Hours in a standard day.

constexpr double gtopt::hours_per_year

Hours in a standard year.

constexpr auto gtopt::is_true_fnc

Predicate that checks if optional has value and value is true (C++23 value_or)

constexpr int gtopt::k_solver_abi_version

ABI version for the SolverBackend plugin interface.

Bump this integer every time the SolverBackend vtable changes (new virtual methods, reordered methods, changed signatures, etc.). SolverRegistry checks the plugin's reported ABI version at load time and rejects incompatible plugins with a clear error instead of crashing.

constexpr int gtopt::kDiagMaxLines

Maximum number of diagnostic output lines before truncation. When diagnostic output exceeds this limit, only the last kDiagTailLines lines are shown to avoid flooding the log.

constexpr int gtopt::kDiagTailLines

Number of trailing lines to keep when truncating diagnostic output.

constexpr int gtopt::kZstdCompressionLevel

Zstd compression level: 3 is the library default, offering a good balance between speed and ratio for LP debug files.

constexpr auto gtopt::lp_algo_entries

Compile-time table mapping each LPAlgo enumerator to its name.

Excludes the sentinel last_algo value.

constexpr std::size_t gtopt::lp_type_count_v

Total number of LP element types.

template<typename T>
constexpr std::size_t gtopt::lp_type_index_v

Compile-time index of LP element type T in lp_element_types_t.

Used by SystemContext::get_element<T> to locate the Collection<T> pointer in the m_collection_ptrs_ array without including system_lp.hpp.

Example: lp_type_index_v<BatteryLP> evaluates to 6 (0-based).

constexpr IntBool gtopt::True

True value for integer boolean.

constexpr auto gtopt::true_fnc

Predicate that always returns true.