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

Feature/ramping model scalian #2081

Draft
wants to merge 28 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a64625a
core implementation of the ramping model
bencamus Dec 5, 2023
b9c4f2b
add export/import features for the thermal ramping attributes
bencamus Dec 7, 2023
624f2ce
make the ramping constraints cyclical as the evolution of the product…
bencamus Dec 18, 2023
915e0c7
remove reference to Yuni in the ramping model code
bencamus Dec 18, 2023
f2d469e
removing of a useless header file
bencamus Dec 18, 2023
e78c034
improve readability of ramping model methods by naming their paramete…
bencamus Dec 18, 2023
b9801fe
add subclass to store and check thermal cluster ramping attributes
bencamus Dec 18, 2023
09a2ca9
Small code improvement for ramping
flomnes Dec 18, 2023
5ce4531
Solve build errors with a friend
flomnes Dec 19, 2023
77daa36
add the possibility to enable/disable the ramping model for each cluster
bencamus Dec 20, 2023
8133150
improvement of the implementation of the ON/OFF ramping model features
bencamus Dec 20, 2023
134ad57
merge commit
bencamus Dec 20, 2023
54ef194
add ramping costs to the output operational costs of the cluster
bencamus Jan 15, 2024
d8ca6aa
add dedicated output log for ramping costs
bencamus Jan 16, 2024
d1f983c
implementation of a new version of the ramping equations
bencamus Feb 29, 2024
70ba583
fixing a bug in the definition of the ramping variables bounds + free…
bencamus Mar 6, 2024
7387013
Supression of clusterRampingVariablesIndex and standardisation of the…
sylvmara Mar 7, 2024
ab1b701
Harmonisation of ramp checking
sylvmara Mar 7, 2024
8b6ce0b
merge with Antares master
bencamus Apr 12, 2024
3b17545
merge last version of ramping model with last version of Antares
bencamus Apr 12, 2024
50f7a48
removing ramping files that are useless with the last version of Antares
bencamus Apr 12, 2024
554455d
changing constraint equation related to power output variation of the…
bencamus Apr 16, 2024
3625bd2
Temporarily enable build for CentOS7
flomnes May 3, 2024
44f722d
changing the variable caption from RAMP COST by plant to RAMP COST BY…
bencamus May 15, 2024
e41d0b8
update the ramping constraint 18ter to remove breaking down thermal u…
bencamus Aug 26, 2024
34f2531
Merge remote-tracking branch 'origin/feature/ramping_model_scalian' i…
bencamus Aug 26, 2024
836be86
merge ramping branch with the develop one
bencamus Sep 25, 2024
c7016fa
remove some debug log for ramping
bencamus Sep 27, 2024
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
1 change: 1 addition & 0 deletions .github/workflows/centos7.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
types: [created]
push:
branches:
- feature/ramping_model_scalian
- develop
- dependabot/*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include <map>
#include <memory>
#include <vector>
#include <optional>


namespace Antares
{
Expand Down Expand Up @@ -339,6 +341,32 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this
double marketBidCost = 0;
//! Variable O&M cost (euros/MWh)
double variableomcost = 0;

struct Ramping
{
//! Cost of power increase (euros/MW)
double powerIncreaseCost;
//! Cost of power decrease (euros/MW)
double powerDecreaseCost;
//! Maximum hourly upward power ramping rate (MW/hour)
double maxUpwardPowerRampingRate;
//! Maximum hourly downward power ramping rate (MW/hour)
double maxDownwardPowerRampingRate;

Ramping() :
powerIncreaseCost(0.),
powerDecreaseCost(0.),
maxUpwardPowerRampingRate(0.),
maxDownwardPowerRampingRate(0.)
{
}

void reset();
bool checkValidity(Area* area, Data::ClusterName clusterName);
friend std::ostream& operator<<(std::ostream&, const Ramping& ramping);
};
std::optional<Ramping> ramping;

//@}

/*!
Expand Down
69 changes: 69 additions & 0 deletions src/libs/antares/study/parts/thermal/cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ void Data::ThermalCluster::copyFrom(const ThermalCluster& cluster)
minUpTime = cluster.minUpTime;
minDownTime = cluster.minDownTime;

// ramping
ramping = cluster.ramping;

// spinning
spinning = cluster.spinning;

Expand Down Expand Up @@ -447,6 +450,9 @@ void Data::ThermalCluster::reset()
marketBidCost = 0.;
variableomcost = 0.;
costsTimeSeries.resize(1, CostsTimeSeries());

// ramping
ramping.reset();

// modulation
modulation.resize(thermalModulationMax, HOURS_PER_YEAR);
Expand Down Expand Up @@ -576,6 +582,18 @@ bool Data::ThermalCluster::integrityCheck()
ret = false;
}*/

// ramping
if (ramping)
{
// if the ramping model is ill defined, then we disable the ramping model for this cluster
bool ramping_ret = ramping.value().checkValidity(parentArea, pName);
if(!ramping_ret)
{
ramping.reset();
}
ret = ramping_ret && ret;
}

return ret;
}

Expand Down Expand Up @@ -789,5 +807,56 @@ bool ThermalCluster::isActive() const {
return enabled && !mustrun;
}

void ThermalCluster::Ramping::reset()
{
powerIncreaseCost = 0;
powerDecreaseCost = 0;
maxUpwardPowerRampingRate = 0;
maxDownwardPowerRampingRate = 0;
}

bool ThermalCluster::Ramping::checkValidity(Area* parentArea, Data::ClusterName clusterName)
{
bool ret = true;

if (maxUpwardPowerRampingRate <= 0)
{
logs.error() << "Thermal cluster: " << parentArea->name << '/' << clusterName
<< ": The maximum upward power ramping rate must greater than zero."
<< "Ramping is disabled for this thermal cluster";
ret = false;
}
if (maxDownwardPowerRampingRate <= 0)
{
logs.error() << "Thermal cluster: " << parentArea->name << '/' << clusterName
<< ": The maximum downward power ramping rate must greater than zero."
<< "Ramping is disabled for this thermal cluster";
ret = false;
}
if (powerIncreaseCost < 0)
{
logs.error() << "Thermal cluster: " << parentArea->name << '/' << clusterName
<< ": The ramping power increase cost must be positive or null."
<< "Ramping is disabled for this thermal cluster";
ret = false;
}
if (powerDecreaseCost < 0)
{
logs.error() << "Thermal cluster: " << parentArea->name << '/' << clusterName
<< ": The ramping power decrease cost must be positive or null."
<< "Ramping is disabled for this thermal cluster";
ret = false;
}
return ret;
}

std::ostream& operator<<(std::ostream& os, const ThermalCluster::Ramping& r)
{
return os << r.powerIncreaseCost << '\t'
<< r.powerDecreaseCost << '\t'
<< r.maxUpwardPowerRampingRate << '\t'
<< r.maxDownwardPowerRampingRate;
}

} // namespace Data
} // namespace Antares
38 changes: 38 additions & 0 deletions src/libs/antares/study/parts/thermal/cluster_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,23 @@ static bool ThermalClusterLoadFromProperty(ThermalCluster& cluster, const IniFil
if (p->key == "startup-cost")
return p->value.to<double>(cluster.startupCost);

// initialize the ramping attributes only if ramping is enabled, else ignore these properties
if (p->key == "power-increase-cost")
return (cluster.ramping)? p->value.to<double>(cluster.ramping.value().powerIncreaseCost) : true;
if (p->key == "power-decrease-cost")
return (cluster.ramping) ? p->value.to<double>(cluster.ramping.value().powerDecreaseCost)
: true;
if (p->key == "max-upward-power-ramping-rate")
return (cluster.ramping)
? p->value.to<double>(cluster.ramping.value().maxUpwardPowerRampingRate)
: true;
if (p->key == "max-downward-power-ramping-rate")
return (cluster.ramping)
? p->value.to<double>(cluster.ramping.value().maxDownwardPowerRampingRate) : true;
// we ignore this property as it was already handled in ThermalClusterLoadFromSection
if (p->key == "ramping-enabled")
return true;

if (p->key == "unitcount")
return p->value.to<uint>(cluster.unitCount);
if (p->key == "volatility.planned")
Expand All @@ -286,6 +303,16 @@ bool ThermalClusterLoadFromSection(const AnyString& filename,

cluster.setName(section.name);

// initialize the ramping attributes only if ramping-enabled=true
auto* rampingEnabledProperty = section.find("ramping-enabled");
if(rampingEnabledProperty)
{
bool rampingEnabled = false;
bool attributeOK = rampingEnabledProperty->value.to<bool>(rampingEnabled);
if (rampingEnabled && attributeOK)
cluster.ramping = ThermalCluster::Ramping();
}

if (section.firstProperty)
{
// Browse all properties
Expand Down Expand Up @@ -420,6 +447,17 @@ bool ThermalClusterList::saveToFolder(const AnyString& folder) const
if (!Utils::isZero(c->variableomcost))
s->add("variableomcost", Utils::round(c->variableomcost, 3));

// ramping (only if ramping is enabled)
if (c->ramping && c->ramping.value().powerIncreaseCost != 0)
s->add("power-increase-cost", Math::Round(c->ramping.value().powerIncreaseCost, 3));
if (c->ramping && c->ramping.value().powerDecreaseCost != 0)
s->add("power-decrease-cost", Math::Round(c->ramping.value().powerDecreaseCost, 3));
if (c->ramping && c->ramping.value().maxUpwardPowerRampingRate != 0)
s->add("max-upward-power-ramping-rate",
Math::Round(c->ramping.value().maxUpwardPowerRampingRate, 3));
if (c->ramping && c->ramping.value().maxDownwardPowerRampingRate != 0)
s->add("max-downward-power-ramping-rate",
Math::Round(c->ramping.value().maxDownwardPowerRampingRate, 3));

//pollutant factor
for (auto const& [key, val] : Pollutant::namesToEnum)
Expand Down
20 changes: 19 additions & 1 deletion src/solver/optimisation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ set(RTESOLVER_OPT
adequacy_patch_csr/constraints/CsrAreaBalance.cpp
include/antares/solver/optimisation/adequacy_patch_csr/constraints/CsrBindingConstraintHour.h
adequacy_patch_csr/constraints/CsrBindingConstraintHour.cpp
opt_decompte_variables_et_contraintes_rampes_thermiques.cpp
opt_construction_variables_rampes_thermiques.cpp
opt_gestion_des_bornes_rampes_thermiques.cpp
opt_gestion_des_couts_rampes_thermiques.cpp

include/antares/solver/optimisation/opt_period_string_generator_base.h
include/antares/solver/optimisation/opt_rename_problem.h
Expand Down Expand Up @@ -127,10 +131,21 @@ set(RTESOLVER_OPT
include/antares/solver/optimisation/constraints/MinDownTime.h
constraints/MinDownTime.cpp

include/antares/solver/optimisation/constraints/RampingIncreaseRate.h
constraints/RampingIncreaseRate.cpp
include/antares/solver/optimisation/constraints/RampingDecreaseRate.h
constraints/RampingDecreaseRate.cpp
include/antares/solver/optimisation/constraints/PowerOutputVariationIncrease.h
constraints/PowerOutputVariationIncrease.cpp
include/antares/solver/optimisation/constraints/PowerOutputVariationDecrease.h
constraints/PowerOutputVariationDecrease.cpp

include/antares/solver/optimisation/ProblemMatrixEssential.h
ProblemMatrixEssential.cpp
include/antares/solver/optimisation/LinearProblemMatrixStartUpCosts.h
LinearProblemMatrixStartUpCosts.cpp
include/antares/solver/optimisation/LinearProblemMatrixRamping.h
LinearProblemMatrixRamping.cpp
include/antares/solver/optimisation/LinearProblemMatrix.h
LinearProblemMatrix.cpp
include/antares/solver/optimisation/QuadraticProblemMatrix.h
Expand All @@ -146,6 +161,10 @@ set(RTESOLVER_OPT
constraints/HydroPowerGroup.cpp
include/antares/solver/optimisation/constraints/HydraulicSmoothingGroup.h
constraints/HydraulicSmoothingGroup.cpp
include/antares/solver/optimisation/constraints/RampingIncreaseDecreaseRateGroup.h
constraints/RampingIncreaseDecreaseRateGroup.cpp
include/antares/solver/optimisation/constraints/PowerOutputVariationGroup.h
constraints/PowerOutputVariationGroup.cpp
include/antares/solver/optimisation/constraints/MinMaxHydroPowerGroup.h
constraints/MinMaxHydroPowerGroup.cpp
include/antares/solver/optimisation/constraints/MaxPumpingGroup.h
Expand Down Expand Up @@ -174,7 +193,6 @@ set(RTESOLVER_OPT
variables/VariableManagement.cpp
variables/VariableManagerUtils.h
variables/VariableManagerUtils.cpp

)


Expand Down
2 changes: 2 additions & 0 deletions src/solver/optimisation/LinearProblemMatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "antares/solver/utils/filename.h"
#include "antares/solver/optimisation/opt_fonctions.h"
#include "antares/solver/optimisation/LinearProblemMatrixStartUpCosts.h"
#include "antares/solver/optimisation/LinearProblemMatrixRamping.h"

using namespace Antares::Data;

Expand Down Expand Up @@ -61,6 +62,7 @@ void LinearProblemMatrix::Run()
if (problemeHebdo_->OptimisationAvecCoutsDeDemarrage)
{
LinearProblemMatrixStartUpCosts(problemeHebdo_, false, builder_).Run();
LinearProblemMatrixRamping(problemeHebdo_, false, builder_).Run();
}

return;
Expand Down
34 changes: 34 additions & 0 deletions src/solver/optimisation/LinearProblemMatrixRamping.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
** Copyright 2007-2024, RTE (https://www.rte-france.com)
** See AUTHORS.txt
** SPDX-License-Identifier: MPL-2.0
** This file is part of Antares-Simulator,
** Adequacy and Performance assessment for interconnected energy networks.
**
** Antares_Simulator is free software: you can redistribute it and/or modify
** it under the terms of the Mozilla Public Licence 2.0 as published by
** the Mozilla Foundation, either version 2 of the License, or
** (at your option) any later version.
**
** Antares_Simulator is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** Mozilla Public Licence 2.0 for more details.
**
** You should have received a copy of the Mozilla Public Licence 2.0
** along with Antares_Simulator. If not, see <https://opensource.org/license/mpl-2-0/>.
*/
#include "antares/solver/optimisation/LinearProblemMatrixRamping.h"
using namespace Antares::Data;

LinearProblemMatrixRamping::LinearProblemMatrixRamping(PROBLEME_HEBDO* problemeHebdo,
bool Simulation,
ConstraintBuilder& builder) :
ProblemMatrixEssential(problemeHebdo),
simulation_(Simulation),
rampingIncreaseDecreaseRateGroup_(problemeHebdo, simulation_, builder),
powerOutputVariationGroup_(problemeHebdo, simulation_, builder)
{
constraintgroups_
= {&rampingIncreaseDecreaseRateGroup_, &powerOutputVariationGroup_};
}
18 changes: 18 additions & 0 deletions src/solver/optimisation/constraints/ConstraintBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,24 @@ ConstraintBuilder& ConstraintBuilder::DispatchableProduction(unsigned int index,
return *this;
}

ConstraintBuilder& ConstraintBuilder::ProductionDecreaseAboveMin(unsigned int index,
double coeff,
int offset,
int delta)
{
AddVariable(variableManager_.ProductionDecreaseAboveMin(index, hourInWeek_, offset, delta), coeff);
return *this;
}

ConstraintBuilder& ConstraintBuilder::ProductionIncreaseAboveMin(unsigned int index,
double coeff,
int offset,
int delta)
{
AddVariable(variableManager_.ProductionIncreaseAboveMin(index, hourInWeek_, offset, delta), coeff);
return *this;
}

ConstraintBuilder& ConstraintBuilder::NumberOfDispatchableUnits(unsigned int index, double coeff)
{
AddVariable(variableManager_.NumberOfDispatchableUnits(index, hourInWeek_), coeff);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "antares/solver/optimisation/constraints/PowerOutputVariationDecrease.h"

void PowerOutputVariationDecrease::add(int pays, int index, int pdt)
{
if (!data.Simulation)
{
int cluster = data.PaliersThermiquesDuPays[pays]
.NumeroDuPalierDansLEnsembleDesPaliersThermiques[index];
double pmaxDUnGroupeDuPalierThermique
= data.PaliersThermiquesDuPays[pays].PmaxDUnGroupeDuPalierThermique[index];
// constraint : P(t) - P(t-1) + P^- + u * M^-(t) >= 0
builder.updateHourWithinWeek(pdt)
.DispatchableProduction(cluster, 1.0)
.DispatchableProduction(
cluster, -1.0, -1, builder.data.NombreDePasDeTempsPourUneOptimisation)
.ProductionDecreaseAboveMin(cluster, 1.0)
.NumberStoppingDispatchableUnits(cluster, pmaxDUnGroupeDuPalierThermique)
.greaterThan();

if (builder.NumberOfVariables() > 0)
{
ConstraintNamer namer(builder.data.NomDesContraintes);

namer.UpdateTimeStep(builder.data.weekInTheYear * 168 + pdt);
namer.UpdateArea(builder.data.NomsDesPays[pays]);

namer.ProductionOutputVariation(
builder.data.nombreDeContraintes,
data.PaliersThermiquesDuPays[pays].NomsDesPaliersThermiques[index]);
}
builder.build();
}
else
{
builder.data.NbTermesContraintesPourLesRampes += 4;
builder.data.nombreDeContraintes++;
}
}
Loading
Loading