Skip to content

Commit

Permalink
Remove hydro hotstart (#2131)
Browse files Browse the repository at this point in the history
AntaresSimulatorTeam/Antares_Simulator_Tests_NR#24

Previously, the default value for property `initial-reservoir-levels`
was `cold start`.

---------

Co-authored-by: Guillaume PIERRE <[email protected]>
Co-authored-by: Florian OMNES <[email protected]>
  • Loading branch information
3 people authored Jun 17, 2024
1 parent be3301c commit 6edcad8
Show file tree
Hide file tree
Showing 25 changed files with 46 additions and 407 deletions.
3 changes: 1 addition & 2 deletions docs/user-guide/solver/04-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,7 @@ _**This section is under construction**_
These parameters are listed under the `[other preferences]` section in the `.ini` file.

---
#### initial-reservoir-levels
[//]: # (TODO: complete the usage paragraph)
#### initial-reservoir-levels (DEPRECATED since 9.2: cold start is default behavior)
- **Expected value:** one of the following (case-insensitive):
- `cold start`
- `hot start`
Expand Down
2 changes: 1 addition & 1 deletion docs/user-guide/solver/06-hydro-heuristics.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,6 @@ $$V_t^- + S_t \geq \underline{S_t}$$

$$Y - V_t^- \geq 0$$

[^monthly_allocation]: In the first equation, $S_{t-1}$ is either the initial stock $S_0$ or the final stock of the previous year (hydro hot start)
[^monthly_allocation]: In the first equation, $S_{t-1}$ is equal to initial stock $S_0$

[^daily_allocation]: In the first equation, $S_{t-1}$ is either the initial stock used in M or the final stock of the previous month ($D(m-1)$)
6 changes: 3 additions & 3 deletions docs/user-guide/solver/09-appendix.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ With `..._MPS` options, the full expression of the faulty problem(s) is printed
thus allowing further analysis of the infeasibility issue.


## Details on the "initial-reservoir-levels" parameter
[//]: # (TODO: update this paragraph)
_**This section is under construction**_
## Details on the "initial-reservoir-levels" parameter (DEPRECATED since 9.2)

### version 9.2: The reservoir level is now always determined with cold start behavior.

This parameter can take the two values "cold start" or "hot start". [default: cold start]. Simulations results may in some circumstances be heavily impacted by this setting, hence proper attention should be paid to its meaning before considering changing the default value.

Expand Down
2 changes: 1 addition & 1 deletion simtest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "v9.1.0-rc5"
"version": "v9.2.0a"
}
37 changes: 0 additions & 37 deletions src/libs/antares/study/fwd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,43 +91,6 @@ const char* SeedToID(SeedIndex seed)
return "";
}

// ... Initial reservoir levels ...
InitialReservoirLevels StringToInitialReservoirLevels(const AnyString& text)
{
if (!text)
{
return irlUnknown;
}

CString<24, false> s = text;
s.trim();
s.toLower();
if (s == "cold start")
{
return irlColdStart;
}
if (s == "hot start")
{
return irlHotStart;
}

return irlUnknown;
}

const char* InitialReservoirLevelsToCString(InitialReservoirLevels iniLevels)
{
switch (iniLevels)
{
case irlColdStart:
return "cold start";
case irlHotStart:
return "hot start";
case irlUnknown:
return "";
}
return "";
}

// ... Hydro heuristic policy ...
HydroHeuristicPolicy StringToHydroHeuristicPolicy(const AnyString& text)
{
Expand Down
18 changes: 0 additions & 18 deletions src/libs/antares/study/include/antares/study/fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,24 +382,6 @@ const char* SeedToCString(SeedIndex seed);
*/
const char* SeedToID(SeedIndex seed);

// ... Initial reservoir levels ...
enum InitialReservoirLevels
{
irlColdStart = 0,
irlHotStart,
irlUnknown,
};

/*!
** \brief Convert an Initial Reservoir Levels strategy into a text
*/
const char* InitialReservoirLevelsToCString(InitialReservoirLevels iniLevels);

/*!
** \brief Convert a text into an Initial Reservoir Levels strategy
*/
InitialReservoirLevels StringToInitialReservoirLevels(const AnyString& text);

// ... Hydro heuristic policy ...
enum HydroHeuristicPolicy
{
Expand Down
11 changes: 0 additions & 11 deletions src/libs/antares/study/include/antares/study/parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,12 +463,6 @@ class Parameters final

RenewableGeneration renewableGeneration;

struct
{
//! Initial reservoir levels
InitialReservoirLevels iniLevels;
} initialReservoirLevels;

struct
{
//! Hydro heuristic policy
Expand All @@ -481,11 +475,6 @@ class Parameters final
HydroPricingMode hpMode;
} hydroPricing;

// In case of hydro hot start and MC years simultaneous run
// ... Answers the question : do all sets of simultaneous years have the same size ?
// (obvious if the parallel mode is not required : answer is yes).
bool allSetsHaveSameSize;

//! Transmission capacities
GlobalTransmissionCapacities transmissionCapacities;
//! Simplex optimization range (day/week)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,9 @@ class PartHydro
// As this function can be called a lot of times, we pass working variables and returned variables
// as arguments, so that we don't have to create them locally (as in a classical function) each
// time.
void getWaterValue(const double& level,
double getWaterValue(const double& level,
const Matrix<double>& waterValues,
const uint day,
double& waterValueToReturn);
const uint day);

// Interpolates a rate from the credit modulation table according to a level
double getWeeklyModulation(const double& level /* format : in % of reservoir capacity */,
Expand Down
16 changes: 0 additions & 16 deletions src/libs/antares/study/include/antares/study/study.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,22 +421,6 @@ class Study: public Yuni::NonCopyable<Study>, public LayerData
*/
void getNumberOfCores(const bool forceParallel, const uint nbYearsParallelForced);

/*!
** \brief In case hydro hot start is enabled, checking all conditions are met.
**
** If hydro hot start is enabled, check that :
** - For all areas for which reservoir management is enabled :
** + Their starting level is initialized on the same day
** + This day is the first day of the simulation calendar
** - The simulation lasts exactly one year
** - All batches (or sets) of simultaneous years have the same size (obvious if a parallel run
*is not required : answer is yes).
**
** If these conditions are not met, some error message is raised, when attempting to run the
*study.
*/
bool checkHydroHotStart();

/*!
** \brief Remove timeseries if ts-generator is enabled
*/
Expand Down
7 changes: 0 additions & 7 deletions src/libs/antares/study/load.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,6 @@ void Study::parameterFiller(const StudyLoadOptions& options)
parameters.firstMonthInYear,
parameters.leapYear});

// In case hydro hot start is enabled, check all conditions are met.
// (has to be called after areas load and calendar building)
if (usedByTheSolver && !checkHydroHotStart())
{
logs.error() << "hydro hot start is enabled, conditions are not met. Aborting";
}

// Reducing memory footprint
reduceMemoryUsage();
}
Expand Down
28 changes: 9 additions & 19 deletions src/libs/antares/study/parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,15 +311,11 @@ void Parameters::reset()
readonly = false;
synthesis = true;

// Initial reservoir levels
initialReservoirLevels.iniLevels = irlColdStart;

// Hydro heuristic policy
hydroHeuristicPolicy.hhPolicy = hhpAccommodateRuleCurves;

// Hydro pricing
hydroPricing.hpMode = hpHeuristic;
allSetsHaveSameSize = true;

// Shedding strategies
power.fluctuations = lssFreeModulations;
Expand Down Expand Up @@ -810,19 +806,6 @@ static bool SGDIntLoadFamily_OtherPreferences(Parameters& d,
d.hydroPricing.hpMode = hpHeuristic;
return false;
}
if (key == "initial-reservoir-levels")
{
auto iniLevels = StringToInitialReservoirLevels(value);
if (iniLevels != irlUnknown)
{
d.initialReservoirLevels.iniLevels = iniLevels;
return true;
}
logs.warning() << "parameters: invalid initital reservoir levels mode. Got '" << value
<< "'. reset to cold start mode.";
d.initialReservoirLevels.iniLevels = irlColdStart;
return false;
}

if (key == "number-of-cores-mode")
{
Expand Down Expand Up @@ -1155,6 +1138,15 @@ static bool SGDIntLoadFamily_Legacy(Parameters& d,
return true;
}

if (key == "initial-reservoir-levels") // ignored since 9.2
{
if (version >= StudyVersion(9,2))
logs.warning() << "Option initial-reservoir-levels is deprecated, please remove it from the study";
else if (value == "hot start")
logs.warning() << "Hydro hot start not supported with this solver, please use a version < 9.2";
return true;
}

return false;
}

Expand Down Expand Up @@ -1874,8 +1866,6 @@ void Parameters::saveToINI(IniFile& ini) const
// Other preferences
{
auto* section = ini.addSection("other preferences");
section->add("initial-reservoir-levels",
InitialReservoirLevelsToCString(initialReservoirLevels.iniLevels));
section->add("hydro-heuristic-policy",
HydroHeuristicPolicyToCString(hydroHeuristicPolicy.hhPolicy));
section->add("hydro-pricing-mode", HydroPricingModeToCString(hydroPricing.hpMode));
Expand Down
14 changes: 5 additions & 9 deletions src/libs/antares/study/parts/hydro/container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -938,24 +938,20 @@ bool PartHydro::CheckDailyMaxEnergy(const AnyString& areaName)
return ret;
}

void getWaterValue(const double& level /* format : in % of reservoir capacity */,
double getWaterValue(const double& level /* format : in % of reservoir capacity */,
const Matrix<double>& waterValues,
const uint day,
double& waterValueToReturn)
const uint day)
{
assert((level >= 0. && level <= 100.) && "getWaterValue function : invalid level");
double levelUp = ceil(level);
double levelDown = floor(level);

if ((int)(levelUp) == (int)(levelDown))
{
waterValueToReturn = waterValues[(int)(levelUp)][day];
}
else
{
waterValueToReturn = waterValues[(int)(levelUp)][day] * (level - levelDown)
+ waterValues[(int)(levelDown)][day] * (levelUp - level);
return waterValues[(int)(levelUp)][day];
}
return waterValues[(int)(levelUp)][day] * (level - levelDown)
+ waterValues[(int)(levelDown)][day] * (levelUp - level);
}

double getWeeklyModulation(const double& level /* format : in % of reservoir capacity */,
Expand Down
91 changes: 0 additions & 91 deletions src/libs/antares/study/study.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,97 +500,6 @@ void Study::getNumberOfCores(const bool forceParallel, const uint nbYearsParalle
// enabled.
// Useful for RAM estimation.
maxNbYearsInParallel_save = maxNbYearsInParallel;

// Here we answer the question (useful only if hydro hot start is asked) : do all sets of
// parallel years have the same size ?
if (parameters.initialReservoirLevels.iniLevels == Antares::Data::irlHotStart
&& setsOfParallelYears.size() && maxNbYearsInParallel > 1)
{
uint currentSetSize = (uint)setsOfParallelYears[0].size();
if (setsOfParallelYears.size() > 1)
{
for (uint s = 1; s < setsOfParallelYears.size(); s++)
{
if (setsOfParallelYears[s].size() != currentSetSize)
{
parameters.allSetsHaveSameSize = false;
break;
}
}
}
} // End if hot start
}

bool Study::checkHydroHotStart()
{
bool hydroHotStart = (parameters.initialReservoirLevels.iniLevels == irlHotStart);

// No need to check further if hydro hot start is not required
if (!hydroHotStart)
{
return true;
}

// Here we answer the question (useful only if hydro hot start is asked) : In case of parallel
// run, do all sets of parallel years have the same size ?
if (maxNbYearsInParallel != 1 && !parameters.allSetsHaveSameSize)
{
logs.error() << "Hot Start Hydro option : conflict with parallelization parameters.";
logs.error()
<< "Please update relevant simulation parameters or use Cold Start option. ";
return false;
}

// Checking calendar conditions
// ... The simulation lasts one year exactly
uint nbDaysInSimulation = parameters.simulationDays.end - parameters.simulationDays.first + 1;
if (nbDaysInSimulation < 364)
{
logs.error()
<< "Hot Start Hydro option : simulation calendar must cover one complete year. ";
logs.error() << "Please update data or use Cold Start option.";
return false;
}

// ... For all areas for which reservoir management is enabled :
// - Their starting level is initialized on the same day
// - This day is the first day of the simulation calendar
const Area::Map::iterator end = areas.end();
for (Area::Map::iterator i = areas.begin(); i != end; ++i)
{
// Reference to the area
Area* area = i->second;

// No need to make a check on level initialization when reservoir management
// is not activated for the current area
if (!area->hydro.reservoirManagement)
{
continue;
}

// Month the reservoir level is initialized according to.
// This month number is given in the civil calendar, from january to december (0 is
// january).
int initLevelOnMonth = area->hydro.initializeReservoirLevelDate;

// Conversion of the previous month into simulation calendar
uint initLevelOnSimMonth = calendar.mapping.months[initLevelOnMonth];

// Previous month's first day in the year
uint initLevelOnSimDay = calendar.months[initLevelOnSimMonth].daysYear.first;

// Check the day of level initialization is the first day of simulation
if (initLevelOnSimDay != parameters.simulationDays.first)
{
logs.error()
<< "Hot Start Hydro option : area '" << area->name
<< "' - hydro level must be initialized on the first simulation month. ";
logs.error() << "Please update data or use Cold Start option.";
return false;
}
} // End loop over areas

return true;
}

bool Study::initializeRuntimeInfos()
Expand Down
2 changes: 0 additions & 2 deletions src/solver/simulation/adequacy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,6 @@ bool Adequacy::year(Progression::Task& progression,
++progression;
}

updatingAnnualFinalHydroLevel(study.areas, currentProblem);

optWriter.finalize();
finalizeOptimizationStatistics(currentProblem, state);

Expand Down
Loading

0 comments on commit 6edcad8

Please sign in to comment.