Antares Simulator
Power System Simulator
Loading...
Searching...
No Matches
info.h
1/*
2** Copyright 2007-2024, 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_INFO_H__
22#define __SOLVER_VARIABLE_INFO_H__
23
24#include <cmath>
25
26#include "antares/solver/variable/surveyresults.h"
27#include "antares/study/fwd.h"
28
29namespace Antares
30{
31namespace Solver
32{
33namespace Variable
34{
35template<class T>
37{
38 typedef T Type;
39};
40
41template<class T, int N>
42struct SpecifierRemover<T[N]>
43{
44 typedef T Type;
45};
46
47template<class T>
49{
50 typedef T Type;
51};
52
53template<class T, int N>
54struct SpecifierRemover<const T[N]>
55{
56 typedef T Type;
57};
58
59template<class T>
60struct SpecifierRemover<const T*>
61{
62 typedef T Type;
63};
64
65template<class ResultsT, int ColumnCountT>
67{
68 typedef typename SpecifierRemover<ResultsT>::Type CleanType;
69 typedef CleanType Type[ColumnCountT];
70
71 template<class U>
72 static void MultiplyHourlyResultsBy(U& intermediateValues, const double v)
73 {
74 assert(!std::isnan(v));
75 for (uint i = 0; i != ColumnCountT; ++i)
76 {
77 Antares::Memory::Stored<double>::ReturnType array = intermediateValues[i].hour;
78 for (uint y = 0; y != HOURS_PER_YEAR; ++y)
79 {
80 array[y] *= v;
81 }
82 }
83 }
84
85 template<class U>
86 static void SetTo1IfPositive(U& intermediateValues)
87 {
88 for (uint i = 0; i != ColumnCountT; ++i)
89 {
90 Antares::Memory::Stored<double>::ReturnType array = intermediateValues[i].hour;
91 for (uint y = 0; y != HOURS_PER_YEAR; ++y)
92 {
93 array[y] = std::abs(array[y]) > 0. ? 1. : 0.;
94 }
95 }
96 }
97
98 template<class U>
99 static void Or(U& intermediateValues)
100 {
101 for (uint i = 0; i != ColumnCountT; ++i)
102 {
103 Antares::Memory::Stored<double>::ReturnType array = intermediateValues[i].hour;
104 for (uint y = 0; y != HOURS_PER_YEAR; ++y)
105 {
106 array[y] = std::abs(array[y]) > 0. ? 100. : 0.;
107 }
108 }
109 }
110
111 template<class U>
112 static void InitializeAndReset(U& out, Data::Study& study)
113 {
114 for (uint i = 0; i != ColumnCountT; ++i)
115 {
116 out[i].initializeFromStudy(study);
117 out[i].reset();
118 }
119 }
120
121 template<class U>
122 static void Reset(U& out)
123 {
124 for (uint i = 0; i != ColumnCountT; ++i)
125 {
126 out[i].reset();
127 }
128 }
129
130 template<class VCardT, class U>
131 static void ComputeStatistics(U& intermediateValues)
132 {
133 for (uint i = 0; i != ColumnCountT; ++i)
134 {
135 // Compute all statistics for the current year (daily,weekly,monthly)
136 if (VCardT::spatialAggregate & Category::spatialAggregateOr)
137 {
138 intermediateValues[i].computeStatisticsOrForTheCurrentYear();
139 }
140 else
141 {
142 if (VCardT::spatialAggregatePostProcessing
143 == (int)Category::spatialAggregatePostProcessingPrice)
144 {
145 intermediateValues[i].computeAveragesForCurrentYearFromHourlyResults();
146 }
147 else
148 {
149 intermediateValues[i].computeStatisticsForTheCurrentYear();
150 }
151 }
152 }
153 }
154
155 template<class U>
156 static void ComputeSummary(U& intermediateValues, Type& container, uint year)
157 {
158 for (uint i = 0; i != ColumnCountT; ++i)
159 {
160 // Merge all those values with the global results
161 container[i].merge(year, intermediateValues[i]);
162 }
163 }
164
165 template<class VCardT>
166 static void BuildDigest(SurveyResults& results,
167 const Type& container,
168 int digestLevel,
169 int dataLevel)
170 {
171 for (uint i = 0; i != ColumnCountT; ++i)
172 {
173 if (*results.isPrinted)
174 {
175 results.variableCaption = VCardT::Multiple::Caption(i);
176 results.variableUnit = VCardT::Multiple::Unit(i);
177 container[i].template buildDigest<VCardT>(results, digestLevel, dataLevel);
178 }
179 // Shift to the next internal variable's non applicable status and print status
180 results.isCurrentVarNA++;
181 results.isPrinted++;
182 }
183 }
184
185 template<class VCardType>
186 static void BuildSurveyReport(SurveyResults& results,
187 const Type& container,
188 int dataLevel,
189 int fileLevel,
190 int precision)
191 {
192 for (uint i = 0; i != ColumnCountT; ++i)
193 {
194 if (*results.isPrinted)
195 {
196 results.variableCaption = VCardType::Multiple::Caption(i);
197 results.variableUnit = VCardType::Multiple::Unit(i);
198 container[i].template buildSurveyReport<ResultsT, VCardType>(results,
199 container[i],
200 dataLevel,
201 fileLevel,
202 precision);
203 }
204 // Shift to the next internal variable's non applicable status and print status
205 results.isCurrentVarNA++;
206 results.isPrinted++;
207 }
208 }
209
210 template<class VCardType>
211 static void BuildAnnualSurveyReport(SurveyResults& results,
212 const Type& container,
213 int fileLevel,
214 int precision)
215 {
216 for (uint i = 0; i != ColumnCountT; ++i)
217 {
218 if (*results.isPrinted)
219 {
220 results.variableCaption = VCardType::Multiple::Caption(i);
221 container[i].template buildAnnualSurveyReport<VCardType>(results,
222 fileLevel,
223 precision);
224 }
225 // Shift to the next internal variable's non applicable status and print status
226 results.isCurrentVarNA++;
227 results.isPrinted++;
228 }
229 }
230
231 template<class U, class VarT>
232 static void ComputeSum(U& out, const VarT& var, uint numSpace)
233 {
234 for (uint i = 0; i != ColumnCountT; ++i)
235 {
236 Antares::Memory::Stored<double>::ConstReturnType src
237 = var.retrieveRawHourlyValuesForCurrentYear(i, numSpace);
238
239 assert(src != NULL);
240 for (uint h = 0; h != HOURS_PER_YEAR; ++h)
241 {
242 out[i].hour[h] += src[h];
243 }
244 }
245 }
246
247 template<class U, class VarT>
248 static void ComputeMax(U& out, const VarT& var, uint numSpace)
249 {
250 for (uint i = 0; i != ColumnCountT; ++i)
251 {
252 Antares::Memory::Stored<double>::ConstReturnType src
253 = var.retrieveRawHourlyValuesForCurrentYear(i, numSpace);
254
255 assert(src != NULL);
256 for (uint h = 0; h != HOURS_PER_YEAR; ++h)
257 {
258 if (out[i].hour[h] < src[h])
259 {
260 out[i].hour[h] = src[h];
261 }
262 }
263 }
264 }
265};
266
267template<class ResultsT>
268struct VariableAccessor<ResultsT, Category::dynamicColumns>
269{
270 typedef typename SpecifierRemover<ResultsT>::Type CleanType;
271 typedef std::vector<CleanType> Type;
272
273 template<class U>
274 static void MultiplyHourlyResultsBy(U& intermediateValues, const double v)
275 {
276 assert(!std::isnan(v));
277 double* array;
278 const typename Type::const_iterator end = intermediateValues.end();
279 for (typename Type::const_iterator i = intermediateValues.begin(); i != end; ++i)
280 {
281 array = (*i).hour;
282 for (uint y = 0; y != HOURS_PER_YEAR; ++y)
283 {
284 array[y] *= v;
285 }
286 }
287 }
288
289 template<class U>
290 static void SetTo1IfPositive(U& intermediateValues)
291 {
292 double* array;
293 const typename Type::const_iterator end = intermediateValues.end();
294 for (typename Type::const_iterator i = intermediateValues.begin(); i != end; ++i)
295 {
296 array = (*i).hour;
297 for (uint y = 0; y != HOURS_PER_YEAR; ++y)
298 {
299 array[y] = std::abs(array[y]) > 0. ? 1. : 0.;
300 }
301 }
302 }
303
304 template<class U>
305 static void Or(U& intermediateValues)
306 {
307 double* array;
308 const typename Type::const_iterator end = intermediateValues.end();
309 for (typename Type::const_iterator i = intermediateValues.begin(); i != end; ++i)
310 {
311 array = (*i).hour;
312 for (uint y = 0; y != HOURS_PER_YEAR; ++y)
313 {
314 array[y] = std::abs(array[y]) > 0. ? 100. : 0.;
315 }
316 }
317 }
318
319 template<class U>
320 static void InitializeAndReset(U& out, Data::Study& study)
321 {
322 const typename Type::const_iterator end = out.end();
323 for (typename Type::const_iterator i = out.begin(); i != end; ++i)
324 {
325 (*i).initializeFromStudy(study);
326 (*i).reset();
327 }
328 }
329
330 template<class U>
331 static void Reset(U& out)
332 {
333 const typename Type::const_iterator end = out.end();
334 for (typename Type::const_iterator i = out.begin(); i != end; ++i)
335 {
336 (*i).reset();
337 }
338 }
339
340 template<class VCardT, class U>
341 static void ComputeStatistics(U& intermediateValues, Type& container, uint)
342 {
343 for (uint i = 0; i != container.size(); ++i)
344 {
345 if (VCardT::spatialAggregate & Category::spatialAggregateOr)
346 {
347 intermediateValues[i].computeStatisticsOrForTheCurrentYear();
348 }
349 else
350 {
351 // Compute all statistics for the current year (daily,weekly,monthly)
352 if (VCardT::spatialAggregatePostProcessing
353 == (int)Category::spatialAggregatePostProcessingPrice)
354 {
355 // intermediateValues[i].adjustValuesWhenRelatedToAPrice();
356 intermediateValues[i].computeAveragesForCurrentYearFromHourlyResults();
357 }
358 else
359 {
360 intermediateValues[i].computeStatisticsForTheCurrentYear();
361 }
362 }
363 }
364 }
365
366 template<class U>
367 static void ComputeSummary(U& intermediateValues, Type& container, uint year)
368 {
369 for (uint i = 0; i != container.size(); ++i)
370 {
371 // Merge all those values with the global results
372 container[i].merge(year, intermediateValues[i]);
373 }
374 }
375
376 template<class VCardT>
377 static void BuildDigest(SurveyResults& results,
378 const Type& container,
379 int digestLevel,
380 int dataLevel)
381 {
382 if (*results.isPrinted)
383 {
384 const Data::PartThermal& thermal = results.data.area->thermal;
385 for (uint i = 0; i != container.size(); ++i)
386 {
387 results.variableCaption = thermal.list.enabledClusterAt(i)->name();
388
389 container[i].template buildDigest<VCardT>(results, digestLevel, dataLevel);
390 }
391 }
392 }
393
394 static bool setClusterCaption(SurveyResults& results, int fileLevel, uint idx)
395 {
396 assert(results.data.area && "Area is NULL");
397 const bool thermal_details = fileLevel & Category::FileLevel::de;
398 const bool renewable_details = fileLevel & Category::FileLevel::de_res;
399 const bool st_storage_details = fileLevel & Category::FileLevel::de_sts;
400
401 std::array<bool, 3> kind_of_details = {thermal_details,
402 renewable_details,
403 st_storage_details};
404
405 // The current result file must be a detail file and of one kind only.
406 // So the vector above must contain one true. No less, no more.
407 auto how_many_kinds_of_details = std::count(kind_of_details.begin(),
408 kind_of_details.end(),
409 true);
410
411 if (how_many_kinds_of_details != 1)
412 {
413 logs.error() << "Inconsistent fileLevel detected";
414 return false;
415 }
416
417 if (thermal_details)
418 {
419 auto& thermal = results.data.area->thermal;
420 results.variableCaption = thermal.list.enabledClusterAt(idx)->name();
421 return true;
422 }
423 if (renewable_details)
424 {
425 auto& renewable = results.data.area->renewable;
426 results.variableCaption = renewable.list.enabledClusterAt(idx)->name();
427 return true;
428 }
429 if (st_storage_details)
430 {
431 auto& st_storage_part = results.data.area->shortTermStorage;
432 results.variableCaption = st_storage_part.storagesByIndex[idx].properties.name;
433 return true;
434 }
435 return true;
436 }
437
438 template<class VCardType>
439 static void BuildSurveyReport(SurveyResults& results,
440 const Type& container,
441 int dataLevel,
442 int fileLevel,
443 int precision)
444 {
445 bool res;
446 if (*results.isPrinted)
447 {
448 for (uint i = 0; i != container.size(); ++i)
449 {
450 res = setClusterCaption(results, fileLevel, i);
451 if (!res)
452 {
453 return;
454 }
455 results.variableUnit = VCardType::Unit();
456
457 container[i].template buildSurveyReport<ResultsT, VCardType>(results,
458 container[i],
459 dataLevel,
460 fileLevel,
461 precision);
462 }
463 }
464 }
465
466 template<class VCardType>
467 static void BuildAnnualSurveyReport(SurveyResults& results,
468 const Type& container,
469 int fileLevel,
470 int precision)
471 {
472 bool res;
473 if (*results.isPrinted)
474 {
475 for (uint i = 0; i != container.size(); ++i)
476 {
477 res = setClusterCaption(results, fileLevel, i);
478 if (!res)
479 {
480 return;
481 }
482 container[i].template buildAnnualSurveyReport<VCardType>(results,
483 fileLevel,
484 precision);
485 }
486 }
487 }
488
489 template<class U, class VarT>
490 static void ComputeSum(U& out, const VarT& var, uint numSpace)
491 {
492 for (uint i = 0; i != var.results().size(); ++i)
493 {
494 Antares::Memory::Stored<double>::ConstReturnType src
495 = var.retrieveRawHourlyValuesForCurrentYear(i, numSpace);
496
497 assert(src != NULL);
498 for (uint h = 0; h != HOURS_PER_YEAR; ++h)
499 {
500 out[i].hour[h] += src[h];
501 }
502 }
503 }
504
505 template<class U, class VarT>
506 static void ComputeMax(U& out, const VarT& var, uint numSpace)
507 {
508 for (uint i = 0; i != var.results().size(); ++i)
509 {
510 Antares::Memory::Stored<double>::ConstReturnType src
511 = var.retrieveRawHourlyValuesForCurrentYear(i, numSpace);
512
513 assert(src != NULL);
514 for (uint h = 0; h != HOURS_PER_YEAR; ++h)
515 {
516 if (out[i].hour[h] < src[h])
517 {
518 out[i].hour[h] = src[h];
519 }
520 }
521 }
522 }
523};
524
525template<class ResultsT>
526struct VariableAccessor<ResultsT, Category::singleColumn /* The default */>
527{
528 typedef typename SpecifierRemover<ResultsT>::Type CleanType;
529 typedef CleanType Type;
530
531 template<class U>
532 static void MultiplyHourlyResultsBy(U& intermediateValues, const double v)
533 {
534 assert(!std::isnan(v));
535 for (uint y = 0; y != HOURS_PER_YEAR; ++y)
536 {
537 intermediateValues.hour[y] *= v;
538 }
539 }
540
541 template<class U>
542 static void SetTo1IfPositive(U& intermediateValues)
543 {
544 for (uint y = 0; y != HOURS_PER_YEAR; ++y)
545 {
546 intermediateValues.hour[y] = std::abs(intermediateValues.hour[y]) > 0. ? 1. : 0.;
547 }
548 }
549
550 template<class U>
551 static void Or(U& intermediateValues)
552 {
553 for (uint y = 0; y != HOURS_PER_YEAR; ++y)
554 {
555 intermediateValues.hour[y] = std::abs(intermediateValues.hour[y]) > 0. ? 100. : 0.;
556 }
557 }
558
559 template<class U>
560 static void InitializeAndReset(U& out, Data::Study& study)
561 {
562 out.initializeFromStudy(study);
563 out.reset();
564 }
565
566 template<class U>
567 static void Reset(U& out)
568 {
569 out.reset();
570 }
571
572 template<class VCardT, class U>
573 static void ComputeStatistics(U& intermediateValues)
574 {
575 if (VCardT::spatialAggregate & Category::spatialAggregateOr)
576 {
577 intermediateValues.computeStatisticsOrForTheCurrentYear();
578 }
579 else
580 {
581 // Compute all statistics for the current year (daily,weekly,monthly)
582 if (VCardT::spatialAggregatePostProcessing
583 == (int)Category::spatialAggregatePostProcessingPrice)
584 {
585 // intermediateValues[i].adjustValuesWhenRelatedToAPrice();
586 intermediateValues.computeAveragesForCurrentYearFromHourlyResults();
587 }
588 else
589 {
590 intermediateValues.computeStatisticsForTheCurrentYear();
591 }
592 }
593 }
594
595 template<class U>
596 static void ComputeSummary(U& intermediateValues, Type& container, uint year)
597 {
598 // Merge all those values with the global results
599 container.merge(year, intermediateValues);
600 }
601
602 template<class VCardT>
603 static void BuildDigest(SurveyResults& results,
604 const Type& container,
605 int digestLevel,
606 int dataLevel)
607 {
608 if (*results.isPrinted)
609 {
610 results.variableCaption = VCardT::Caption();
611 results.variableUnit = VCardT::Unit();
612 container.template buildDigest<VCardT>(results, digestLevel, dataLevel);
613 }
614 }
615
616 template<class VCardType>
617 static void BuildSurveyReport(SurveyResults& results,
618 const Type& container,
619 int dataLevel,
620 int fileLevel,
621 int precision,
622 bool updateCaption = true)
623 {
624 if (*results.isPrinted)
625 {
626 if (updateCaption)
627 {
628 results.variableCaption = VCardType::Caption();
629 results.variableUnit = VCardType::Unit();
630 }
631 container.template buildSurveyReport<ResultsT, VCardType>(results,
632 container,
633 dataLevel,
634 fileLevel,
635 precision);
636 }
637 }
638
639 template<class VCardType>
640 static void BuildAnnualSurveyReport(SurveyResults& results,
641 const Type& container,
642 int fileLevel,
643 int precision)
644 {
645 if (*results.isPrinted)
646 {
647 results.variableCaption = VCardType::Caption();
648 results.variableUnit = VCardType::Unit();
649 container.template buildAnnualSurveyReport<VCardType>(results, fileLevel, precision);
650 }
651 }
652
653 template<class U, class VarT>
654 static void ComputeSum(U& out, const VarT& var, uint numSpace)
655 {
656 Antares::Memory::Stored<double>::ConstReturnType src
657 = var.retrieveRawHourlyValuesForCurrentYear(-1, numSpace);
658
659 assert(src != NULL);
660 for (uint h = 0; h != HOURS_PER_YEAR; ++h)
661 {
662 out.hour[h] += src[h];
663 }
664 }
665
666 template<class U, class VarT>
667 static void ComputeMax(U& out, const VarT& var, uint numSpace)
668 {
669 Antares::Memory::Stored<double>::ConstReturnType src
670 = var.retrieveRawHourlyValuesForCurrentYear(-1, numSpace);
671
672 assert(src != NULL);
673 for (uint h = 0; h != HOURS_PER_YEAR; ++h)
674 {
675 if (out.hour[h] < src[h])
676 {
677 out.hour[h] = src[h];
678 }
679 }
680 }
681};
682
683template<class ResultsT>
684struct VariableAccessor<ResultsT, Category::noColumn>
685{
686 typedef typename SpecifierRemover<ResultsT>::Type CleanType;
687 typedef CleanType Type;
688
689 template<class U>
690 static void MultiplyHourlyResultsBy(U&, const double)
691 {
692 // Do nothing
693 }
694
695 template<class U>
696 static void SetTo1IfPositive(U&)
697 {
698 }
699
700 template<class U>
701 static void Or(U&)
702 {
703 }
704
705 template<class U>
706 static void InitializeAndReset(U&, Data::Study&)
707 {
708 // Do nothing
709 }
710
711 template<class U>
712 static void Reset(U&)
713 {
714 // Do nothing
715 }
716
717 template<class VCardT, class U>
718 static void ComputeStatisticsAndMerge(U&, Type&, uint)
719 {
720 // Do nothing
721 }
722
723 static uint64_t Value(const Type&)
724 {
725 return 0;
726 }
727
728 template<class VCardType>
729 static void BuildSurveyReport(SurveyResults&, const Type&, int, int, int)
730 {
731 // Do nothing
732 }
733
734 template<class VCardType>
735 static void BuildAnnualSurveyReport(SurveyResults&, const Type&, int, int)
736 {
737 // Do nothing
738 }
739
740 template<class VCardT>
741 static void BuildDigest(SurveyResults&, const Type&, int, int)
742 {
743 // Do nothing
744 }
745
746 template<class U, class VarT>
747 static void ComputeSum(U&, const VarT&, uint)
748 {
749 // Do nothing
750 }
751
752 template<class U, class VarT>
753 static void ComputeMax(U&, const VarT&, uint)
754 {
755 // Do nothing
756 }
757};
758
759template<class VCardT>
766
767template<bool Allowed, int OperationT, class VCardT>
769{
770 template<class U, class VarT>
771 static void Perform(U&, const VarT&, uint)
772 {
773 }
774};
775
776// `+`
777template<class VCardT>
778struct SpatialAggregateOperation<true, Category::spatialAggregateSum, VCardT>
779{
780 template<class U, class VarT>
781 static void Perform(U& intermediateResults, const VarT& var, uint numSpace)
782 {
783 typedef typename VCardT::ResultsType ResultsType;
785 var,
786 numSpace);
787 }
788};
789
790// `+`
791template<class VCardT>
792struct SpatialAggregateOperation<true, Category::spatialAggregateOr, VCardT>
793{
794 template<class U, class VarT>
795 static void Perform(U& intermediateResults, const VarT& var, uint numSpace)
796 {
797 typedef typename VCardT::ResultsType ResultsType;
799 var,
800 numSpace);
801 }
802};
803
804// `+`
805template<class VCardT>
806struct SpatialAggregateOperation<true, Category::spatialAggregateSumThen1IfPositive, VCardT>
807{
808 template<class U, class VarT>
809 static void Perform(U& intermediateResults, const VarT& var, uint numSpace)
810 {
811 typedef typename VCardT::ResultsType ResultsType;
813 var,
814 numSpace);
815 }
816};
817
818// `+`
819template<class VCardT>
820struct SpatialAggregateOperation<true, Category::spatialAggregateAverage, VCardT>
821{
822 template<class U, class VarT>
823 static void Perform(U& intermediateResults, const VarT& var, uint numSpace)
824 {
825 typedef typename VCardT::ResultsType ResultsType;
827 var,
828 numSpace);
829 }
830};
831
832// `>`
833template<class VCardT>
834struct SpatialAggregateOperation<true, Category::spatialAggregateMax, VCardT>
835{
836 template<class U, class VarT>
837 static void Perform(U& intermediateResults, const VarT& var, uint numSpace)
838 {
839 typedef typename VCardT::ResultsType ResultsType;
841 var,
842 numSpace);
843 }
844};
845
846} // namespace Variable
847} // namespace Solver
848} // namespace Antares
849
850#endif // __SOLVER_VARIABLE_INFO_H__
Definition container.h:33
ThermalClusterList list
List of all thermal clusters (enabled and disabled) except must-run clusters.
Definition container.h:90
Definition study.h:61
const Data::Area * area
Current area.
Definition data.h:69
Class utility for building CSV results files.
Definition surveyresults.h:41
bool * isPrinted
Same thing for print status (do we print the current output variable ?)
Definition surveyresults.h:134
CaptionType variableCaption
Caption for the current variable.
Definition surveyresults.h:95
Solver::Variable::Private::SurveyResultsData data
Data (not related to the template parameter)
Definition surveyresults.h:92
bool * isCurrentVarNA
Definition surveyresults.h:132
Definition variable.h:25
VariableAccessor< typenameVCardT::ResultsType, VCardT::columnCount >::Type ResultsType
The true type used for the results.
Definition info.h:764