Antares Simulator
Power System Simulator
cbuilder.h
1 /*
2  * Copyright 2007-2025, RTE (https://www.rte-france.com)
3  * See AUTHORS.txt
4  * SPDX-License-Identifier: MPL-2.0
5  * This file is part of Antares-Simulator,
6  * Adequacy and Performance assessment for interconnected energy networks.
7  *
8  * Antares_Simulator is free software: you can redistribute it and/or modify
9  * it under the terms of the Mozilla Public Licence 2.0 as published by
10  * the Mozilla Foundation, either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * Antares_Simulator is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * Mozilla Public Licence 2.0 for more details.
17  *
18  * You should have received a copy of the Mozilla Public Licence 2.0
19  * along with Antares_Simulator. If not, see <https://opensource.org/license/mpl-2-0/>.
20  */
21 #ifndef __ANTARES_CONSTRAINTSBUILDER_BUILDER_CBUILDER_H__
22 #define __ANTARES_CONSTRAINTSBUILDER_BUILDER_CBUILDER_H__
23 
24 #include <yuni/yuni.h>
25 #include <yuni/core/string.h>
26 
27 #include <antares/study/study.h>
28 #include "antares/solver/constraints-builder/grid.h"
29 #include "antares/study/area/constants.h"
30 
31 #define CB_PREFIX "@UTO_"
32 
33 namespace Antares
34 {
35 class areaInfo
36 {
37 public:
38  areaInfo(Data::Area* area)
39  {
40  ptr = area;
41  nodeName = area->name.to<std::string>();
42  }
43 
44  std::string getName()
45  {
46  return nodeName;
47  }
48 
49 public:
50  Data::Area* ptr;
51  std::string nodeName;
52 };
53 
54 class linkInfo
55 {
56 public:
57  double weight;
58  bool enabled = true;
59  Data::AreaLinkName name;
60  Antares::Data::AssetType type;
61  double angleLB = 0;
62  double angleUB = 0;
63  bool hasPShiftsEqual = true;
64 
65  uint nImpedanceChanges;
66  double avgImpedance;
67  Data::AreaLink* ptr;
68 
69 public:
70  double getWeightWithImpedance() const;
71  Yuni::String getName() const;
72 
73  linkInfo() = default;
74 
75  ~linkInfo() = default;
76 
78  {
79  inline bool operator()(const linkInfo* lhs, const linkInfo* rhs) const
80  {
81  return lhs->getWeightWithImpedance() < rhs->getWeightWithImpedance();
82  }
83  };
84 
86  {
87  inline bool operator()(const linkInfo* lhs, const linkInfo* rhs) const
88  {
89  return lhs->getWeightWithImpedance() < rhs->getWeightWithImpedance();
90  }
91  };
92 
93  struct addpWeight
94  {
95  double operator()(double i, const linkInfo* o) const
96  {
97  return (o->getWeightWithImpedance() + i);
98  }
99  };
100 
102  {
103  double operator()(double i, const linkInfo* o) const
104  {
105  return (o->getWeightWithImpedance() + i);
106  }
107  };
108 
109  bool operator<(const linkInfo& other) const
110  {
111  return getWeightWithImpedance() < other.getWeightWithImpedance()
112  ? true
113  : (getWeightWithImpedance() > other.getWeightWithImpedance()
114  ? false
115  : getName() < other.getName());
116  }
117 }; // class linkInfo
118 
119 class State
120 {
121 public:
122  State(std::vector<double> impedancesList, uint time, double infinite = 1000000):
123  secondMember(3, time),
124  impedances(impedancesList)
125  {
126  secondMember.fillColumn(1, -1 * infinite);
127  secondMember.fillColumn(0, infinite);
128  }
129 
130  Matrix<double, double> secondMember;
131  std::vector<double> impedances;
132  std::map<linkInfo*, double> WeightMap;
133 };
134 
135 class Cycle
136 {
137 public:
138  Cycle(const std::vector<linkInfo*>& linkList, double infinite = 1000000):
139  time(0),
140  loop(linkList),
141  opType(Data::BindingConstraint::opEquality),
142  pInfinite(infinite)
143  {
144  uint columnImpedance = (uint)Antares::Data::fhlImpedances;
145 
146  std::vector<double> impedances;
147  Data::AreaLink* previousLine = linkList[0]->ptr;
148  double currentLineSign = 1;
149  for (auto line = linkList.begin(); line != linkList.end(); line++)
150  {
151  if ((*line)->nImpedanceChanges > 0
152  || ((*line)->type == Antares::Data::atAC && (!(*line)->hasPShiftsEqual)))
153  {
154  opType = Data::BindingConstraint::opBoth;
155  }
156  impedances.push_back((*line)->ptr->parameters[columnImpedance][0]);
157 
158  time = HOURS_PER_YEAR; /*BC loading always expects 8786 values heigth will
159  have to be resized*/
160 
161  if (line == linkList.begin())
162  {
163  currentLineSign = 1;
164  }
165  else
166  {
167  if (previousLine->with == (*line)->ptr->from
168  || previousLine->from
169  == (*line)->ptr->with) //[(A/B),(B/C),... ] or [(A,B),(C/A),... ]
170  {
171  }
172  else if (previousLine->from == (*line)->ptr->from
173  || previousLine->with == (*line)->ptr->with)
174  {
175  currentLineSign *= -1;
176  }
177  else
178  {
179  assert(0 and "links of the loops do not connect or are not in the right order");
180  }
181  }
182 
183  sign.push_back(currentLineSign);
184  previousLine = (*line)->ptr;
185  }
186  State state(impedances, time, pInfinite);
187  states.push_back(state);
188  }
189 
190  State& getState(std::vector<double>& impedances)
191  {
192  std::vector<State>::iterator stIT = std::find_if(states.begin(),
193  states.end(),
194  [&impedances](State& s) -> bool
195  { return s.impedances == impedances; });
196 
197  if (stIT == states.end())
198  {
199  State state(impedances, time, pInfinite);
200  states.push_back(state);
201  stIT = std::find_if(states.begin(),
202  states.end(),
203  [&impedances](State& s) -> bool
204  { return s.impedances == impedances; });
205  }
206  return *stIT;
207  }
208 
209  uint time;
210  std::vector<double> sign;
211  const std::vector<linkInfo*>& loop;
212  std::vector<State> states;
213  Data::BindingConstraint::Operator opType;
214  double pInfinite;
215 };
216 
217 class CBuilder final
218 {
219 public:
220  typedef std::vector<linkInfo*> Vector;
221  typedef std::map<linkInfo*, double> WeightMap;
222  typedef std::map<linkInfo*, double> Pattern;
223  typedef std::vector<Pattern> VectorOfPatterns;
224  typedef std::map<uint, Pattern*> Map;
225 
226 public:
228 
229 
234  ~CBuilder() = default;
236 
240  bool runConstraintsBuilder(bool standalone = false);
241 
245  bool completeFromStudy();
246 
251 
252  bool saveCBuilderToFile(const String& filename = "") const;
253  bool completeCBuilderFromFile(const std::string& filename = "");
254 
258  int alreadyExistingNetworkConstraints(const Yuni::String& prefix) const;
259 
261  linkInfo* findLinkInfoFromNodeNames(Data::AreaName& u, Data::AreaName& v)
262  {
263  auto linkIT = std::find_if(pLink.begin(),
264  pLink.end(),
265  [&u, &v](std::shared_ptr<linkInfo> edgeP) -> bool
266  {
267  if (edgeP->ptr->from->id == u && edgeP->ptr->with->id == v)
268  {
269  return true;
270  }
271  if (edgeP->ptr->from->id == v && edgeP->ptr->with->id == u)
272  {
273  return true;
274  }
275  else
276  {
277  return false;
278  }
279  });
280  if (linkIT != pLink.end())
281  {
282  return linkIT->get();
283  }
284 
285  return nullptr;
286  }
287 
290  {
291  areaToLinks.clear();
292  for (auto& area: pStudy.areas)
293  {
294  auto a = area.second;
295  std::for_each(pLink.begin(),
296  pLink.end(),
297  [&a, this](std::shared_ptr<linkInfo> edgeP)
298  {
299  if (edgeP->ptr->from == a || edgeP->ptr->with == a)
300  {
301  this->areaToLinks[a].insert(edgeP.get());
302  }
303  });
304  }
305  }
306 
307  linkInfo* getLink(uint i)
308  {
309  if (i < pLink.size())
310  {
311  return pLink[i].get();
312  }
313  return nullptr;
314  }
315 
316  size_t linkCount()
317  {
318  return pLink.size();
319  }
320 
321  bool isCycleDriver(linkInfo*);
322 
323  uint cycleCount(linkInfo* lnkI);
324 
328  bool createConstraints(const std::vector<Vector>&);
329 
330  double setInfinite(const long value)
331  {
332  return infiniteSecondMember = value;
333  }
334 
335  bool setCheckNodalLoopFlow(const bool value)
336  {
337  return checkNodalLoopFlow = value;
338  }
339 
340  bool setLoopFlowInclusion(const bool value)
341  {
342  return includeLoopFlow = value;
343  }
344 
345  bool setPhaseShiftInclusion(const bool value)
346  {
347  return includePhaseShift = value;
348  }
349 
350  double getInfinite()
351  {
352  return infiniteSecondMember;
353  }
354 
355  bool getCheckNodalLoopFlow()
356  {
357  return checkNodalLoopFlow;
358  }
359 
360  bool getLoopFlowInclusion()
361  {
362  return includeLoopFlow;
363  }
364 
365  bool getPhaseShiftInclusion()
366  {
367  return includePhaseShift;
368  }
369 
370  bool setUpToDate(const bool value)
371  {
372  return isUpToDate = value;
373  }
374 
375  bool getUpToDate()
376  {
377  return isUpToDate;
378  }
379 
380  bool update();
381 
382  bool updateLinks();
383 
384  bool checkValidityOfNodalLoopFlow(linkInfo* linkInfo, size_t hour);
385 
386  void updateLinkPhaseShift(linkInfo* linkInfo, size_t hour) const;
387  bool checkLinkPhaseShift(linkInfo* linkInfo, size_t hour) const;
388 
389  void setCalendarStart(int start)
390  {
391  calendarStart = start;
392  }
393 
394  void setCalendarEnd(int end)
395  {
396  calendarEnd = end;
397  }
398 
399  uint getCalendarStart()
400  {
401  return calendarStart;
402  }
403 
404  uint getCalendarEnd()
405  {
406  return calendarEnd;
407  }
408 
409 private:
413  std::shared_ptr<Antares::Data::BindingConstraint> addConstraint(
414  const Data::ConstraintName& name,
415  const Yuni::String& op,
416  const Yuni::String& type,
417  const WeightMap& weights,
418  const double& secondMember);
419 
420 public:
421  std::vector<std::shared_ptr<linkInfo>> pLink;
422 
423 private:
424  std::string pPrefix;
425  std::string pPrefixDelete;
426  bool pDelete;
427  bool includeLoopFlow = true;
428  bool includePhaseShift = true;
429  bool isUpToDate = false;
430  bool checkNodalLoopFlow = true;
431  double infiniteSecondMember = 1000000;
432 
433  uint calendarStart = 1;
434  uint calendarEnd = 8760;
435 
436  std::vector<std::vector<linkInfo*>> pMesh;
437 
438  std::map<Data::Area*, std::set<linkInfo*>> areaToLinks;
439 
440  Antares::Data::Study& pStudy;
441 
443 
444 }; // class cbuilder
445 
446 } // namespace Antares
447 
448 #endif // __ANTARES_CONSTRAINTSBUILDER_BUILDER_CBUILDER_H__
Definition: cbuilder.h:218
linkInfo * findLinkInfoFromNodeNames(Data::AreaName &u, Data::AreaName &v)
find an edge from node names
Definition: cbuilder.h:261
~CBuilder()=default
Destructor.
bool completeFromStudy()
Complete the settings with the data from the study.
Definition: load.cpp:27
void buildAreaToLinkInfosMap()
build list of edges from area
Definition: cbuilder.h:289
int alreadyExistingNetworkConstraints(const Yuni::String &prefix) const
check if network constraints already exists in the study
Definition: cbuilder.cpp:460
CBuilder(Antares::Data::Study &)
Default constructor.
Definition: cbuilder.cpp:49
bool runConstraintsBuilder(bool standalone=false)
Independent function to run the constraint generator from a study.
Definition: cbuilder.cpp:283
bool deletePreviousConstraints()
Delete the network constraints.
Definition: cbuilder.cpp:304
Definition: cbuilder.h:136
Definition for a single area.
Definition: area.h:51
Definition: study.h:57
AreaList areas
All available areas.
Definition: study.h:524
void fillColumn(uint x, const T &value)
Set a entire column with a given value.
Definition: matrix.hxx:491
Definition: cbuilder.h:120
Definition: cbuilder.h:36
Definition: cbuilder.h:55
Definition: cbuilder.h:94
Definition: cbuilder.h:78