Ignore:
Timestamp:
01/26/15 14:39:26 (9 years ago)
Author:
rlacroix
Message:

Revised calendar functionalities:

  • the calendar is now configured from a specific calendar child node of the context in the XML configuration file. Example: <calendar type="Gregorian" start_date="2012-03-01 15:00:00" time_origin="2012-02-29 15:00:00" timestep="1h" />
  • the calendar type should now be configured when defining the start time and/or the time origin.
  • the start time and the time origin are now optional, 0000-01-01 00:00:00 will be used by default. It is also possible to define them partially. For example, 2015 and 2014-12 are valid dates corresponding respectively to 2015-01-01 00:00:00 and 2014-12-01 00:00:00.
  • an optional duration offset can be added to the start date and time origin. For example, it's possible to define the date 2015-01-12 12:00:00 as 2015-01-11 + 36h or 2015-01-11 12:00:00 + 1d. The duration format is the same as the time step. Being that the date is optional, it is possible to only use a duration (for example + 42s is the same as 0000-01-01 00:00:00 + 42s). An error will be raised if a duration based on the time step is used before the time step was configured. For example, the following would cause an error: <calendar type="Gregorian" start_date="+ 1ts" /> but <calendar type="Gregorian" start_date="+ 1ts" timestep="0.5h" /> would not.
  • new Fortran interface to define the calendar:
    • xios_define_calendar(type[, timestep, start_date, time_origin]) will create a calendar when none had previously been defined. Only the type argument is mandatory, the rest is optional. Calendar operations on dates and durations are possible as soon as the calendar is created (either using this procedure or directly from the XML configuration file).
    • the following getter and setter procedures are available: xios_set_timestep, xios_set_start_date, xios_set_time_origin, xios_get_calendar_type, xios_get_timestep, xios_get_start_date, xios_get_time_origin.
  • new Fortran interface to interact with the calendar: xios_update_calendar, xios_get_current_date, xios_get_year_length_in_seconds, xios_get_day_length_in_seconds.
  • new Fortran interface for date conversion: xios_date_get_second_of_year, xios_date_get_day_of_year, xios_date_get_fraction_of_year, xios_date_get_second_of_day, xios_date_get_fraction_of_day.
  • two new placeholders are available to format the file name when splitting the output (split_freq_format attribute):
    • %S the number of seconds since the time origin
    • %D the integral number of days since the time origin
File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/node/context.cpp

    r545 r549  
    1717namespace xios { 
    1818 
    19   shared_ptr<CContextGroup> CContext::root ; 
     19  shared_ptr<CContextGroup> CContext::root; 
    2020 
    2121   /// ////////////////////// Définitions ////////////////////// /// 
     
    3333   CContext::~CContext(void) 
    3434   { 
    35      if (hasClient) delete client ; 
    36      if (hasServer) delete server ; 
     35     if (hasClient) delete client; 
     36     if (hasServer) delete server; 
    3737   } 
    3838 
     
    5050   CContextGroup* CContext::getRoot(void) 
    5151   { 
    52       if (root.get()==NULL) root=shared_ptr<CContextGroup>(new CContextGroup(xml::CXMLNode::GetRootName())) ; 
     52      if (root.get()==NULL) root=shared_ptr<CContextGroup>(new CContextGroup(xml::CXMLNode::GetRootName())); 
    5353      return root.get(); 
    5454   } 
     
    7373   { 
    7474      this->calendar = newCalendar; 
    75       calendar_type.fromString(this->calendar->getId()); 
    76       start_date.setValue(this->calendar->getInitDate()); 
    77    } 
    78  
    79    //---------------------------------------------------------------- 
    80    //! Process all information of calendar 
    81    void CContext::solveCalendar(void) 
    82    { 
    83       if (calendar_type.isEmpty()) 
    84          ERROR(" CContext::solveCalendar(void)", 
    85                << "[ context id = " << this->getId() << " ] " 
    86                << "Impossible to define a calendar: the calendar type is missing."); 
    87       if (start_date.isEmpty()) 
    88          ERROR(" CContext::solveCalendar(void)", 
    89                << "[ context id = " << this->getId() << " ] " 
    90                << "Impossible to define a calendar: the start date is missing."); 
    91       if (timestep.isEmpty()) 
    92          ERROR(" CContext::solveCalendar(void)", 
    93                << "[ context id = " << this->getId() << " ] " 
    94                << "Impossible to define a calendar: the timestep is missing."); 
    95  
    96       if (this->calendar) 
    97       { 
    98         if (this->calendar->getId() != calendar_type.getStringValue() 
    99               || this->calendar->getInitDate() != start_date.getValue() 
    100               || (time_origin.isEmpty() && this->calendar->getTimeOrigin() != start_date.getValue()) 
    101               || (!time_origin.isEmpty() && this->calendar->getTimeOrigin() != time_origin.getValue()) 
    102               || this->calendar->getTimeStep() != timestep.getValue()) 
    103           ERROR(" CContext::solveCalendar(void)", 
    104                 << "[ context id = " << this->getId() << " ] " 
    105                 << "Impossible to define a calendar again with new parameters."); 
    106         return; 
    107       } 
    108  
    109 #define DECLARE_CALENDAR(MType, eType)                                             \ 
    110   if (calendar_type.getValue() == eType)                                           \ 
    111   {                                                                                \ 
    112     if (time_origin.isEmpty())                                                     \ 
    113       this->calendar = boost::shared_ptr<CCalendar>                                \ 
    114           (new C##MType##Calendar(start_date.getValue()));                         \ 
    115     else this->calendar = boost::shared_ptr<CCalendar>                             \ 
    116           (new C##MType##Calendar(start_date.getValue(), time_origin.getValue())); \ 
    117                                                                                    \ 
    118     if (!start_date.getValue().setRelCalendar(*this->calendar))                    \ 
    119       ERROR("CContext::solveCalendar(void)",                                       \ 
    120             "start_date: Bad format or date not conform to the calendar");         \ 
    121     if (!time_origin.getValue().setRelCalendar(*this->calendar))                   \ 
    122       ERROR("CContext::solveCalendar(void)",                                       \ 
    123             "time_origin: Bad format or date not conform to the calendar");        \ 
    124                                                                                    \ 
    125     this->calendar->setTimeStep(this->timestep.getValue());                        \ 
    126                                                                                    \ 
    127     return;                                                                        \ 
    128   } 
    129 #include "calendar_type.conf" 
    130 #undef DECLARE_CALENDAR 
    131  
    132       ERROR("CContext::solveCalendar(void)", 
    133             << "[ calendar_type = " << calendar_type.getStringValue() << " ] " 
    134             << "The calendar is not properly handled!"); 
    13575   } 
    13676 
     
    182122#define DECLARE_NODE(Name_, name_)    \ 
    183123   if (name.compare(C##Name_##Definition::GetDefName()) == 0) \ 
    184    { C##Name_##Definition::create(C##Name_##Definition::GetDefName()) -> parse(node) ; continue; } 
     124   { C##Name_##Definition::create(C##Name_##Definition::GetDefName()) -> parse(node); continue; } 
    185125#define DECLARE_NODE_PAR(Name_, name_) 
    186126#include "node_type.conf" 
     
    200140   void CContext::ShowTree(StdOStream & out) 
    201141   { 
    202       StdString currentContextId = CContext::getCurrent() -> getId() ; 
     142      StdString currentContextId = CContext::getCurrent() -> getId(); 
    203143      std::vector<CContext*> def_vector = 
    204144         CContext::getRoot()->getChildList(); 
     
    285225//   { 
    286226//      if (!this->hasId()) return; 
    287 //      vector<CField*> allField = CField::getAll() ; 
     227//      vector<CField*> allField = CField::getAll(); 
    288228////              = CObjectTemplate<CField>::GetAllVectobject(this->getId()); 
    289229//      std::vector<CField*>::iterator 
     
    301241   void CContext::CleanTree(void) 
    302242   { 
    303 #define DECLARE_NODE(Name_, name_) C##Name_##Group::ClearAllAttributes(); 
     243#define DECLARE_NODE(Name_, name_) C##Name_##Definition::ClearAllAttributes(); 
    304244#define DECLARE_NODE_PAR(Name_, name_) 
    305245#include "node_type.conf" 
     
    310250   void CContext::initClient(MPI_Comm intraComm, MPI_Comm interComm, CContext* cxtServer) 
    311251   { 
    312      hasClient=true ; 
    313      client = new CContextClient(this,intraComm, interComm, cxtServer) ; 
     252     hasClient=true; 
     253     client = new CContextClient(this,intraComm, interComm, cxtServer); 
    314254   } 
    315255 
     
    325265   bool CContext::isInitialized(void) 
    326266   { 
    327      return hasClient ; 
     267     return hasClient; 
    328268   } 
    329269 
     
    331271   void CContext::initServer(MPI_Comm intraComm,MPI_Comm interComm) 
    332272   { 
    333      hasServer=true ; 
    334      server = new CContextServer(this,intraComm,interComm) ; 
     273     hasServer=true; 
     274     server = new CContextServer(this,intraComm,interComm); 
    335275   } 
    336276 
     
    338278   bool CContext::eventLoop(void) 
    339279   { 
    340      return server->eventLoop() ; 
     280     return server->eventLoop(); 
    341281   } 
    342282 
     
    346286      if (hasClient && !hasServer) 
    347287      { 
    348          client->finalize() ; 
     288         client->finalize(); 
    349289      } 
    350290      if (hasServer) 
    351291      { 
    352         closeAllFile() ; 
     292        closeAllFile(); 
    353293      } 
    354294   } 
     
    385325      this->sendAllAttributesToServer(); 
    386326 
     327      // Send all attributes of current calendar 
     328      CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(); 
     329 
    387330      // We have enough information to send to server 
    388331      // First of all, send all enabled files 
     
    428371////        this->findEnabledFiles(); 
    429372// 
    430 //        this->processEnabledFiles() ; 
     373//        this->processEnabledFiles(); 
    431374// 
    432375//        this->solveAllGridRef(); 
     
    445388// 
    446389// 
    447 //      this->processEnabledFiles() ; 
     390//      this->processEnabledFiles(); 
    448391 
    449392/* 
     
    464407      if (hasClient && !hasServer) CleanTree(); // Only on client side?? 
    465408//      if (hasClient) CleanTree(); 
    466       if (hasClient) sendCreateFileHeader() ; 
     409      if (hasClient) sendCreateFileHeader(); 
    467410   } 
    468411 
     
    523466 
    524467     // Résolution des héritages par référence au niveau des fichiers. 
    525       const vector<CFile*> allFiles=CFile::getAll() ; 
     468      const vector<CFile*> allFiles=CFile::getAll(); 
    526469      const vector<CGrid*> allGrids= CGrid::getAll(); 
    527470 
     
    580523   { 
    581524 
    582       if (SuperClass::dispatchEvent(event)) return true ; 
     525      if (SuperClass::dispatchEvent(event)) return true; 
    583526      else 
    584527      { 
     
    586529        { 
    587530           case EVENT_ID_CLOSE_DEFINITION : 
    588              recvCloseDefinition(event) ; 
    589              return true ; 
    590              break ; 
     531             recvCloseDefinition(event); 
     532             return true; 
     533             break; 
    591534           case EVENT_ID_UPDATE_CALENDAR : 
    592              recvUpdateCalendar(event) ; 
    593              return true ; 
    594              break ; 
     535             recvUpdateCalendar(event); 
     536             return true; 
     537             break; 
    595538           case EVENT_ID_CREATE_FILE_HEADER : 
    596              recvCreateFileHeader(event) ; 
    597              return true ; 
    598              break ; 
     539             recvCreateFileHeader(event); 
     540             return true; 
     541             break; 
    599542           case EVENT_ID_POST_PROCESS: 
    600              recvPostProcessing(event) ; 
    601              return true ; 
    602              break ; 
     543             recvPostProcessing(event); 
     544             return true; 
     545             break; 
    603546           default : 
    604547             ERROR("bool CContext::dispatchEvent(CEventServer& event)", 
    605                     <<"Unknown Event") ; 
    606            return false ; 
     548                    <<"Unknown Event"); 
     549           return false; 
    607550         } 
    608551      } 
     
    612555   void CContext::sendCloseDefinition(void) 
    613556   { 
    614      CEventClient event(getType(),EVENT_ID_CLOSE_DEFINITION) ; 
     557     CEventClient event(getType(),EVENT_ID_CLOSE_DEFINITION); 
    615558     if (client->isServerLeader()) 
    616559     { 
    617        CMessage msg ; 
    618        msg<<this->getIdServer() ; 
    619        event.push(client->getServerLeader(),1,msg) ; 
    620        client->sendEvent(event) ; 
    621      } 
    622      else client->sendEvent(event) ; 
     560       CMessage msg; 
     561       msg<<this->getIdServer(); 
     562       event.push(client->getServerLeader(),1,msg); 
     563       client->sendEvent(event); 
     564     } 
     565     else client->sendEvent(event); 
    623566   } 
    624567 
     
    629572      CBufferIn* buffer=event.subEvents.begin()->buffer; 
    630573      string id; 
    631       *buffer>>id ; 
     574      *buffer>>id; 
    632575      get(id)->closeDefinition(); 
    633576   } 
     
    638581     if (!hasServer) 
    639582     { 
    640        CEventClient event(getType(),EVENT_ID_UPDATE_CALENDAR) ; 
     583       CEventClient event(getType(),EVENT_ID_UPDATE_CALENDAR); 
    641584       if (client->isServerLeader()) 
    642585       { 
    643          CMessage msg ; 
    644          msg<<this->getIdServer()<<step ; 
    645          event.push(client->getServerLeader(),1,msg) ; 
    646          client->sendEvent(event) ; 
     586         CMessage msg; 
     587         msg<<this->getIdServer()<<step; 
     588         event.push(client->getServerLeader(),1,msg); 
     589         client->sendEvent(event); 
    647590       } 
    648        else client->sendEvent(event) ; 
     591       else client->sendEvent(event); 
    649592     } 
    650593   } 
     
    656599      CBufferIn* buffer=event.subEvents.begin()->buffer; 
    657600      string id; 
    658       *buffer>>id ; 
    659       get(id)->recvUpdateCalendar(*buffer) ; 
     601      *buffer>>id; 
     602      get(id)->recvUpdateCalendar(*buffer); 
    660603   } 
    661604 
     
    663606   void CContext::recvUpdateCalendar(CBufferIn& buffer) 
    664607   { 
    665       int step ; 
    666       buffer>>step ; 
    667       updateCalendar(step) ; 
     608      int step; 
     609      buffer>>step; 
     610      updateCalendar(step); 
    668611   } 
    669612 
     
    671614   void CContext::sendCreateFileHeader(void) 
    672615   { 
    673      CEventClient event(getType(),EVENT_ID_CREATE_FILE_HEADER) ; 
     616     CEventClient event(getType(),EVENT_ID_CREATE_FILE_HEADER); 
    674617     if (client->isServerLeader()) 
    675618     { 
    676        CMessage msg ; 
    677        msg<<this->getIdServer() ; 
    678        event.push(client->getServerLeader(),1,msg) ; 
    679        client->sendEvent(event) ; 
    680      } 
    681      else client->sendEvent(event) ; 
     619       CMessage msg; 
     620       msg<<this->getIdServer(); 
     621       event.push(client->getServerLeader(),1,msg); 
     622       client->sendEvent(event); 
     623     } 
     624     else client->sendEvent(event); 
    682625   } 
    683626 
     
    687630      CBufferIn* buffer=event.subEvents.begin()->buffer; 
    688631      string id; 
    689       *buffer>>id ; 
    690       get(id)->recvCreateFileHeader(*buffer) ; 
     632      *buffer>>id; 
     633      get(id)->recvCreateFileHeader(*buffer); 
    691634   } 
    692635 
     
    694637   void CContext::recvCreateFileHeader(CBufferIn& buffer) 
    695638   { 
    696       createFileHeader() ; 
     639      createFileHeader(); 
    697640   } 
    698641 
     
    702645     if (!hasServer) 
    703646     { 
    704        CEventClient event(getType(),EVENT_ID_POST_PROCESS) ; 
     647       CEventClient event(getType(),EVENT_ID_POST_PROCESS); 
    705648       if (client->isServerLeader()) 
    706649       { 
    707          CMessage msg ; 
     650         CMessage msg; 
    708651         msg<<this->getIdServer(); 
    709          event.push(client->getServerLeader(),1,msg) ; 
    710          client->sendEvent(event) ; 
     652         event.push(client->getServerLeader(),1,msg); 
     653         client->sendEvent(event); 
    711654       } 
    712        else client->sendEvent(event) ; 
     655       else client->sendEvent(event); 
    713656     } 
    714657   } 
     
    726669   void CContext::recvPostProcessing(CBufferIn& buffer) 
    727670   { 
     671      CCalendarWrapper::get(CCalendarWrapper::GetDefName())->createCalendar(); 
    728672      postProcessing(); 
    729673//      std::cout << "server context " << *this << std::endl; 
     
    751695     if (isPostProcessed) return; 
    752696 
    753      // Solve calendar for both side: client and server 
    754       this->solveCalendar(); 
     697      // Make sure the calendar was correctly created 
     698      if (!calendar) 
     699        ERROR("CContext::postProcessing()", << "A calendar must be defined for the context \"" << getId() << "!\"") 
     700      else if (calendar->getTimeStep() == NoneDu) 
     701        ERROR("CContext::postProcessing()", << "A timestep must be defined for the context \"" << getId() << "!\"") 
    755702 
    756703      // Find all inheritance in xml structure 
     
    932879   void CContext::updateCalendar(int step) 
    933880   { 
    934       info(50)<<"updateCalendar : before : "<<calendar->getCurrentDate()<<endl ; 
    935       calendar->update(step) ; 
    936       info(50)<<"updateCalendar : after : "<<calendar->getCurrentDate()<<endl ; 
     881      info(50)<<"updateCalendar : before : "<<calendar->getCurrentDate()<<endl; 
     882      calendar->update(step); 
     883      info(50)<<"updateCalendar : after : "<<calendar->getCurrentDate()<<endl; 
    937884   } 
    938885 
     
    940887   void CContext::createFileHeader(void ) 
    941888   { 
    942       vector<CFile*>::const_iterator it ; 
     889      vector<CFile*>::const_iterator it; 
    943890 
    944891      for (it=enabledFiles.begin(); it != enabledFiles.end(); it++) 
     
    951898   CContext* CContext::getCurrent(void) 
    952899   { 
    953      return CObjectFactory::GetObject<CContext>(CObjectFactory::GetCurrentContextId()).get() ; 
     900     return CObjectFactory::GetObject<CContext>(CObjectFactory::GetCurrentContextId()).get(); 
    954901   } 
    955902 
     
    971918  CContext* CContext::create(const StdString& id) 
    972919  { 
    973     CContext::setCurrent(id) ; 
     920    CContext::setCurrent(id); 
    974921 
    975922    bool hasctxt = CContext::has(id); 
    976923    CContext* context = CObjectFactory::CreateObject<CContext>(id).get(); 
    977     getRoot() ; 
     924    getRoot(); 
    978925    if (!hasctxt) CGroupFactory::AddChild(root, context->getShared()); 
    979926 
Note: See TracChangeset for help on using the changeset viewer.