source: XIOS/trunk/src/node/field.cpp @ 501

Last change on this file since 501 was 501, checked in by ymipsl, 10 years ago

Add licence copyright to all file ond directory src using the command :
svn propset -R copyright -F header_licence src

XIOS is now officialy under CeCILL licence

YM

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 27.5 KB
RevLine 
[219]1#include "field.hpp"
2
[352]3#include "attribute_template.hpp"
4#include "object_template.hpp"
5#include "group_template.hpp"
[219]6
7#include "node_type.hpp"
8#include "calendar_util.hpp"
[352]9#include "message.hpp"
10#include "xmlioserver_spl.hpp"
11#include "type.hpp"
12#include "context_client.hpp"
[459]13#include <set>
[219]14
[335]15namespace xios{
[219]16   
17   /// ////////////////////// Définitions ////////////////////// ///
18
19   CField::CField(void)
20      : CObjectTemplate<CField>(), CFieldAttributes()
21      , refObject(), baseRefObject()
22      , grid(), file()
23      , freq_operation(), freq_write()
[266]24      , nstep(0)
[219]25      , last_Write(), last_operation()
[459]26      , foperation(), hasInstantData(false), hasExpression(false)
[460]27      , active(false) , hasOutputFile(false),hasFieldOut(false), slotUpdateDate(NULL)
[459]28      , processed(false)
[472]29      { setVirtualVariableGroup() ; }
[219]30
31   CField::CField(const StdString & id)
32      : CObjectTemplate<CField>(id), CFieldAttributes()
33      , refObject(), baseRefObject()
34      , grid(), file()
35      , freq_operation(), freq_write()
[266]36      , nstep(0)
[219]37      , last_Write(), last_operation()
[466]38      , foperation(), hasInstantData(false), hasExpression(false)
[460]39      , active(false), hasOutputFile(false), hasFieldOut(false), slotUpdateDate(NULL)
[459]40      , processed(false)
[472]41   { setVirtualVariableGroup() ; }
[219]42
43   CField::~CField(void)
44   {
[347]45//      this->grid.reset() ;
46//      this->file.reset() ;
[219]47      this->foperation.reset() ;
[459]48      if (hasExpression) delete expression ;
49      if (slotUpdateDate!=NULL) delete slotUpdateDate ;
50       
[219]51   }
52
[472]53
54  //----------------------------------------------------------------
55
56   void CField::setVirtualVariableGroup(CVariableGroup* newVVariableGroup)
57   { 
58      this->vVariableGroup = newVVariableGroup; 
59   }
60 
61   void CField::setVirtualVariableGroup(void)
62   {
63      this->setVirtualVariableGroup(CVariableGroup::create());
64   }
65 
66   CVariableGroup* CField::getVirtualVariableGroup(void) const
67   {
68      return (this->vVariableGroup);
69   }
70
71 
72   std::vector<CVariable*> CField::getAllVariables(void) const
73   {
74      return (this->vVariableGroup->getAllChildren());
75   }
76   
77   void CField::solveDescInheritance(bool apply, const CAttributeMap * const parent)
78   {
79      SuperClassAttribute::setAttributes(parent,apply);
80      this->getVirtualVariableGroup()->solveDescInheritance(apply, NULL);
81   }
[219]82   //----------------------------------------------------------------
[472]83   //----------------------------------------------------------------
[219]84
85   bool CField::updateDataServer
[343]86      (const CDate & currDate,
[369]87       const std::deque< CArray<double, 1>* > storedClient)
[219]88   {
[343]89      const CDate opeDate      = *last_operation + freq_operation;
90      const CDate writeDate    = *last_Write     + freq_write; 
[278]91     
92      if (opeDate <= currDate)
[219]93      {
[369]94         if (this->data.numElements() != this->grid->storeIndex[0]->numElements())
[278]95         {
[369]96            this->data.resize(this->grid->storeIndex[0] ->numElements());
[278]97         } 
[369]98         CArray<double,1> input(data.numElements()) ;
[278]99         this->grid->inputFieldServer(storedClient, input);         
[219]100         (*this->foperation)(input);
101         *last_operation = currDate;
102      }
[278]103      if (writeDate < (currDate + freq_operation))
[219]104      {
[278]105         this->foperation->final();
106         this->incrementNStep();
107         *last_Write = writeDate;
108         return (true);       
[219]109      }
110      return (false);
111   }
[300]112   
113   bool CField::dispatchEvent(CEventServer& event)
114  {
115     
116    if (SuperClass::dispatchEvent(event)) return true ;
117    else
118    {
119      switch(event.type)
120      {
121        case EVENT_ID_UPDATE_DATA :
122          recvUpdateData(event) ;
123          return true ;
124          break ;
[472]125
126            case EVENT_ID_ADD_VARIABLE :
127             recvAddVariable(event) ;
128             return true ;
129             break ;
130         
131           case EVENT_ID_ADD_VARIABLE_GROUP :
132             recvAddVariableGroup(event) ;
133             return true ;
134             break ; 
[300]135 
136        default :
137          ERROR("bool CField::dispatchEvent(CEventServer& event)",<<"Unknown Event") ;
138          return false ;
139      }
140    }
141  }
142 
143  void CField::sendUpdateData(void)
144  {
[347]145    CContext* context = CContext::getCurrent() ;
[300]146    CContextClient* client=context->client ;
147   
148    CEventClient event(getType(),EVENT_ID_UPDATE_DATA) ;
149   
[369]150    map<int,CArray<int, 1>* >::iterator it ;
[300]151    list<shared_ptr<CMessage> > list_msg ;
[369]152    list< CArray<double,1>* > list_data ;
[300]153   
154    for(it=grid->storeIndex_toSrv.begin();it!=grid->storeIndex_toSrv.end();it++)
155    {
156      int rank=(*it).first ;
[369]157      CArray<int,1>& index = *(it->second) ;
158      CArray<double,1> data_tmp(index.numElements()) ;
159     
160      for(int n=0;n<data_tmp.numElements();n++) data_tmp(n)=data(index(n)) ;
[300]161      list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
[369]162      list_data.push_back(new CArray<double,1>(data_tmp)) ;
163      *list_msg.back()<<getId()<<*list_data.back() ;
[300]164      event.push(rank,grid->nbSenders[rank],*list_msg.back()) ;
165    }
166    client->sendEvent(event) ;
[369]167   
168    for(list< CArray<double,1>* >::iterator it=list_data.begin();it!=list_data.end();it++) delete *it ;
[300]169  }
170 
171  void CField::recvUpdateData(CEventServer& event)
172  {
173    vector<int> ranks ;
174    vector<CBufferIn*> buffers ;
175     
176    list<CEventServer::SSubEvent>::iterator it ;
177    string fieldId ;
[219]178
[300]179    for (it=event.subEvents.begin();it!=event.subEvents.end();++it)
180    {
181      int rank=it->rank;
182      CBufferIn* buffer=it->buffer;
183      *buffer>>fieldId ;
184      ranks.push_back(rank) ;
185      buffers.push_back(buffer) ;
186    }
187    get(fieldId)->recvUpdateData(ranks,buffers) ;   
188  }
189 
190  void  CField::recvUpdateData(vector<int>& ranks, vector<CBufferIn*>& buffers)
191  {
192   
193    if (data_srv.empty())
194    {
[369]195      for(map<int, CArray<int, 1>* >::iterator it=grid->out_i_fromClient.begin();it!=grid->out_i_fromClient.end();it++)
[300]196      {
197        int rank=it->first ;
[369]198        CArray<double,1> data_tmp(it->second->numElements()) ;
199        data_srv.insert( pair<int, CArray<double,1>* >(rank, new CArray<double,1>(data_tmp) ) ) ;
200        foperation_srv.insert(pair<int,boost::shared_ptr<func::CFunctor> >(rank,boost::shared_ptr<func::CFunctor>(new func::CInstant(*data_srv[rank])))) ;
[300]201      }
202    }
203
[347]204    CContext* context = CContext::getCurrent() ;
[343]205    const CDate & currDate = context->getCalendar()->getCurrentDate();
206    const CDate opeDate      = *last_operation_srv + freq_operation_srv;
207    const CDate writeDate    = *last_Write_srv     + freq_write_srv; 
[300]208   
209
210   
211    if (opeDate <= currDate)
212    {
213      for(int n=0;n<ranks.size();n++)
214      {
[369]215        CArray<double,1> data_tmp ;
[300]216        *buffers[n]>>data_tmp ;
217        (*foperation_srv[ranks[n]])(data_tmp) ;
218      }
219      *last_operation_srv = currDate;
220    }
221     
222    if (writeDate < (currDate + freq_operation_srv))
223    {
224      for(int n=0;n<ranks.size();n++)
225      {
226        this->foperation_srv[ranks[n]]->final();
227      }
228     
229      *last_Write_srv = writeDate;
230      writeField() ;
[334]231      *lastlast_Write_srv=*last_Write_srv;
[300]232    }
233  }
234 
235  void CField::writeField(void)
236  {
[379]237    if (! getRelFile()->allDomainEmpty )
238      if (! grid->domain->isEmpty() || getRelFile()->type == CFile::type_attr::one_file)
239      {
240        getRelFile()->checkFile();
241        this->incrementNStep();
242        getRelFile()->getDataOutput()->writeFieldData(CField::get(this));
243      }
[300]244  }
[219]245   //----------------------------------------------------------------
246
[347]247   void CField::setRelFile(CFile* _file)
[219]248   { 
[459]249      this->file = _file;
250      hasOutputFile=true ; 
[219]251   }
252
253   //----------------------------------------------------------------
254
255   StdString CField::GetName(void)   { return (StdString("field")); }
256   StdString CField::GetDefName(void){ return (CField::GetName()); }
257   ENodeType CField::GetType(void)   { return (eField); }
258
259   //----------------------------------------------------------------
260
[347]261   CGrid* CField::getRelGrid(void) const
[219]262   { 
263      return (this->grid); 
264   }
265
266   //----------------------------------------------------------------
267
[347]268   CFile* CField::getRelFile(void) const
[219]269   { 
270      return (this->file);
271   }
[266]272   
273   StdSize CField::getNStep(void) const
274   {
275      return (this->nstep);
276   }
277   
278   void CField::incrementNStep(void)
279   {
280      this->nstep++;
281   }
[321]282 
283   void CField::resetNStep(void)
284   {
285      this->nstep=0;
286   }
[219]287
288   //----------------------------------------------------------------
289
[347]290   CField* CField::getDirectFieldReference(void) const
[219]291   {
292      if (this->field_ref.isEmpty())
293         return (this->getBaseFieldReference());
294
[346]295      if (! CField::has(this->field_ref.getValue()))
[219]296         ERROR("CField::getDirectFieldReference(void)",
297               << "[ ref_name = " << this->field_ref.getValue() << "]"
298               << " invalid field name !");
299
[346]300      return (CField::get(this->field_ref.getValue()));
[219]301   }
302
303   //----------------------------------------------------------------
304
[347]305   CField* CField::getBaseFieldReference(void) const
[219]306   { 
307      return (baseRefObject); 
308   }
309
310   //----------------------------------------------------------------
311
[347]312   const std::vector<CField*>& CField::getAllReference(void) const 
[219]313   { 
314      return (refObject);
315   }
316
317   //----------------------------------------------------------------
318
319   const StdString & CField::getBaseFieldId(void) const
320   { 
321      return (this->getBaseFieldReference()->getId());
322   }
323   
324   //----------------------------------------------------------------
325   
[343]326   const CDuration & CField::getFreqOperation(void) const
[219]327   {
328      return (this->freq_operation);
329   }
330   
331   //----------------------------------------------------------------
[343]332   const CDuration & CField::getFreqWrite(void) const
[219]333   {
334      return (this->freq_write);
335   }
336   
337   //----------------------------------------------------------------
338         
339   boost::shared_ptr<func::CFunctor> CField::getFieldOperation(void) const
340   {
341      return (this->foperation);
342   }
343
344   //----------------------------------------------------------------
345
346   bool CField::hasDirectFieldReference(void) const
347   { 
[310]348     return (!this->field_ref.isEmpty()); 
[219]349   }
350   
[310]351   bool CField::isActive(void) const
352   { 
353      return (!this->refObject.empty()); 
354   }
[219]355   //----------------------------------------------------------------
356   
[369]357   CArray<double, 1> CField::getData(void) const
[219]358   {
359      return(this->data);
360   }
361
362   //----------------------------------------------------------------
363
[343]364   boost::shared_ptr<CDate> CField::getLastWriteDate(void) const
[219]365   {
366      return(this->last_Write);
367   }
368
369   //----------------------------------------------------------------
370
[343]371   boost::shared_ptr<CDate> CField::getLastOperationDate(void) const
[219]372   {
373      return(this->last_operation);
374   }
375
376   //----------------------------------------------------------------
377
[459]378   void CField::processEnabledField(void)
379   {
380      if (!processed)
381      {
382        processed=true ;
[482]383        solveRefInheritance(true) ;
[478]384        solveBaseReference() ;
[459]385        solveOperation() ;
386        solveGridReference() ;
387     
388        if (hasDirectFieldReference()) baseRefObject->processEnabledField() ;
389        buildExpression(); 
390        active=true;
391      }
392    }
[478]393
[445]394   void CField::solveRefInheritance(bool apply)
[219]395   {
396      std::set<CField *> sset;
[347]397      CField* refer_sptr;
[219]398      CField * refer_ptr = this;
[478]399     
400      while (refer_ptr->hasDirectFieldReference())
401      {
402         refer_sptr = refer_ptr->getDirectFieldReference();
403         refer_ptr  = refer_sptr;
404
405         if(sset.end() != sset.find(refer_ptr))
406         {
407            DEBUG (<< "Circular dependency stopped for field object on "
408                   << "\"" + refer_ptr->getId() + "\" !");
409            break;
410         }
411
412         SuperClassAttribute::setAttributes(refer_ptr, apply);
413         sset.insert(refer_ptr);
414      }
[219]415     
[478]416   }
417
418   void CField::solveBaseReference(void)
419   {
420      std::set<CField *> sset;
421      CField* refer_sptr;
422      CField * refer_ptr = this;
423     
[459]424      if (this->hasDirectFieldReference())  baseRefObject = getDirectFieldReference();
425      else  baseRefObject = CField::get(this);
[219]426     
427      while (refer_ptr->hasDirectFieldReference())
428      {
429         refer_sptr = refer_ptr->getDirectFieldReference();
[347]430         refer_ptr  = refer_sptr;
[219]431
432         if(sset.end() != sset.find(refer_ptr))
433         {
[478]434            DEBUG (<< "Circular dependency stopped for field object on "
[219]435                   << "\"" + refer_ptr->getId() + "\" !");
436            break;
437         }
438
439         sset.insert(refer_ptr);
440      }
[459]441     
442      if (hasDirectFieldReference()) baseRefObject->addReference(this) ;
[219]443   }
[478]444   
[219]445   //----------------------------------------------------------------
446
447   void  CField::solveOperation(void)
448   {
449      using namespace func;
[459]450     
[460]451      if (!hasOutputFile && !hasFieldOut) return ;
[459]452     
453      StdString id ;
454      if (hasId()) id=getId();
455      else if (!name.isEmpty()) id=name ;
456      else if (hasDirectFieldReference()) id=baseRefObject->getId() ;
457     
[347]458      CContext* context = CContext::getCurrent();
[436]459     
460      if (freq_op.isEmpty()) freq_op=string("1ts") ;
461     
[459]462      if (operation.isEmpty() )
[219]463      {
464         ERROR("CField::solveOperation(void)",
465               << "[ id = " << id << "]"
[421]466               << "Impossible to define an operation for this field !");
[219]467      }
[278]468     
469      CDuration freq_offset_ = NoneDu;
470      if (!freq_offset.isEmpty())
471      {
472         freq_offset_ = CDuration::FromString(freq_offset.getValue());
473      }
474      else
475      {
476         freq_offset.setValue(NoneDu.toString());
477      } 
[219]478
[300]479//      if (CXIOSManager::GetStatus() == CXIOSManager::LOC_SERVER)
480      if (context->hasServer)
[219]481      {
[460]482         if (hasOutputFile) 
483         {
484           this->freq_operation_srv =CDuration::FromString(this->file->output_freq.getValue());
485           this->freq_write_srv = CDuration::FromString(this->file->output_freq.getValue());
486         }
[343]487         this->lastlast_Write_srv     = boost::shared_ptr<CDate>
488                        (new CDate(context->getCalendar()->getInitDate()));
489         this->last_Write_srv     = boost::shared_ptr<CDate>
490                        (new CDate(context->getCalendar()->getInitDate()));
491         this->last_operation_srv = boost::shared_ptr<CDate>
492                        (new CDate(context->getCalendar()->getInitDate()));
[300]493//         this->foperation_srv     =
494//             boost::shared_ptr<func::CFunctor>(new CInstant(this->data_srv));
[278]495             
[460]496         if (hasOutputFile) 
497         {
498           const CDuration toffset = this->freq_operation_srv - freq_offset_ - context->getCalendar()->getTimeStep(); 
499           *this->last_operation_srv   = *this->last_operation_srv - toffset;
500         }
[219]501      }
[300]502     
[449]503//      if (context->hasClient)
504//      {                 
[219]505         this->freq_operation = CDuration::FromString(freq_op.getValue());
[460]506         if (hasOutputFile) this->freq_write     = CDuration::FromString(this->file->output_freq.getValue());
507         if (hasFieldOut) 
508         {
509           this->freq_write = CDuration::FromString(this->fieldOut->freq_op.getValue());
510         }
[343]511         this->last_Write     = boost::shared_ptr<CDate>
512                        (new CDate(context->getCalendar()->getInitDate()));
513         this->last_operation = boost::shared_ptr<CDate>
514                        (new CDate(context->getCalendar()->getInitDate()));
[278]515                       
[300]516         const CDuration toffset = this->freq_operation - freq_offset_ - context->getCalendar()->getTimeStep(); 
[278]517         *this->last_operation   = *this->last_operation - toffset; 
[436]518     
519        if (operation.get()=="once") isOnceOperation=true ;
520        else isOnceOperation=false;
521        isFirstOperation=true;
[470]522       
523         
[219]524#define DECLARE_FUNCTOR(MType, mtype)              \
525   if  (operation.getValue().compare(#mtype) == 0) \
526   {                                               \
[470]527      if (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value==true) \
528      { \
529        boost::shared_ptr<func::CFunctor> foperation_(new C##MType(this->data,default_value)); \
[473]530        this->foperation = foperation_; \
[470]531      } \
532      else \
533      { \
534        boost::shared_ptr<func::CFunctor> foperation_(new C##MType(this->data)); \
535        this->foperation = foperation_;  \
536      } \
[219]537      return;                                      \
538   }
539   
540#include "functor_type.conf"
541         
542         ERROR("CField::solveOperation(void)",
543               << "[ operation = " << operation.getValue() << "]"
[421]544               << "The operation is not defined !");
[449]545//      }
[436]546     
547
[219]548   }
549   
550   //----------------------------------------------------------------
[369]551/*
[219]552   void CField::fromBinary(StdIStream & is)
553   {
554      SuperClass::fromBinary(is);
555#define CLEAR_ATT(name_)\
[369]556      SuperClassAttribute::operator[](#name_)->reset()
[219]557
558         CLEAR_ATT(domain_ref);
559         CLEAR_ATT(axis_ref);
560#undef CLEAR_ATT
561
562   }
[369]563*/
[219]564   //----------------------------------------------------------------
565
566   void CField::solveGridReference(void)
567   {
[347]568      CDomain* domain;
569      CAxis* axis;
[219]570
571      if (!domain_ref.isEmpty())
572      {
[346]573         if (CDomain::has(domain_ref.getValue()))
574            domain = CDomain::get(domain_ref.getValue()) ;
[219]575         else
576            ERROR("CField::solveGridReference(void)",
[421]577                  << "Reference to the domain \'"
578                  << domain_ref.getValue() << "\' is wrong") ;
[219]579      }
580
581      if (!axis_ref.isEmpty())
582      {
[346]583         if (CAxis::has(axis_ref.getValue()))
584            axis = CAxis::get(axis_ref.getValue()) ;
[219]585         else
586            ERROR("CField::solveGridReference(void)",
[421]587                  << "Reference to the axis \'"
588                  << axis_ref.getValue() <<"\' is wrong") ;
[219]589      }
590
591      if (!grid_ref.isEmpty())
592      {
[346]593         if (CGrid::has(grid_ref.getValue()))
594            this->grid = CGrid::get(grid_ref.getValue()) ;
[219]595         else
596            ERROR("CField::solveGridReference(void)",
[421]597                  << "Reference to the grid \'"
598                  << grid_ref.getValue() << "\' is wrong");
[219]599      }
[418]600     
601      if (grid_ref.isEmpty() &&  domain_ref.isEmpty())
[219]602      {
603            ERROR("CField::solveGridReference(void)",
[421]604                  << "The horizontal domain for this field is not defined");
[418]605
606     }
607     
608     CType<string> goodDomain ;
609     CType<string> goodAxis ;
610     if (!grid_ref.isEmpty())
611     {
612       if (!grid->domain_ref.isEmpty()) goodDomain=grid->domain_ref ;
613       if (!grid->axis_ref.isEmpty()) goodAxis=grid->axis_ref ;
614     }
615     if (!domain_ref.isEmpty()) goodDomain=domain_ref ;
616     if (!axis_ref.isEmpty()) goodAxis=axis_ref ;
617     
618     
619     if (goodDomain.isEmpty()) 
620     {
[421]621       ERROR("CField::solveGridReference(void)", << "The horizontal domain for this field is not defined");
[418]622     }
623     else 
624     {
625       if (CDomain::has(goodDomain)) domain = CDomain::get(goodDomain) ;
[421]626       else ERROR("CField::solveGridReference(void)",<< "Reference to the domain \'"<<goodDomain.get() << "\' is wrong") ;
[418]627     }
628 
629     if (!goodAxis.isEmpty())
630     {
631       if (CAxis::has(goodAxis))  axis = CAxis::get(goodAxis) ;
[421]632       else  ERROR("CField::solveGridReference(void)", << "Reference to the axis \'"
633                  << goodAxis.get() <<"\' is wrong") ;
[418]634     } 
635   
636     bool nothingToDo=false ;
637     
638     if (!grid_ref.isEmpty())
639     {
640       if (!grid->domain_ref.isEmpty() && goodDomain.get() == grid->domain_ref.get())
641         if (goodAxis.isEmpty()) nothingToDo=true ;
642         else if (!grid->axis_ref.isEmpty()) 
643                 if (grid->axis_ref.get()==goodAxis.get()) nothingToDo=true ;
644     }
645     
646     if (!nothingToDo)
647     {
648       if (!goodAxis.isEmpty())
649       {
650         this->grid = CGrid::createGrid(domain, axis) ;
651         this->grid_ref.setValue(this->grid->getId());
652       }
653       else
654       {
655         this->grid = CGrid::createGrid(domain) ;
656         this->grid_ref.setValue(this->grid->getId());
657       }   
658     }
659
660     grid->solveReference() ;
[459]661
[219]662   }
663
664
665   ///-------------------------------------------------------------------
666
667   template <>
668      void CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)
669   {
670      if (this->group_ref.isEmpty()) return;
671      StdString gref = this->group_ref.getValue();
672
[346]673      if (!CFieldGroup::has(gref))
[219]674         ERROR("CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)",
675               << "[ gref = " << gref << "]"
676               << " invalid group name !");
677
[347]678      CFieldGroup* group = CFieldGroup::get(gref);
679      CFieldGroup* owner = CFieldGroup::get(boost::polymorphic_downcast<CFieldGroup*>(this));
[219]680
[347]681      std::vector<CField*> allChildren  = group->getAllChildren();
682      std::vector<CField*>::iterator
[219]683         it = allChildren.begin(), end = allChildren.end();
684     
685      for (; it != end; it++)
686      {
[347]687         CField* child = *it;
[346]688         if (child->hasId()) owner->createChild()->field_ref.setValue(child->getId()) ;
689           
[219]690      }
691   }
[300]692   
[464]693   void CField::scaleFactorAddOffset(double scaleFactor, double addOffset)
694   {
695     map<int, CArray<double,1>* >::iterator it;
696     for(it=data_srv.begin();it!=data_srv.end();it++) *it->second = (*it->second -addOffset) * 1./scaleFactor  ;
697   }
698   
[369]699   void CField::outputField(CArray<double,3>& fieldOut)
[300]700   {
[369]701      map<int, CArray<double,1>* >::iterator it;
[300]702      for(it=data_srv.begin();it!=data_srv.end();it++)
[369]703         grid->outputField(it->first,*it->second, fieldOut) ;
[300]704     
705   }
706   
[369]707   void CField::outputField(CArray<double,2>& fieldOut)
[300]708   {
[369]709      map<int, CArray<double,1>* >::iterator it;
[219]710
[300]711      for(it=data_srv.begin();it!=data_srv.end();it++)
712      {
[369]713         grid->outputField(it->first,*it->second, fieldOut) ;
[300]714      }
715   }
[219]716   ///-------------------------------------------------------------------
717
[459]718   void CField::parse(xml::CXMLNode & node)
719   {
720      SuperClass::parse(node);
[476]721      if (! node.getContent(this->content)) 
[472]722      {
[476]723        if (node.goToChildElement())
[472]724        {
[476]725          do
726          {
727            if (node.getElementName()=="variable" || node.getElementName()=="variable_group") this->getVirtualVariableGroup()->parseChild(node);
728          } while (node.goToNextElement()) ;
729          node.goToParentElement();
730        }
[472]731      }
[459]732    }
733   
734  CArray<double,1>* CField::getInstantData(void)
735  {
736    if (!hasInstantData) 
737    {
738      instantData.resize(grid->storeIndex_client.numElements()) ;
739      hasInstantData=true ;
740    }
741    return &instantData ;
742  }
743 
744  void CField::addReference(CField* field)
745  {
746    refObject.push_back(field) ;
747  }
748 
749  void CField::addDependency(CField* field, int slotId)
750  {
751    fieldDependency.push_back(pair<CField*,int>(field,slotId)) ;
752  }
753 
754  void CField::buildExpression(void)
755  {
756    if (content.size() > 0) 
757    {
758      CSimpleNodeExpr* simpleExpr=parseExpr(content+'\0') ;
759      expression=CFieldNode::newNode(simpleExpr) ;
760      delete simpleExpr ;
[460]761      set<string> instantFieldIds ;
762      map<string,CField*> associatedInstantFieldIds ;
763      expression->getInstantFieldIds(instantFieldIds) ;
764      for (set<string>::iterator it=instantFieldIds.begin() ; it!=instantFieldIds.end();++it) 
765      {
766        if (*it!="this") 
767        {
768          if (CField::has(*it)) 
769          {
770            CField* field=CField::get(*it) ;
771            field->processEnabledField() ;
772            associatedInstantFieldIds[*it]=field ;
773          }
774          else  ERROR("void CField::buildExpression(void)",<<" Field "<<*it<<" does not exist") ;
775        }
776      }
[459]777     
[460]778      set<string> averageFieldIds ;
779      map<string,CField*> associatedAverageFieldIds ;
[459]780
[460]781      expression->getAverageFieldIds(averageFieldIds) ;
782      for (set<string>::iterator it=averageFieldIds.begin() ; it!=averageFieldIds.end();++it) 
783      {     
784        if (CField::has(*it)) 
785        {
786           CFieldGroup* root=CFieldGroup::get("field_definition") ;
787           CField* averageField=root->createChild() ;
788           CField* instantField=root->createChild() ;
789           averageField->field_ref=*it ;
790           averageField->hasFieldOut=true ;
791           averageField->fieldOut=instantField ;
792           instantField->freq_op=freq_op ;
793           averageField-> processEnabledField() ;
794           instantField->SuperClassAttribute::setAttributes(averageField, true);
795           instantField->field_ref.reset() ;
796           instantField->operation.reset() ;
797
798           instantField-> processEnabledField() ;
799           associatedAverageFieldIds[*it]=instantField  ;
800        }
801        else ERROR("void CField::buildExpression(void)",<<" Field "<<*it<<" does not exist") ;
802      }
803
804      expression->reduce(this,associatedInstantFieldIds,associatedAverageFieldIds) ;
805
806      slots.resize(instantFieldIds.size()+averageFieldIds.size()) ;
[459]807      resetSlots() ;
808      int slotId=0 ;
809      set<CField*> fields ;
810      expression->getFields(fields) ;
811      for (set<CField*>::iterator it=fields.begin() ; it!=fields.end();++it,++slotId) (*it)->addDependency(this,slotId) ;
812      hasExpression=true; 
813    }
814  }
815 
816  void CField::resetSlots(void)
817  {
818    for(vector<bool>::iterator it=slots.begin();it!=slots.end();++it) *it=false ;
819  }
820 
821  bool CField::slotsFull(void)
822  {
823    bool ret=true ;
824    for(vector<bool>::iterator it=slots.begin();it!=slots.end();++it) ret &= *it;
825    return ret ;
826  }
827
828 
829  void CField::setSlot(int slotId)
830  {
831    CContext* context = CContext::getCurrent() ;
832    const CDate & currDate = context->getCalendar()->getCurrentDate();
833    if (slotUpdateDate==NULL || currDate!=*slotUpdateDate) 
834    {
835      resetSlots() ;
836      if (slotUpdateDate==NULL) slotUpdateDate=new CDate(currDate) ;
837      else *slotUpdateDate=currDate ;
838    }
839    slots[slotId]=true ;
840    if (slotsFull())
841    {
842      CArray<double,1> expr(expression->compute()) ;
843     
844      if (hasInstantData) 
845      {
846        instantData=expr ;
847        for(list< pair<CField *,int> >::iterator it=fieldDependency.begin(); it!=fieldDependency.end(); ++it) 
848          if (it->first!=this) it->first->setSlot(it->second) ;
849      }
850     
851      if (hasOutputFile) updateDataFromExpression(expr) ;
852     
853    }
854  }
[472]855
856
857
858   CVariable* CField::addVariable(const string& id)
859   {
860     return vVariableGroup->createChild(id) ;
861   }
862
863   CVariableGroup* CField::addVariableGroup(const string& id)
864   {
865     return vVariableGroup->createChildGroup(id) ;
866   }
867
868
869   void CField::sendAddVariable(const string& id)
870   {
871    CContext* context=CContext::getCurrent() ;
872   
873    if (! context->hasServer )
874    {
875       CContextClient* client=context->client ;
876
877       CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE) ;   
878       if (client->isServerLeader())
879       {
880         CMessage msg ;
881         msg<<this->getId() ;
882         msg<<id ;
883         event.push(client->getServerLeader(),1,msg) ;
884         client->sendEvent(event) ;
885       }
886       else client->sendEvent(event) ;
887    }
888     
889   }
890 
891   
892   void CField::sendAddVariableGroup(const string& id)
893   {
894    CContext* context=CContext::getCurrent() ;
895    if (! context->hasServer )
896    {
897       CContextClient* client=context->client ;
898
899       CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE_GROUP) ;   
900       if (client->isServerLeader())
901       {
902         CMessage msg ;
903         msg<<this->getId() ;
904         msg<<id ;
905         event.push(client->getServerLeader(),1,msg) ;
906         client->sendEvent(event) ;
907       }
908       else client->sendEvent(event) ;
909    }
910     
911   }
912   
913   void CField::recvAddVariable(CEventServer& event)
914   {
915     
916      CBufferIn* buffer=event.subEvents.begin()->buffer;
917      string id;
918      *buffer>>id ;
919      get(id)->recvAddVariable(*buffer) ;
920   }
921   
922   
923   void CField::recvAddVariable(CBufferIn& buffer)
924   {
925      string id ;
926      buffer>>id ;
927      addVariable(id) ;
928   }
929
930   void CField::recvAddVariableGroup(CEventServer& event)
931   {
932     
933      CBufferIn* buffer=event.subEvents.begin()->buffer;
934      string id;
935      *buffer>>id ;
936      get(id)->recvAddVariableGroup(*buffer) ;
937   }
938   
939   
940   void CField::recvAddVariableGroup(CBufferIn& buffer)
941   {
942      string id ;
943      buffer>>id ;
944      addVariableGroup(id) ;
945   }
946
947
948
[459]949 
[335]950} // namespace xios
Note: See TracBrowser for help on using the repository browser.