Skip to content

Commit

Permalink
Modeler 1.1c: Scenarize problem filler [ANT-2003] (#2445)
Browse files Browse the repository at this point in the history
  • Loading branch information
payetvin authored Oct 10, 2024
1 parent 6324724 commit f21b708
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class LinearProblemBuilder
{
public:
explicit LinearProblemBuilder(const std::vector<LinearProblemFiller*>& fillers);
void build(ILinearProblem& pb, LinearProblemData& data);
void build(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx);

private:
const std::vector<LinearProblemFiller*>& fillers_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,37 @@
namespace Antares::Solver::Modeler::Api
{

struct FillContext
{
FillContext(unsigned first, unsigned last):
firstTimeStep(first),
lastTimeStep(last)
{
}

unsigned getFirstTimeStep() const
{
return firstTimeStep;
}

unsigned getLastTimeStep() const
{
return lastTimeStep;
}

std::vector<unsigned> scenariosSelected;

private:
unsigned firstTimeStep;
unsigned lastTimeStep;
};

class LinearProblemFiller
{
public:
virtual void addVariables(ILinearProblem& pb, LinearProblemData& data) = 0;
virtual void addConstraints(ILinearProblem& pb, LinearProblemData& data) = 0;
virtual void addObjective(ILinearProblem& pb, LinearProblemData& data) = 0;
virtual void addVariables(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) = 0;
virtual void addConstraints(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) = 0;
virtual void addObjective(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) = 0;
virtual ~LinearProblemFiller() = default;
};

Expand Down
32 changes: 28 additions & 4 deletions src/solver/modeler/api/linearProblemBuilder.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
/*
* 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 <algorithm>
#include <memory>

Expand All @@ -11,11 +32,14 @@ LinearProblemBuilder::LinearProblemBuilder(const std::vector<LinearProblemFiller
{
}

void LinearProblemBuilder::build(ILinearProblem& pb, LinearProblemData& data)
void LinearProblemBuilder::build(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx)
{
std::ranges::for_each(fillers_, [&](const auto& filler) { filler->addVariables(pb, data); });
std::ranges::for_each(fillers_, [&](const auto& filler) { filler->addConstraints(pb, data); });
std::ranges::for_each(fillers_, [&](const auto& filler) { filler->addObjective(pb, data); });
std::ranges::for_each(fillers_,
[&](const auto& filler) { filler->addVariables(pb, data, ctx); });
std::ranges::for_each(fillers_,
[&](const auto& filler) { filler->addConstraints(pb, data, ctx); });
std::ranges::for_each(fillers_,
[&](const auto& filler) { filler->addObjective(pb, data, ctx); });
}

} // namespace Antares::Solver::Modeler::Api
48 changes: 48 additions & 0 deletions src/tests/src/solver/modeler/api/mock-fillers/FillerContext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once

#include "antares/solver/modeler/api/linearProblemFiller.h"

namespace Antares::Solver::Modeler::Api
{

class VarFillerContext: public LinearProblemFiller
{
public:
explicit VarFillerContext() = default;
void addVariables(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;
void addConstraints(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;
void addObjective(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;

std::array<std::array<int, 3>, 5> timeseries = {
{{1, 3, 5}, {2, 4, 6}, {7, 9, 11}, {8, 10, 12}, {13, 15, 17}}};
};

void VarFillerContext::addVariables(ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
for (unsigned timestep = ctx.getFirstTimeStep(); timestep < ctx.getLastTimeStep(); timestep++)
{
for (unsigned scenario: ctx.scenariosSelected)
{
pb.addNumVariable(timeseries[timestep][scenario],
timeseries[timestep][scenario],
"variable-ts" + std::to_string(timestep) + "-sc"
+ std::to_string(scenario));
}
}
}

void VarFillerContext::addConstraints([[maybe_unused]] ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
}

void VarFillerContext::addObjective([[maybe_unused]] ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
}

} // namespace Antares::Solver::Modeler::Api
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,27 @@ class OneConstraintFiller: public LinearProblemFiller
{
public:
explicit OneConstraintFiller() = default;
void addVariables(ILinearProblem& pb, LinearProblemData& data) override;
void addConstraints(ILinearProblem& pb, LinearProblemData& data) override;
void addObjective(ILinearProblem& pb, LinearProblemData& data) override;
void addVariables(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;
void addConstraints(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;
void addObjective(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;
};

void OneConstraintFiller::addVariables(ILinearProblem& pb, LinearProblemData& data)
void OneConstraintFiller::addVariables([[maybe_unused]] ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
}

void OneConstraintFiller::addConstraints(ILinearProblem& pb, LinearProblemData& data)
void OneConstraintFiller::addConstraints(ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
pb.addConstraint(1, 2, "constraint-by-OneConstraintFiller");
}

void OneConstraintFiller::addObjective(ILinearProblem& pb, LinearProblemData& data)
void OneConstraintFiller::addObjective([[maybe_unused]] ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
}

Expand Down
18 changes: 12 additions & 6 deletions src/tests/src/solver/modeler/api/mock-fillers/OneVarFiller.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,30 @@ class OneVarFiller: public LinearProblemFiller
{
public:
explicit OneVarFiller() = default;
void addVariables(ILinearProblem& pb, LinearProblemData& data) override;
void addConstraints(ILinearProblem& pb, LinearProblemData& data) override;
void addObjective(ILinearProblem& pb, LinearProblemData& data) override;
void addVariables(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;
void addConstraints(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;
void addObjective(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;

private:
std::string added_var_name_ = "var-by-OneVarFiller";
};

void OneVarFiller::addVariables(ILinearProblem& pb, LinearProblemData& data)
void OneVarFiller::addVariables(ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
pb.addNumVariable(0, 1, added_var_name_);
}

void OneVarFiller::addConstraints(ILinearProblem& pb, LinearProblemData& data)
void OneVarFiller::addConstraints([[maybe_unused]] ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
}

void OneVarFiller::addObjective(ILinearProblem& pb, LinearProblemData& data)
void OneVarFiller::addObjective(ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
auto* var = pb.getVariable(added_var_name_);
pb.setObjectiveCoefficient(var, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,30 @@ class TwoVarsTwoConstraintsFiller: public LinearProblemFiller
{
public:
explicit TwoVarsTwoConstraintsFiller() = default;
void addVariables(ILinearProblem& pb, LinearProblemData& data) override;
void addConstraints(ILinearProblem& pb, LinearProblemData& data) override;
void addObjective(ILinearProblem& pb, LinearProblemData& data) override;
void addVariables(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;
void addConstraints(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;
void addObjective(ILinearProblem& pb, LinearProblemData& data, FillContext& ctx) override;
};

void TwoVarsTwoConstraintsFiller::addVariables(ILinearProblem& pb, LinearProblemData& data)
void TwoVarsTwoConstraintsFiller::addVariables(ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
pb.addNumVariable(0, 1, "var-1-by-TwoVarsTwoConstraintsFiller");
pb.addNumVariable(0, 3, "var-2-by-TwoVarsTwoConstraintsFiller");
}

void TwoVarsTwoConstraintsFiller::addConstraints(ILinearProblem& pb, LinearProblemData& data)
void TwoVarsTwoConstraintsFiller::addConstraints(ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
pb.addConstraint(1, 2, "constr-1-by-TwoVarsTwoConstraintsFiller");
pb.addConstraint(1, 3, "constr-2-by-TwoVarsTwoConstraintsFiller");
}

void TwoVarsTwoConstraintsFiller::addObjective(ILinearProblem& pb, LinearProblemData& data)
void TwoVarsTwoConstraintsFiller::addObjective([[maybe_unused]] ILinearProblem& pb,
[[maybe_unused]] LinearProblemData& data,
[[maybe_unused]] FillContext& ctx)
{
}

Expand Down
34 changes: 29 additions & 5 deletions src/tests/src/solver/modeler/api/testModelerLPbuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <antares/solver/modeler/api/linearProblemBuilder.h>
#include <antares/solver/modeler/ortoolsImpl/linearProblem.h>

#include "mock-fillers/FillerContext.h"
#include "mock-fillers/OneConstraintFiller.h"
#include "mock-fillers/OneVarFiller.h"
#include "mock-fillers/TwoVarsTwoConstraintsFiller.h"
Expand All @@ -41,6 +42,7 @@ struct Fixture

std::vector<LinearProblemFiller*> fillers;
LinearProblemData LP_Data;
FillContext ctx = {0, 0}; // dummy value for other tests than context
std::unique_ptr<ILinearProblem> pb;
};

Expand All @@ -49,7 +51,7 @@ BOOST_AUTO_TEST_SUITE(tests_on_linear_problem_builder)
BOOST_FIXTURE_TEST_CASE(no_filler_given_to_builder___nothing_built, Fixture)
{
LinearProblemBuilder lpBuilder(fillers);
lpBuilder.build(*pb, LP_Data);
lpBuilder.build(*pb, LP_Data, ctx);

BOOST_CHECK_EQUAL(pb->variableCount(), 0);
BOOST_CHECK_EQUAL(pb->constraintCount(), 0);
Expand All @@ -61,7 +63,7 @@ BOOST_FIXTURE_TEST_CASE(one_var_filler___the_var_is_built, Fixture)
fillers = {oneVarFiller.get()};

LinearProblemBuilder lpBuilder(fillers);
lpBuilder.build(*pb, LP_Data);
lpBuilder.build(*pb, LP_Data, ctx);

BOOST_CHECK_EQUAL(pb->variableCount(), 1);
BOOST_CHECK_EQUAL(pb->constraintCount(), 0);
Expand All @@ -76,7 +78,7 @@ BOOST_FIXTURE_TEST_CASE(one_constraint_filler___the_constraint_is_built, Fixture
fillers = {oneConstrFiller.get()};

LinearProblemBuilder lpBuilder(fillers);
lpBuilder.build(*pb, LP_Data);
lpBuilder.build(*pb, LP_Data, ctx);

BOOST_CHECK_EQUAL(pb->variableCount(), 0);
BOOST_CHECK_EQUAL(pb->constraintCount(), 1);
Expand All @@ -91,7 +93,7 @@ BOOST_FIXTURE_TEST_CASE(two_fillers_given_to_builder___all_is_built, Fixture)
fillers = {oneVarFiller.get(), oneConstrFiller.get()};

LinearProblemBuilder lpBuilder(fillers);
lpBuilder.build(*pb, LP_Data);
lpBuilder.build(*pb, LP_Data, ctx);

BOOST_CHECK_EQUAL(pb->constraintCount(), 1);
BOOST_CHECK(pb->getConstraint("constraint-by-OneConstraintFiller"));
Expand All @@ -106,10 +108,32 @@ BOOST_FIXTURE_TEST_CASE(three_fillers_given_to_builder___3_vars_3_constr_are_bui
fillers = {oneVarFiller.get(), oneConstrFiller.get(), twoVarsTwoConstrFiller.get()};

LinearProblemBuilder lpBuilder(fillers);
lpBuilder.build(*pb, LP_Data);
lpBuilder.build(*pb, LP_Data, ctx);

BOOST_CHECK_EQUAL(pb->variableCount(), 3);
BOOST_CHECK_EQUAL(pb->constraintCount(), 3);
}

BOOST_FIXTURE_TEST_CASE(FillerWithContext, Fixture)
{
auto varFiller = std::make_unique<VarFillerContext>();
fillers = {varFiller.get()};

ctx = FillContext(0, 5);

ctx.scenariosSelected.push_back(0);
ctx.scenariosSelected.push_back(2);

LinearProblemBuilder lpBuilder(fillers);
lpBuilder.build(*pb, LP_Data, ctx);

BOOST_CHECK_EQUAL(pb->variableCount(), 10); // 5 timestep * 2 scenario

auto var1 = pb->getVariable("variable-ts0-sc0");
BOOST_CHECK_EQUAL(var1->getLb(), varFiller->timeseries[0][0]);

auto var2 = pb->getVariable("variable-ts3-sc2");
BOOST_CHECK_EQUAL(var2->getLb(), varFiller->timeseries[3][2]);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit f21b708

Please sign in to comment.