Skip to content

Commit

Permalink
Add interface for Thermal costs, fix wrong values in GUI (#2526)
Browse files Browse the repository at this point in the history
# Advantages
- Better separation of responsabilities, remove a lot of `if..else`
- Make sure that if costgeneration = setManually (legacy behavior), no
new code is executed

# Cons
- The caller needs to call function `ThermalCluster::getCostProvider`
first

# GUI
Previously, the formula used for modulation columns was "netCost =
modulation * modulation * originalCost" for market bid & marginal costs.
We fix this formula to "netCost = modulation * originalCost"
  • Loading branch information
flomnes authored Dec 10, 2024
1 parent 7a79330 commit 001e6d5
Show file tree
Hide file tree
Showing 14 changed files with 322 additions and 225 deletions.
3 changes: 3 additions & 0 deletions src/libs/antares/study/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,11 @@ set(SRC_STUDY_PART_THERMAL
include/antares/study/parts/thermal/ecoInput.h
parts/thermal/ecoInput.cpp
include/antares/study/parts/thermal/cluster.h
include/antares/study/parts/thermal/cost_provider.h
include/antares/study/parts/thermal/cluster.hxx
parts/thermal/cluster.cpp
parts/thermal/scenarized_cost_provider.cpp
parts/thermal/constant_cost_provider.cpp
include/antares/study/parts/thermal/cluster_list.h
parts/thermal/cluster_list.cpp
include/antares/study/parts/thermal/pollutant.h
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#include "../../fwd.h"
#include "../common/cluster.h"
#include "cost_provider.h"
#include "defines.h"
#include "ecoInput.h"
#include "pollutant.h"
Expand Down Expand Up @@ -64,6 +65,12 @@ enum class LocalTSGenerationBehavior
forceNoGen
};

double computeMarketBidCost(double fuelCost,
double fuelEfficiency,
double co2EmissionFactor,
double co2cost,
double variableomcost);

/*!
** \brief A single thermal cluster
*/
Expand Down Expand Up @@ -147,13 +154,6 @@ class ThermalCluster final: public Cluster, public std::enable_shared_from_this<
*/
void calculationOfSpinning();

//! \name MarketBid and Marginal Costs
//@{
/*!
** \brief Calculation of market bid and marginals costs per hour
*/
void ComputeCostTimeSeries();

/*!
** \brief Calculation of spinning (reverse)
**
Expand Down Expand Up @@ -207,10 +207,6 @@ class ThermalCluster final: public Cluster, public std::enable_shared_from_this<

bool doWeGenerateTS(bool globalTSgeneration) const;

double getOperatingCost(uint tsIndex, uint hourInTheYear) const;
double getMarginalCost(uint tsIndex, uint hourInTheYear) const;
double getMarketBidCost(uint hourInTheYear, uint year) const;

// Check & correct availability timeseries for thermal availability
// Only applies if time-series are ready-made
void checkAndCorrectAvailability();
Expand Down Expand Up @@ -349,29 +345,16 @@ class ThermalCluster final: public Cluster, public std::enable_shared_from_this<
//! Data for the preprocessor
std::unique_ptr<PreproAvailability> prepro;

/*!
** \brief Production Cost, Market Bid Cost and Marginal Cost Matrixes - Per Hour and per Time
*Series
*/
struct CostsTimeSeries
{
std::array<double, HOURS_PER_YEAR> productionCostTs;
std::array<double, HOURS_PER_YEAR> marketBidCostTS;
std::array<double, HOURS_PER_YEAR> marginalCostTS;
};

std::vector<CostsTimeSeries> costsTimeSeries;

EconomicInputData ecoInput;

LocalTSGenerationBehavior tsGenBehavior = LocalTSGenerationBehavior::useGlobalParameter;

friend class ThermalClusterList;

double computeMarketBidCost(double fuelCost, double co2EmissionFactor, double co2cost);

unsigned int precision() const override;

CostProvider& getCostProvider();

private:
// Calculation of marketBid and marginal costs hourly time series
//
Expand All @@ -383,12 +366,7 @@ class ThermalCluster final: public Cluster, public std::enable_shared_from_this<
// Marginal_Cost[€/MWh] = Market_Bid_Cost[€/MWh] = (Fuel_Cost[€/GJ] * 3.6 * 100 / Efficiency[%])
// CO2_emission_factor[tons/MWh] * C02_cost[€/tons] + Variable_O&M_cost[€/MWh]

void fillMarketBidCostTS();
void fillMarginalCostTS();
void resizeCostTS();
void ComputeMarketBidTS();
void MarginalCostEqualsMarketBid();
void ComputeProductionCostTS();
std::unique_ptr<CostProvider> costProvider;

}; // class ThermalCluster
} // namespace Data
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* 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/>.
*/

#pragma once

#include <array>
#include <vector>

namespace Antares::Data
{
class CostProvider
{
public:
virtual ~CostProvider() = default;
virtual double getOperatingCost(uint serieIndex, uint hourInTheYear) const = 0;
virtual double getMarginalCost(uint serieIndex, uint hourInTheYear) const = 0;
virtual double getMarketBidCost(uint hourInTheYear, uint year) const = 0;
};

class ThermalCluster;

class ConstantCostProvider: public CostProvider
{
public:
explicit ConstantCostProvider(const ThermalCluster& cluster);
virtual ~ConstantCostProvider() = default;
double getOperatingCost(uint serieIndex, uint hourInTheYear) const override;
double getMarginalCost(uint serieIndex, uint hourInTheYear) const override;
double getMarketBidCost(uint hourInTheYear, uint year) const override;

private:
const ThermalCluster& cluster;
};

class ScenarizedCostProvider: public CostProvider
{
public:
explicit ScenarizedCostProvider(const ThermalCluster& cluster);
virtual ~ScenarizedCostProvider() = default;
double getOperatingCost(uint serieIndex, uint hourInTheYear) const override;
double getMarginalCost(uint serieIndex, uint hourInTheYear) const override;
double getMarketBidCost(uint hourInTheYear, uint year) const override;

private:
/*!
** \brief Production Cost, Market Bid Cost and Marginal Cost Matrixes - Per Hour and per Time
*Series
*/
struct CostsTimeSeries
{
std::array<double, HOURS_PER_YEAR> productionCostTs;
std::array<double, HOURS_PER_YEAR> marketBidCostTS;
std::array<double, HOURS_PER_YEAR> marginalCostTS;
};

void resizeCostTS();
void ComputeMarketBidTS();
void MarginalCostEqualsMarketBid();
void ComputeProductionCostTS();

std::vector<CostsTimeSeries> costsTimeSeries;
const ThermalCluster& cluster;
};
} // namespace Antares::Data
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,13 @@
#ifndef __ANTARES_LIBS_STUDY_PARTS_THERMAL_DEFINES_H__
#define __ANTARES_LIBS_STUDY_PARTS_THERMAL_DEFINES_H__

namespace Antares
{
namespace Data
namespace Antares::Data
{
// Forward declaration
class ThermalCluster;
class ThermalClusterList;
class PreproAvailability;

} // namespace Data
} // namespace Antares
} // namespace Antares::Data

#endif // __ANTARES_LIBS_STUDY_PARTS_THERMAL_DEFINES_H__
Loading

0 comments on commit 001e6d5

Please sign in to comment.