Skip to content

Commit

Permalink
End-to-end simple tests : replace test 5 by its cleaner version + cle…
Browse files Browse the repository at this point in the history
…aning.
  • Loading branch information
guilpier-code committed Jul 27, 2023
1 parent 553e1dc commit 507008f
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 292 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
#define WIN32_LEAN_AND_MEAN
#include <boost/test/included/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include "utils.h"
#include "simulation.h"

#include "antares/study/study.h"
#include "utils.h"

namespace utf = boost::unit_test;
namespace tt = boost::test_tools;
Expand Down
224 changes: 21 additions & 203 deletions src/tests/end-to-end/simple_study/simple-study.cpp
Original file line number Diff line number Diff line change
@@ -1,138 +1,14 @@
#define BOOST_TEST_MODULE test-end-to-end tests
#include <boost/test/included/unit_test.hpp>
#include <boost/test/data/test_case.hpp>

#include "utils.h"
#include "simulation.h"

namespace utf = boost::unit_test;
namespace tt = boost::test_tools;

using namespace Antares::Data;

Area* addArea(Study::Ptr pStudy, const std::string& areaName, int nbTS)
{
Area* pArea = pStudy->areaAdd(areaName);

BOOST_CHECK(pArea != NULL);

//Need to add unsupplied energy cost constraint so load is respected
pArea->thermal.unsuppliedEnergyCost = 10000.0;
pArea->spreadUnsuppliedEnergyCost = 0.01;

//Define default load
pArea->load.series->timeSeries.resize(nbTS, HOURS_PER_YEAR);
pArea->load.series->timeSeries.fill(0.0);

return pArea;
}

std::shared_ptr<ThermalCluster> addCluster(Area* pArea, const std::string& clusterName, double maximumPower, double cost, int nbTS, int unitCount)
{
auto pCluster = std::make_shared<ThermalCluster>(pArea);
pCluster->setName(clusterName);
pCluster->reset();

pCluster->unitCount = unitCount;
pCluster->nominalCapacity = maximumPower;

//Power cost
pCluster->marginalCost = cost;

//Must define market bid cost otherwise all production is used
pCluster->marketBidCost = cost;

//Must define min stable power always 0.0
pCluster->minStablePower = 0.0;

//Define power consumption
pCluster->series->timeSeries.resize(nbTS, HOURS_PER_YEAR);
pCluster->series->timeSeries.fill(0.0);

//No modulation on cost
pCluster->modulation.reset(thermalModulationMax, HOURS_PER_YEAR);
pCluster->modulation.fill(1.);
pCluster->modulation.fillColumn(thermalMinGenModulation, 0.);

//Initialize production cost from modulation
if (not pCluster->productionCost)
pCluster->productionCost = new double[HOURS_PER_YEAR];


double* prodCost = pCluster->productionCost;
double marginalCost = pCluster->marginalCost;

// Production cost
auto& modulation = pCluster->modulation[thermalModulationCost];
for (uint h = 0; h != pCluster->modulation.height; ++h)
prodCost[h] = marginalCost * modulation[h];


pCluster->nominalCapacityWithSpinning = pCluster->nominalCapacity;

auto added = pArea->thermal.list.add(pCluster);

BOOST_CHECK(added != nullptr);

pArea->thermal.list.mapping[pCluster->id()] = added;

return pCluster;
}

Solver::Simulation::ISimulation< Solver::Simulation::Economy >* runSimulation(Study::Ptr pStudy)
{
// Runtime data dedicated for the solver
BOOST_CHECK(pStudy->initializeRuntimeInfos());

for(auto [_, area]: pStudy->areas) {
for (unsigned int i = 0; i<pStudy->maxNbYearsInParallel ;++i) {
area->scratchpad.push_back(AreaScratchpad(*pStudy->runtime, *area));
}
}

Settings pSettings;
pSettings.tsGeneratorsOnly = false;
pSettings.noOutput = false;

//Launch simulation
Benchmarking::NullDurationCollector nullDurationCollector;
Solver::Simulation::ISimulation<Solver::Simulation::Economy> *simulation = new Solver::Simulation::ISimulation<Solver::Simulation::Economy>(
*pStudy, pSettings, &nullDurationCollector);

// Allocate all arrays
SIM_AllocationTableaux();

// Let's go
simulation->run();

return simulation;
}


// checkVariable<VCard>(simulation, pArea, expectedHourlyVal)
//
// Check variable value from VCard
// Template param :
// VCard : VCard defining variable (Solver::Variable::Economy::VCardOverallCost for example)
// classical params :
// simulation : Simulation object containing results
// area : Area to be checked
// expectedHourlyValue : Expected hourly value
template<class VCard>
void checkVariable(
Solver::Simulation::ISimulation< Solver::Simulation::Economy >* simulation,
Area* pArea,
double expectedHourlyValue
)

{
/*Get value*/
typename Antares::Solver::Variable::Storage<VCard>::ResultsType* result = nullptr;
simulation->variables.retrieveResultsForArea<VCard>(&result, pArea);
BOOST_TEST(result->avgdata.hourly[0] == expectedHourlyValue, tt::tolerance(0.001));
BOOST_TEST(result->avgdata.daily[0] == expectedHourlyValue * 24, tt::tolerance(0.001));
BOOST_TEST(result->avgdata.weekly[0] == expectedHourlyValue * 24 * 7, tt::tolerance(0.001));
}

// =================================
// Basic fixture
// =================================
Expand Down Expand Up @@ -195,7 +71,7 @@ BOOST_AUTO_TEST_CASE(two_MC_years__thermal_cluster_fullfills_area_demand_on_2nd_
BOOST_TEST(output->load(area).hour(0) == loadInArea, tt::tolerance(0.001));
}

BOOST_AUTO_TEST_CASE(two_mc_year_two_ts_identical)
BOOST_AUTO_TEST_CASE(two_mc_years__two_ts_identical)
{
setNumberMCyears(2);

Expand All @@ -214,7 +90,7 @@ BOOST_AUTO_TEST_CASE(two_mc_year_two_ts_identical)
BOOST_TEST(output->load(area).hour(0) == loadInArea, tt::tolerance(0.001));
}

BOOST_AUTO_TEST_CASE(two_mc_year__two_ts_for_load)
BOOST_AUTO_TEST_CASE(two_mc_years__two_ts_for_load)
{
setNumberMCyears(2);

Expand All @@ -234,86 +110,28 @@ BOOST_AUTO_TEST_CASE(two_mc_year__two_ts_for_load)
BOOST_TEST(output->overallCost(area).hour(0) == averageLoad * clusterCost, tt::tolerance(0.001));
}

BOOST_AUTO_TEST_SUITE_END()


BOOST_AUTO_TEST_SUITE(simple_test)

//Very simple test with one area and one load and two year with different load and weight
BOOST_AUTO_TEST_CASE(two_mc_year_two_ts_different_weight)
BOOST_AUTO_TEST_CASE(two_mc_years_with_different_weight__two_ts)
{
//Create study
Study::Ptr pStudy = std::make_shared<Study>(true); // for the solver

//Two years and two TS
int nbYears = 2;
int nbTS = 2;

//Prepare study
prepareStudy(pStudy, nbYears);
pStudy->parameters.nbTimeSeriesLoad = nbTS;
pStudy->parameters.nbTimeSeriesThermal = nbTS;

//Define years weight
std::vector<float> yearsWeight;
yearsWeight.assign(nbYears, 1);
yearsWeight[0] = 4.f; yearsWeight[1] = 10.f;

float yearSum = defineYearsWeight(pStudy,yearsWeight);

//Create area
double load = 5.0;
Area* pArea = addArea(pStudy, "Area 1", nbTS);

//Initialize time series
std::vector<double> loadList;
loadList.assign(nbTS, load);
loadList[1] = load * 2;

for (int i = 0; i < nbTS; i++)
{
pArea->load.series->timeSeries.fillColumn(i, loadList[i]);
}

//Add thermal cluster
double availablePower = 20.0;
double cost = 2.2;
double maximumPower = 100.0;
auto pCluster = addCluster(pArea, "Cluster 1", maximumPower, cost, nbTS);

//Initialize time series
pCluster->series->timeSeries.fillColumn(0, availablePower);
pCluster->series->timeSeries.fillColumn(1, availablePower);

//Create scenario rules to force use of TS otherwise the TS used is random
std::vector<int> areaLoadTS;
areaLoadTS.assign(nbYears, 1);
areaLoadTS[0] = 1; areaLoadTS[1] = 2;

ScenarioBuilder::Rules::Ptr pRules = createScenarioRules(pStudy);
for (int i = 0; i < nbYears; i++)
{
pRules->load.setTSnumber(pArea->index, i, areaLoadTS[i]);
}

//Calculate average load with mc years weight
double averageLoad = 0.0;
for (int i = 0; i < nbYears; i++)
{
averageLoad += loadList[areaLoadTS[i] - 1 ] * yearsWeight[i] / yearSum;
}

//Launch simulation
Solver::Simulation::ISimulation< Solver::Simulation::Economy >* simulation = runSimulation(pStudy);
setNumberMCyears(2);

//Overall cost must be load * cost by MW
checkVariable<Solver::Variable::Economy::VCardOverallCost>(simulation, pArea, averageLoad * cost);
giveWeightToYear(4.f, 0);
giveWeightToYear(10.f, 1);
float weightSum = study->parameters.getYearsWeightSum();

//Load must be load
checkVariable<Solver::Variable::Economy::VCardTimeSeriesValuesLoad>(simulation, pArea, averageLoad);
loadTSconfig->setNumberColumns(2);
loadTSconfig->fillColumnWith(0, 7.0);
loadTSconfig->fillColumnWith(1, 14.0);

cleanSimulation(simulation);
cleanStudy(pStudy);
ScenarioBuilderRule scenarioBuilderRule(study);
scenarioBuilderRule.load().setTSnumber(area->index, 0, 1);
scenarioBuilderRule.load().setTSnumber(area->index, 1, 2);

simulation->create();
simulation->run();

double averageLoad = (4 * 7. + 10. * 14.) / weightSum;
BOOST_TEST(output->thermalGeneration(cluster.get()).hour(10) == averageLoad, tt::tolerance(0.001));
BOOST_TEST(output->overallCost(area).hour(0) == averageLoad * clusterCost, tt::tolerance(0.001));
}

BOOST_AUTO_TEST_SUITE_END()
76 changes: 8 additions & 68 deletions src/tests/end-to-end/utils/utils.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#define WIN32_LEAN_AND_MEAN
#include "utils.h"
#include "simulation/simulation.h"

using namespace Antares::Data;


void initializeStudy(Study::Ptr study)
Expand Down Expand Up @@ -154,6 +151,14 @@ void StudyBuilder::playOnlyYear(unsigned int year)
params.yearsFilter[year] = true;
}

void StudyBuilder::giveWeightToYear(float weight, unsigned int year)
{
study->parameters.setYearWeight(year, weight);

// Activate playlist, otherwise previous sets won't have any effect
study->parameters.userPlaylist = true;
}

Area* StudyBuilder::addAreaToStudy(const std::string& areaName)
{
Area* area = addAreaToListOfAreas(study->areas, areaName);
Expand All @@ -172,77 +177,12 @@ Area* StudyBuilder::addAreaToStudy(const std::string& areaName)
return area;
}


// ===========================================================

void prepareStudy(Study::Ptr pStudy, int nbYears)
{
//Define study parameters
pStudy->parameters.reset();
pStudy->parameters.resetPlaylist(nbYears);

//Prepare parameters for simulation
Data::StudyLoadOptions options;
pStudy->parameters.prepareForSimulation(options);

// Logical cores
// -------------------------
// Getting the number of logical cores to use before loading and creating the areas :
// Areas need this number to be up-to-date at construction.
pStudy->getNumberOfCores(false, 0);

// Define as current study
Data::Study::Current::Set(pStudy);
}

std::shared_ptr<BindingConstraint> addBindingConstraints(Study::Ptr study, std::string name, std::string group) {
auto bc = study->bindingConstraints.add(name);
bc->group(group);
return bc;
}

Antares::Data::ScenarioBuilder::Rules::Ptr createScenarioRules(Study::Ptr study)
{
ScenarioBuilder::Rules::Ptr rules;

study->scenarioRulesCreate();
ScenarioBuilder::Sets* sets = study->scenarioRules;
if (sets && !sets->empty())
{
rules = sets->createNew("Custom");

study->parameters.useCustomScenario = true;
study->parameters.activeRulesScenario = "Custom";
}

return rules;
}

float defineYearsWeight(Study::Ptr pStudy, const std::vector<float>& yearsWeight)
{
pStudy->parameters.userPlaylist = true;

for (uint i = 0; i < yearsWeight.size(); i++)
{
pStudy->parameters.setYearWeight(i, yearsWeight[i]);
}

return pStudy->parameters.getYearsWeightSum();
}

void cleanSimulation(Solver::Simulation::ISimulation< Solver::Simulation::Economy >* simulation)
{
delete simulation;
}

void cleanStudy(Study::Ptr pStudy)
{
pStudy->clear();

// Remove any global reference
Data::Study::Current::Set(nullptr);
}

void NullResultWriter::addEntryFromBuffer(const std::string&, Clob&)
{

Expand Down
Loading

0 comments on commit 507008f

Please sign in to comment.