Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove hydro hotstart [ANT-1815] #2131

Merged
merged 18 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions docs/user-guide/solver/04-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -587,20 +587,6 @@ _**This section is under construction**_
## Other parameters
These parameters are listed under the `[other preferences]` section in the `.ini` file.

---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we have to write somewhere that this option is deprecated

#### initial-reservoir-levels
[//]: # (TODO: complete the usage paragraph)
- **Expected value:** one of the following (case-insensitive):
- `cold start`
- `hot start`
- **Required:** no
- **Default value:** `cold start`
- **Usage:** initial reservoir levels:
- `cold start`
- `hot start`

> _**Note:**_ You can find more information on this parameter [here](09-appendix.md#details-on-the-initial-reservoir-levels-parameter).

---
#### hydro-heuristic-policy
[//]: # (TODO: complete the usage paragraph)
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 either initial stock $S_0$
payetvin marked this conversation as resolved.
Show resolved Hide resolved

[^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)$)
56 changes: 0 additions & 56 deletions docs/user-guide/solver/09-appendix.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,62 +63,6 @@ With `..._DRY` options, no specific data is printed regarding the faulty problem
With `..._MPS` options, the full expression of the faulty problem(s) is printed in the standard "MPS" format,
thus allowing further analysis of the infeasibility issue.


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

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.

**General:**

This parameter is meant to define the initial reservoir levels that should be used, in each system area, when processing
data related to the hydropower storage resources to consider in each specific Monte-Carlo year.

As a consequence, Areas which fall in either of the two following categories are not impacted by the value of the parameter:
- No hydro-storage capability installed
- Hydro-storage capability installed, but the "reservoir management" option is set to "False"

Areas that have some hydro-storage capability installed and for which explicit reservoir management is required are concerned by the parameter. The developments that follow concern only this category of Areas.

**Cold Start:**

On starting the simulation of a new Monte-Carlo year, the reservoir level to consider in each Area on the first day of
the initialization month is randomly drawn between the extreme levels defined for the Area on that day.

More precisely:

- The value is drawn according to the probability distribution function of a "Beta" random variable, whose four internal parameters are set so as to adopt the following behavior:
Lower bound: Minimum reservoir level.
Upper bound: Maximum reservoir level
Expectation: Average reservoir level
Standard Deviation: (1/3) (Upper bound-Lower bound)

- The random number generator used for that purpose works with a dedicated seed that ensures that results can be reproduced
[^17] from one run to another, regardless of the simulation runtime mode (sequential or parallel)
and regardless of the number of Monte-Carlo years to be simulated [^18].

**Hot Start:**

On starting the simulation of a new Monte-Carlo year, the reservoir level to consider in each Area on the first day of the initialization month is set to the value reached at the end of the previous simulated year, if three conditions are met:

- The simulation calendar is defined throughout the whole year, and the simulation starts on the day chosen for initializing the reservoir levels of all Areas.

- The Monte-Carlo year considered is not the first to simulate, or does not belong to the first batch of years to be simulated in parallel. In sequential runtime mode, that means that year #N may start with the level reached at the end of year #(N-1). In parallel runtime mode, if the simulation is carried out with batches of B years over as many CPU cores, years of the k-th batch
[^19] may start with the ending levels of the years processed in the (k-1)-th batch.

- The parallelization context (see [Multi-threading](optional-features/multi-threading.md)) must be set to ensure that the M Monte-Carlo years to simulate will be processed in a round number of K consecutive batches of B years in parallel (i.e. M = K\*B and all time-series refresh intervals are exact multiple of B).

The first year of the simulation, and more generally years belonging to the first simulation batch in parallel mode, are initialized as they would be in the cold start option.

**Note that:**

- _Depending on the hydro management options used, the amount of hydro-storage energy generated throughout the year may either match closely the overall amount of natural inflows of the same year, or differ to a lesser or greater extent. In the case of a close match, the ending reservoir level will be similar to the starting level. If the energy generated exceeds the inflows (either natural or pumped), the ending level will be lower than the starting level (and conversely, be higher if generation does not reach the inflow credit). Using the "hot start" option allows to take this phenomenon into account in a very realistic fashion, since the consequences of hydro decisions taken at any time have a decisive influence on the system's long term future._

- _When using the reservoir level "hot start" option, comparisons between different simulations make sense only if they rely on the exact same options, i.e. either sequential mode or parallel mode over the same number of CPU cores._

- _More generally, it has to be pointed out that the "hydro-storage" model implemented in Antares can be used to model "storable" resources quite different from actual hydro reserves: batteries, gas subterraneous stocks, etc._

## Details on the "hydro-heuristic-policy" parameter
[//]: # (TODO: update this paragraph)
_**This section is under construction**_
Expand Down
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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took advantage of the hydro hot start removal to make some quick and small cleanings.

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
22 changes: 3 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,9 @@ static bool SGDIntLoadFamily_Legacy(Parameters& d,
return true;
}

if (key == "initial-reservoir-levels") // ignored since 9.2
flomnes marked this conversation as resolved.
Show resolved Hide resolved
payetvin marked this conversation as resolved.
Show resolved Hide resolved
return true;

return false;
}

Expand Down Expand Up @@ -1874,8 +1860,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
Loading
Loading