Antares Simulator
Power System Simulator
area.hxx
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 __SOLVER_VARIABLE_AREA_HXX__
22 #define __SOLVER_VARIABLE_AREA_HXX__
23 
24 #include <antares/study/filter.h>
25 #include "antares/solver/variable/economy/dispatchable-generation-margin.h"
26 
27 namespace Antares::Solver::Variable
28 {
29 template<class NextT>
31 {
32  // Do nothing
33 }
34 
35 template<class NextT>
37 {
38  // Nothing to do here
39  // This method is called by initializeFromStudy() to all children
40 }
41 
42 template<class NextT>
43 inline void Areas<NextT>::initializeFromAreaLink(Data::Study*, Data::AreaLink*)
44 {
45  // Nothing to do here
46 }
47 
48 template<class NextT>
49 inline void Areas<NextT>::initializeFromThermalCluster(Data::Study*,
50  Data::Area*,
52 {
53  // This method should not be called at this point
54 }
55 
56 template<class NextT>
57 void Areas<NextT>::buildSurveyReport(SurveyResults& results,
58  int dataLevel,
59  int fileLevel,
60  int precision) const
61 {
62  int count_int = count;
63  bool linkDataLevel = dataLevel & Category::DataLevel::link;
64  bool areaDataLevel = dataLevel & Category::DataLevel::area;
65  bool thermalAggregateDataLevel = dataLevel & Category::DataLevel::thermalAggregate;
66  if (count_int && (linkDataLevel || areaDataLevel || thermalAggregateDataLevel))
67  {
68  assert(results.data.area != NULL
69  && "The area must not be null to generate a survey report");
70 
71  // Build the survey results for the given area
72  auto& area = *results.data.area;
73 
74  // Filtering
75  if (0 == (dataLevel & Category::DataLevel::link)) // filter on all but links
76  {
77  switch (precision)
78  {
79  case Category::hourly:
80  if (not(area.filterSynthesis & Data::filterHourly))
81  {
82  return;
83  }
84  break;
85  case Category::daily:
86  if (not(area.filterSynthesis & Data::filterDaily))
87  {
88  return;
89  }
90  break;
91  case Category::weekly:
92  if (not(area.filterSynthesis & Data::filterWeekly))
93  {
94  return;
95  }
96  break;
97  case Category::monthly:
98  if (not(area.filterSynthesis & Data::filterMonthly))
99  {
100  return;
101  }
102  break;
103  case Category::annual:
104  if (not(area.filterSynthesis & Data::filterAnnual))
105  {
106  return;
107  }
108  break;
109  case Category::all:
110  break;
111  }
112  }
113  pAreas[area.index].buildSurveyReport(results, dataLevel, fileLevel, precision);
114  }
115 }
116 
117 template<class NextT>
118 void Areas<NextT>::buildAnnualSurveyReport(SurveyResults& results,
119  int dataLevel,
120  int fileLevel,
121  int precision,
122  uint numSpace) const
123 {
124  int count_int = count;
125  bool linkDataLevel = dataLevel & Category::DataLevel::link;
126  bool areaDataLevel = dataLevel & Category::DataLevel::area;
127  bool thermalAggregateDataLevel = dataLevel & Category::DataLevel::thermalAggregate;
128  if (count_int && (linkDataLevel || areaDataLevel || thermalAggregateDataLevel))
129  {
130  assert(results.data.area != NULL
131  && "The area must not be null to generate a survey report");
132 
133  auto& area = *results.data.area;
134 
135  // Filtering
136  if (0 == (dataLevel & Category::DataLevel::link)) // filter on all but links
137  {
138  switch (precision)
139  {
140  case Category::hourly:
141  if (!(area.filterYearByYear & Data::filterHourly))
142  {
143  return;
144  }
145  break;
146  case Category::daily:
147  if (!(area.filterYearByYear & Data::filterDaily))
148  {
149  return;
150  }
151  break;
152  case Category::weekly:
153  if (!(area.filterYearByYear & Data::filterWeekly))
154  {
155  return;
156  }
157  break;
158  case Category::monthly:
159  if (!(area.filterYearByYear & Data::filterMonthly))
160  {
161  return;
162  }
163  break;
164  case Category::annual:
165  if (!(area.filterYearByYear & Data::filterAnnual))
166  {
167  return;
168  }
169  break;
170  case Category::all:
171  break;
172  }
173  }
174 
175  // Build the survey results for the given area
176  pAreas[area.index].buildAnnualSurveyReport(results,
177  dataLevel,
178  fileLevel,
179  precision,
180  numSpace);
181  }
182 }
183 
184 template<class NextT>
185 void Areas<NextT>::buildDigest(SurveyResults& results, int digestLevel, int dataLevel) const
186 {
187  int count_int = count;
188  if (count_int)
189  {
190  if (dataLevel & Category::DataLevel::area)
191  {
192  assert(pAreaCount == results.data.study.areas.size());
193 
194  // Reset captions
195  results.data.rowCaptions.clear();
196  results.data.rowCaptions.resize(pAreaCount);
197 
198  // For each area
199  // for (uint i = 0; i != results.data.study.areas.byIndex.size(); ++i)
200  for (uint i = 0; i != pAreaCount; ++i)
201  {
202  results.data.area = results.data.study.areas[i];
203  uint index = results.data.area->index;
204  results.data.rowIndex = index;
205  results.data.rowCaptions[index] = results.data.area->id;
206  results.data.columnIndex = 0;
207  results.resetValuesAtLine(i);
208  pAreas[i].buildDigest(results, digestLevel, dataLevel);
209  }
210  }
211  }
212 }
213 
214 template<class NextT>
215 template<class PredicateT>
216 inline void Areas<NextT>::RetrieveVariableList(PredicateT& predicate)
217 {
218  NextType::RetrieveVariableList(predicate);
219 }
220 
221 template<class NextT>
222 template<class I>
223 inline void Areas<NextT>::provideInformations(I& infos)
224 {
225  // Begining of the node
226  if (VCardType::nodeDepthForGUI)
227  {
228  infos.template beginNode<VCardType>();
229  // Next variable in the list
230  NextType::template provideInformations<I>(infos);
231  // End of the node
232  infos.endNode();
233  }
234  else
235  {
236  // Giving our VCard
237  infos.template addVCard<VCardType>();
238  // Next variable in the list
239  NextType::template provideInformations<I>(infos);
240  }
241 }
242 
243 template<class NextT>
244 template<class SearchVCardT, class O>
245 inline void Areas<NextT>::computeSpatialAggregateWith(O&)
246 {
247  // Do nothing
248 }
249 
250 template<class NextT>
251 template<class SearchVCardT, class O>
252 inline void Areas<NextT>::computeSpatialAggregateWith(O& out, const Data::Area* area, uint numSpace)
253 {
254  assert(NULL != area);
255  pAreas[area->index].template computeSpatialAggregateWith<SearchVCardT, O>(out, numSpace);
256 }
257 
258 template<class NextT>
259 template<class VCardToFindT>
260 const double* Areas<NextT>::retrieveHourlyResultsForCurrentYear() const
261 {
262  return nullptr;
263 }
264 
265 template<class NextT>
266 template<class VCardToFindT>
267 inline void Areas<NextT>::retrieveResultsForArea(
268  typename Storage<VCardToFindT>::ResultsType** result,
269  const Data::Area* area)
270 {
271  pAreas[area->index].template retrieveResultsForArea<VCardToFindT>(result, area);
272 }
273 
274 template<class NextT>
275 template<class VCardToFindT>
276 inline void Areas<NextT>::retrieveResultsForThermalCluster(
277  typename Storage<VCardToFindT>::ResultsType** result,
278  const Data::ThermalCluster* cluster)
279 {
280  pAreas[cluster->parentArea->index]
281  .template retrieveResultsForThermalCluster<VCardToFindT>(result, cluster);
282 }
283 
284 template<class NextT>
285 template<class VCardToFindT>
286 inline void Areas<NextT>::retrieveResultsForLink(
287  typename Storage<VCardToFindT>::ResultsType** result,
288  const Data::AreaLink* link)
289 {
290  pAreas[link->from->index].template retrieveResultsForLink<VCardToFindT>(result, link);
291 }
292 
293 template<class NextT>
295 {
296  // Releasing the memory occupied by the areas
297  delete[] pAreas;
298 }
299 
300 template<class NextT>
302 {
303  // The total number of areas
304  pAreaCount = study.areas.size();
305 
306  // Reserving the memory
307  pAreas = new NextType[pAreaCount];
308 
309  // For each area...
310  uint tick = 6;
311  uint oldPercent = 0;
312  for (uint i = 0; i != pAreaCount; ++i)
313  {
314  // Instancing a new set of variables of the area
315  auto* currentArea = study.areas.byIndex[i];
316  if (!(--tick))
317  {
318  uint newPercent = ((i * 100u) / pAreaCount);
319  if (newPercent != oldPercent)
320  {
321  logs.info() << "Allocating resources " << ((i * 100u) / pAreaCount) << "%";
322  oldPercent = newPercent;
323  }
324  // Reset the tick
325  tick = 6;
326  }
327 
328  // Initialize the variables
329  // From the study
330  pAreas[i].initializeFromStudy(study);
331  // From the area
332  pAreas[i].initializeFromArea(&study, currentArea);
333  // Does current output variable appears non applicable in areas' output files, not
334  // districts'. Note that digest gather area and district results.
335  pAreas[i].broadcastNonApplicability(not currentArea->hydro.reservoirManagement);
336 
337  // For each current area's variable, getting the print status, that is :
338  // is variable's column(s) printed in output (areas) reports ?
339  pAreas[i].getPrintStatusFromStudy(study);
340 
341  pAreas[i].supplyMaxNumberOfColumns(study);
342  }
343 }
344 
345 template<class NextT>
346 void Areas<NextT>::simulationBegin()
347 {
348  for (uint i = 0; i != pAreaCount; ++i)
349  {
350  pAreas[i].simulationBegin();
351  }
352 }
353 
354 template<class NextT>
355 void Areas<NextT>::simulationEnd()
356 {
357  for (uint i = 0; i != pAreaCount; ++i)
358  {
359  pAreas[i].simulationEnd();
360  }
361 }
362 
363 template<class NextT>
364 void Areas<NextT>::hourForEachArea(State& state, uint numSpace)
365 {
366  // For each area...
367  state.study.areas.each(
368  [this, &state, &numSpace](Data::Area& area)
369  {
370  state.area = &area; // the current area
371 
372  // Initializing the state for the current area
373  state.initFromAreaIndex(area.index, numSpace);
374 
375  for (const auto& cluster: area.thermal.list.each_enabled())
376  {
377  // Intiializing the state for the current thermal cluster
378  state.initFromThermalClusterIndex(cluster->enabledIndex);
379  }
380 
381  // Variables
382  auto& variablesForArea = pAreas[area.index];
383  variablesForArea.hourForEachArea(state, numSpace);
384 
385  // All links
386  auto end = area.links.end();
387  for (auto i = area.links.begin(); i != end; ++i)
388  {
389  state.link = i->second;
390  // Variables
391  variablesForArea.hourForEachLink(state, numSpace);
392  }
393  }); // for each area
394 }
395 
396 template<class NextT>
397 void Areas<NextT>::weekForEachArea(State& state, uint numSpace)
398 {
399  // For each area...
400  state.study.areas.each(
401  [this, &state, &numSpace](Data::Area& area)
402  {
403  state.area = &area; // the current area
404 
405  // Initializing the state for the current area
406  state.initFromAreaIndex(area.index, numSpace);
407 
408  auto& variablesForArea = pAreas[area.index];
409 
410  // DTG MRG
411  state.dispatchableMargin = variablesForArea.template retrieveHourlyResultsForCurrentYear<
412  Economy::VCardDispatchableGenMargin>(numSpace);
413 
414  variablesForArea.weekForEachArea(state, numSpace);
415 
416  // NOTE
417  // currently, the event is not broadcasted to thermal
418  // clusters and links
419  }); // for each area
420 }
421 
422 template<class NextT>
423 void Areas<NextT>::yearBegin(uint year, uint numSpace)
424 {
425  for (uint i = 0; i != pAreaCount; ++i)
426  {
427  pAreas[i].yearBegin(year, numSpace);
428  }
429 }
430 
431 template<class NextT>
432 void Areas<NextT>::yearEndBuild(State& state, uint year, uint numSpace)
433 {
434  // For each area...
435  state.study.areas.each(
436  [this, &state, &year, &numSpace](Data::Area& area)
437  {
438  state.area = &area; // the current area
439 
440  // Initializing the state for the current area
441  state.initFromAreaIndex(area.index, numSpace);
442 
443  // Variables
444  auto& variablesForArea = pAreas[area.index];
445 
446  for (const auto& cluster: area.thermal.list.each_enabled())
447  {
448  state.thermalCluster = cluster.get();
449  state.yearEndResetThermal();
450 
451  // Variables
452  variablesForArea.yearEndBuildPrepareDataForEachThermalCluster(state, year, numSpace);
453 
454  // Building the end of year
455  state.yearEndBuildFromThermalClusterIndex(cluster->enabledIndex);
456 
457  // Variables
458  variablesForArea.yearEndBuildForEachThermalCluster(state, year, numSpace);
459  } // for each thermal cluster
460  }); // for each area
461 }
462 
463 template<class NextT>
464 void Areas<NextT>::yearEnd(uint year, uint numSpace)
465 {
466  for (uint i = 0; i != pAreaCount; ++i)
467  {
468  // Broadcast to all areas
469  pAreas[i].yearEnd(year, numSpace);
470  }
471 }
472 
473 template<class NextT>
474 void Areas<NextT>::computeSummary(unsigned int year, unsigned int numSpace)
475 {
476  for (uint i = 0; i != pAreaCount; ++i)
477  {
478  // Broadcast to all areas
479  pAreas[i].computeSummary(year, numSpace);
480  }
481 }
482 
483 template<class NextT>
484 void Areas<NextT>::weekBegin(State& state)
485 {
486  for (uint i = 0; i != pAreaCount; ++i)
487  {
488  pAreas[i].weekBegin(state);
489  }
490 }
491 
492 template<class NextT>
493 void Areas<NextT>::weekEnd(State& state)
494 {
495  for (uint i = 0; i != pAreaCount; ++i)
496  {
497  pAreas[i].weekEnd(state);
498  }
499 }
500 
501 template<class NextT>
502 void Areas<NextT>::hourBegin(uint hourInTheYear)
503 {
504  for (uint i = 0; i != pAreaCount; ++i)
505  {
506  pAreas[i].hourBegin(hourInTheYear);
507  }
508 }
509 
510 template<class NextT>
511 void Areas<NextT>::hourForEachLink(State& state, uint numSpace)
512 {
513  for (uint i = 0; i != pAreaCount; ++i)
514  {
515  pAreas[i].hourForEachLink(state, numSpace);
516  }
517 }
518 
519 template<class NextT>
520 void Areas<NextT>::hourEnd(State& state, uint hourInTheYear)
521 {
522  for (uint i = 0; i != pAreaCount; ++i)
523  {
524  pAreas[i].hourEnd(state, hourInTheYear);
525  }
526 }
527 
528 template<class NextT>
529 void Areas<NextT>::beforeYearByYearExport(uint year, uint numSpace)
530 {
531  for (uint i = 0; i != pAreaCount; ++i)
532  {
533  pAreas[i].beforeYearByYearExport(year, numSpace);
534  }
535 }
536 } // namespace Antares::Solver::Variable
537 
538 #endif // __SOLVER_VARIABLE_AREA_HXX__
Definition for a single area.
Definition: area.h:51
uint index
Index of the area - only valid when already added to an area list.
Definition: area.h:216
Area * parentArea
The associate area (alias)
Definition: cluster.h:111
Definition: study.h:57
A single thermal cluster.
Definition: cluster.h:76
Areas()
Default Constructor.
Definition: area.hxx:30
static void RetrieveVariableList(PredicateT &predicate)
Retrieve the list of all individual variables.
Definition: area.hxx:216
~Areas()
Destructor.
Definition: area.hxx:294
Definition: cbuilder.h:120
VariableAccessor< typename VCardT::ResultsType, VCardT::columnCount >::Type ResultsType
The true type used for the results.
Definition: info.h:760