source: XIOS/trunk/src/node/calendar_wrapper.cpp @ 1542

Last change on this file since 1542 was 1542, checked in by oabramkina, 6 years ago

Replacing Boost's unordered_map and shared_pointer by its STL counterparts.

Two notes for Curie:

  • one can see the content of unordered_map with ddt only if XIOS has been compiled with gnu
  • XIOS will not compile any more with pgi (all available versions use old STL which are not up to the c++11 norms)
File size: 6.7 KB
Line 
1#include "calendar_wrapper.hpp"
2#include "type.hpp"
3#include "calendar_type.hpp"
4#include "duration.hpp"
5#include "context.hpp"
6
7namespace xios {
8
9  /// ////////////////////// Définitions ////////////////////// ///
10
11  CCalendarWrapper::CCalendarWrapper(void)
12    : CObjectTemplate<CCalendarWrapper>(), CCalendarWrapperAttributes()
13  { /* Ne rien faire de plus */ }
14
15  CCalendarWrapper::CCalendarWrapper(const StdString & id)
16    : CObjectTemplate<CCalendarWrapper>(id), CCalendarWrapperAttributes()
17  { /* Ne rien faire de plus */ }
18
19  CCalendarWrapper::~CCalendarWrapper(void)
20  {}
21
22  //----------------------------------------------------------------
23
24  StdString CCalendarWrapper::GetName(void)    { return StdString("calendar_wrapper"); }
25  StdString CCalendarWrapper::GetDefName(void) { return StdString("calendar"); }
26  ENodeType CCalendarWrapper::GetType(void)    { return eCalendarWrapper; }
27
28  //----------------------------------------------------------------
29
30  /*!
31  \brief Extract the calendar from its wrapper
32  \return the calendar
33  */
34  std::shared_ptr<CCalendar> CCalendarWrapper::getCalendar(bool checkValid /*= false*/) const
35  {
36    if (checkValid && !this->calendar)
37      ERROR("CCalendarWrapper::getCalendar(bool checkValid = true)", << "The calendar was accessed before being created!");
38    return this->calendar;
39  }
40
41  const CDate& CCalendarWrapper::getInitDate() const
42  {
43    return getCalendar(true)->getInitDate();
44  }
45
46  const CDate& CCalendarWrapper::getTimeOrigin() const
47  {
48    return getCalendar(true)->getTimeOrigin();
49  }
50
51  //----------------------------------------------------------------
52
53  void CCalendarWrapper::setInitDate(const CDate& initDate)
54  {
55    getCalendar(true)->setInitDate(initDate);
56    start_date = initDate.toString();
57  }
58
59  void CCalendarWrapper::setTimeOrigin(const CDate& timeOrigin)
60  {
61    getCalendar(true)->setTimeOrigin(timeOrigin);
62    time_origin = timeOrigin.toString();
63  }
64
65  //----------------------------------------------------------------
66
67  /*!
68  \brief Parse the calendar node
69  \param [in] node xmld node corresponding to the calendar definition
70  */
71  void CCalendarWrapper::parse(xml::CXMLNode& node)
72  {
73    SuperClass::parse(node);
74
75    // Try to create the calendar
76    createCalendar();
77  }
78
79  /*!
80  \brief Try to create the calendar from the parsed attributes
81  */
82  void CCalendarWrapper::createCalendar(void)
83  {
84    // Create the calendar if possible
85    if (calendar)
86    {
87      ERROR("CCalendarWrapper::createCalendar(void)",
88            << "Error: the calendar can only be defined once!");
89    }
90    else if (!type.isEmpty())
91    {
92#define DECLARE_CALENDAR(MType, eType)                                     \
93      if (type.getValue() == type_attr::eType)                             \
94        calendar = std::shared_ptr<CCalendar>(new C##MType##Calendar());
95#include "calendar_type.conf"
96#undef DECLARE_CALENDAR
97      // Special case for the user defined calendar
98      if (type.getValue() == type_attr::user_defined)
99      {
100        if (day_length.isEmpty())
101          ERROR("CCalendarWrapper::createCalendar(void)",
102                << "The day length must be configured when using an user defined calendar.");
103        if (month_lengths.isEmpty() == year_length.isEmpty())
104          ERROR("CCalendarWrapper::createCalendar(void)",
105                << "Either the month lengths or the year length must be configured when using an user defined calendar.");
106        if (leap_year_drift.isEmpty() != leap_year_month.isEmpty())
107          ERROR("CCalendarWrapper::createCalendar(void)",
108                << "Both leap_year_drift and leap_year_month attributes must be set if you wish to configure leap years.");
109        if (leap_year_drift.isEmpty() && !leap_year_drift_offset.isEmpty())
110          ERROR("CCalendarWrapper::createCalendar(void)",
111                << "Both leap_year_drift and leap_year_month attributes are mandatory if you wish to use leap_year_drift_offset attribute.");
112
113        std::shared_ptr<CUserDefinedCalendar> userDefinedCalendar;
114        if (year_length.isEmpty())
115          userDefinedCalendar.reset(new CUserDefinedCalendar(day_length.getValue(), month_lengths.getValue()));
116        else
117          userDefinedCalendar.reset(new CUserDefinedCalendar(day_length.getValue(), year_length.getValue()));
118
119        if (!leap_year_month.isEmpty())
120          userDefinedCalendar->configureLeapYear(leap_year_month.getValue(),
121                                                 leap_year_drift.getValue(),
122                                                 leap_year_drift_offset.isEmpty() ? 0.0 : leap_year_drift_offset.getValue());
123
124        calendar = userDefinedCalendar;
125      }
126      else
127      {
128#define CHECK_EMPTY(attr)                                                                       \
129        if (!attr.isEmpty())                                                                    \
130          ERROR("CCalendarWrapper::createCalendar(void)",                                       \
131                << "The attribute \"" #attr "\" can only be used with user defined calendar.");
132        CHECK_EMPTY(day_length)
133        CHECK_EMPTY(month_lengths)
134        CHECK_EMPTY(year_length)
135        CHECK_EMPTY(leap_year_month)
136        CHECK_EMPTY(leap_year_drift)
137        CHECK_EMPTY(leap_year_drift_offset)
138#undef CHECK_EMPTY
139      }
140
141      if (!calendar)
142        ERROR("CCalendarWrapper::createCalendar(void)",
143              << "[ type = " << type.getStringValue() << " ] "
144              << "The calendar is not properly handled!");
145
146      // Set the timestep is available
147      if (!timestep.isEmpty())
148        calendar->setTimeStep(timestep.getValue());
149
150      // Parse and set the start date if available
151      if (!start_date.isEmpty())
152        calendar->setInitDate(CDate::FromString(start_date.getValue(), *calendar));
153
154      // Parse and set the time origin if available
155      if (!time_origin.isEmpty())
156        calendar->setTimeOrigin(CDate::FromString(time_origin.getValue(), *calendar));
157
158      // Notify the context about the calendar
159      CContext* context = CContext::getCurrent();
160      if (!context)
161        ERROR("CCalendarWrapper::createCalendar(void)", << "Impossible to set the calendar: no current context available.");
162      context->setCalendar(calendar);
163    }
164    else if (!start_date.isEmpty() || !time_origin.isEmpty())
165    {
166      ERROR("CCalendarWrapper::createCalendar(void)",
167            << "The calendar type must be set before defining the start date or the time origin!");
168    }
169  }
170
171  /*!
172  \brief Try to update the timestep of the calendar with the corresponding attribute
173  */
174  void CCalendarWrapper::updateTimestep(void)
175  {
176    if (timestep.isEmpty())
177    {
178      ERROR("CCalendarWrapper::updateTimestep(void)",
179            << "Error: the timestep needs to be defined!");
180    }
181    else if (calendar)
182      calendar->setTimeStep(timestep.getValue());
183  }
184}
Note: See TracBrowser for help on using the repository browser.