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

Last change on this file since 476 was 476, checked in by ymipsl, 8 years ago

bug fix : bug while parsing xml file when field has content.

YM

File size: 27.2 KB
Line 
1#include "field.hpp"
2
3#include "attribute_template.hpp"
4#include "object_template.hpp"
5#include "group_template.hpp"
6
7#include "node_type.hpp"
8#include "calendar_util.hpp"
9#include "message.hpp"
10#include "xmlioserver_spl.hpp"
11#include "type.hpp"
12#include "context_client.hpp"
13#include <set>
14
15namespace xios{
16   
17   /// ////////////////////// Définitions ////////////////////// ///
18
19   CField::CField(void)
20      : CObjectTemplate<CField>(), CFieldAttributes()
21      , refObject(), baseRefObject()
22      , grid(), file()
23      , freq_operation(), freq_write()
24      , nstep(0)
25      , last_Write(), last_operation()
26      , foperation(), hasInstantData(false), hasExpression(false)
27      , active(false) , hasOutputFile(false),hasFieldOut(false), slotUpdateDate(NULL)
28      , processed(false)
29      { setVirtualVariableGroup() ; }
30
31   CField::CField(const StdString & id)
32      : CObjectTemplate<CField>(id), CFieldAttributes()
33      , refObject(), baseRefObject()
34      , grid(), file()
35      , freq_operation(), freq_write()
36      , nstep(0)
37      , last_Write(), last_operation()
38      , foperation(), hasInstantData(false), hasExpression(false)
39      , active(false), hasOutputFile(false), hasFieldOut(false), slotUpdateDate(NULL)
40      , processed(false)
41   { setVirtualVariableGroup() ; }
42
43   CField::~CField(void)
44   {
45//      this->grid.reset() ;
46//      this->file.reset() ;
47      this->foperation.reset() ;
48      if (hasExpression) delete expression ;
49      if (slotUpdateDate!=NULL) delete slotUpdateDate ;
50       
51   }
52
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   }
82   //----------------------------------------------------------------
83   //----------------------------------------------------------------
84
85   bool CField::updateDataServer
86      (const CDate & currDate,
87       const std::deque< CArray<double, 1>* > storedClient)
88   {
89      const CDate opeDate      = *last_operation + freq_operation;
90      const CDate writeDate    = *last_Write     + freq_write; 
91     
92      if (opeDate <= currDate)
93      {
94         if (this->data.numElements() != this->grid->storeIndex[0]->numElements())
95         {
96            this->data.resize(this->grid->storeIndex[0] ->numElements());
97         } 
98         CArray<double,1> input(data.numElements()) ;
99         this->grid->inputFieldServer(storedClient, input);         
100         (*this->foperation)(input);
101         *last_operation = currDate;
102      }
103      if (writeDate < (currDate + freq_operation))
104      {
105         this->foperation->final();
106         this->incrementNStep();
107         *last_Write = writeDate;
108         return (true);       
109      }
110      return (false);
111   }
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 ;
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 ; 
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  {
145    CContext* context = CContext::getCurrent() ;
146    CContextClient* client=context->client ;
147   
148    CEventClient event(getType(),EVENT_ID_UPDATE_DATA) ;
149   
150    map<int,CArray<int, 1>* >::iterator it ;
151    list<shared_ptr<CMessage> > list_msg ;
152    list< CArray<double,1>* > list_data ;
153   
154    for(it=grid->storeIndex_toSrv.begin();it!=grid->storeIndex_toSrv.end();it++)
155    {
156      int rank=(*it).first ;
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)) ;
161      list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
162      list_data.push_back(new CArray<double,1>(data_tmp)) ;
163      *list_msg.back()<<getId()<<*list_data.back() ;
164      event.push(rank,grid->nbSenders[rank],*list_msg.back()) ;
165    }
166    client->sendEvent(event) ;
167   
168    for(list< CArray<double,1>* >::iterator it=list_data.begin();it!=list_data.end();it++) delete *it ;
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 ;
178
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    {
195      for(map<int, CArray<int, 1>* >::iterator it=grid->out_i_fromClient.begin();it!=grid->out_i_fromClient.end();it++)
196      {
197        int rank=it->first ;
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])))) ;
201      }
202    }
203
204    CContext* context = CContext::getCurrent() ;
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; 
208   
209
210   
211    if (opeDate <= currDate)
212    {
213      for(int n=0;n<ranks.size();n++)
214      {
215        CArray<double,1> data_tmp ;
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() ;
231      *lastlast_Write_srv=*last_Write_srv;
232    }
233  }
234 
235  void CField::writeField(void)
236  {
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      }
244  }
245   //----------------------------------------------------------------
246
247   void CField::setRelFile(CFile* _file)
248   { 
249      this->file = _file;
250      hasOutputFile=true ; 
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
261   CGrid* CField::getRelGrid(void) const
262   { 
263      return (this->grid); 
264   }
265
266   //----------------------------------------------------------------
267
268   CFile* CField::getRelFile(void) const
269   { 
270      return (this->file);
271   }
272   
273   StdSize CField::getNStep(void) const
274   {
275      return (this->nstep);
276   }
277   
278   void CField::incrementNStep(void)
279   {
280      this->nstep++;
281   }
282 
283   void CField::resetNStep(void)
284   {
285      this->nstep=0;
286   }
287
288   //----------------------------------------------------------------
289
290   CField* CField::getDirectFieldReference(void) const
291   {
292      if (this->field_ref.isEmpty())
293         return (this->getBaseFieldReference());
294
295      if (! CField::has(this->field_ref.getValue()))
296         ERROR("CField::getDirectFieldReference(void)",
297               << "[ ref_name = " << this->field_ref.getValue() << "]"
298               << " invalid field name !");
299
300      return (CField::get(this->field_ref.getValue()));
301   }
302
303   //----------------------------------------------------------------
304
305   CField* CField::getBaseFieldReference(void) const
306   { 
307      return (baseRefObject); 
308   }
309
310   //----------------------------------------------------------------
311
312   const std::vector<CField*>& CField::getAllReference(void) const 
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   
326   const CDuration & CField::getFreqOperation(void) const
327   {
328      return (this->freq_operation);
329   }
330   
331   //----------------------------------------------------------------
332   const CDuration & CField::getFreqWrite(void) const
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   { 
348     return (!this->field_ref.isEmpty()); 
349   }
350   
351   bool CField::isActive(void) const
352   { 
353      return (!this->refObject.empty()); 
354   }
355   //----------------------------------------------------------------
356   
357   CArray<double, 1> CField::getData(void) const
358   {
359      return(this->data);
360   }
361
362   //----------------------------------------------------------------
363
364   boost::shared_ptr<CDate> CField::getLastWriteDate(void) const
365   {
366      return(this->last_Write);
367   }
368
369   //----------------------------------------------------------------
370
371   boost::shared_ptr<CDate> CField::getLastOperationDate(void) const
372   {
373      return(this->last_operation);
374   }
375
376   //----------------------------------------------------------------
377
378   void CField::processEnabledField(void)
379   {
380      if (!processed)
381      {
382        processed=true ;
383        solveRefInheritance(true) ;
384        solveOperation() ;
385        solveGridReference() ;
386     
387        if (hasDirectFieldReference()) baseRefObject->processEnabledField() ;
388        buildExpression(); 
389        active=true;
390      }
391    }
392   
393   void CField::solveRefInheritance(bool apply)
394   {
395      std::set<CField *> sset;
396      CField* refer_sptr;
397      CField * refer_ptr = this;
398     
399      if (this->hasDirectFieldReference())  baseRefObject = getDirectFieldReference();
400      else  baseRefObject = CField::get(this);
401     
402      while (refer_ptr->hasDirectFieldReference())
403      {
404         refer_sptr = refer_ptr->getDirectFieldReference();
405         refer_ptr  = refer_sptr;
406
407         if(sset.end() != sset.find(refer_ptr))
408         {
409            DEBUG (<< "Dépendance circulaire stoppée pour l'objet de type CField sur "
410                   << "\"" + refer_ptr->getId() + "\" !");
411            break;
412         }
413
414         SuperClassAttribute::setAttributes(refer_ptr, apply);
415         sset.insert(refer_ptr);
416//ym         baseRefObject = refer_sptr;
417//ym         refObject.push_back(refer_sptr);
418      }
419     
420      if (hasDirectFieldReference()) baseRefObject->addReference(this) ;
421   }
422
423   //----------------------------------------------------------------
424
425   void  CField::solveOperation(void)
426   {
427      using namespace func;
428     
429      if (!hasOutputFile && !hasFieldOut) return ;
430     
431      StdString id ;
432      if (hasId()) id=getId();
433      else if (!name.isEmpty()) id=name ;
434      else if (hasDirectFieldReference()) id=baseRefObject->getId() ;
435     
436      CContext* context = CContext::getCurrent();
437     
438      if (freq_op.isEmpty()) freq_op=string("1ts") ;
439     
440      if (operation.isEmpty() )
441      {
442         ERROR("CField::solveOperation(void)",
443               << "[ id = " << id << "]"
444               << "Impossible to define an operation for this field !");
445      }
446     
447      CDuration freq_offset_ = NoneDu;
448      if (!freq_offset.isEmpty())
449      {
450         freq_offset_ = CDuration::FromString(freq_offset.getValue());
451      }
452      else
453      {
454         freq_offset.setValue(NoneDu.toString());
455      } 
456
457//      if (CXIOSManager::GetStatus() == CXIOSManager::LOC_SERVER)
458      if (context->hasServer)
459      {
460         if (hasOutputFile) 
461         {
462           this->freq_operation_srv =CDuration::FromString(this->file->output_freq.getValue());
463           this->freq_write_srv = CDuration::FromString(this->file->output_freq.getValue());
464         }
465         this->lastlast_Write_srv     = boost::shared_ptr<CDate>
466                        (new CDate(context->getCalendar()->getInitDate()));
467         this->last_Write_srv     = boost::shared_ptr<CDate>
468                        (new CDate(context->getCalendar()->getInitDate()));
469         this->last_operation_srv = boost::shared_ptr<CDate>
470                        (new CDate(context->getCalendar()->getInitDate()));
471//         this->foperation_srv     =
472//             boost::shared_ptr<func::CFunctor>(new CInstant(this->data_srv));
473             
474         if (hasOutputFile) 
475         {
476           const CDuration toffset = this->freq_operation_srv - freq_offset_ - context->getCalendar()->getTimeStep(); 
477           *this->last_operation_srv   = *this->last_operation_srv - toffset;
478         }
479      }
480     
481//      if (context->hasClient)
482//      {                 
483         this->freq_operation = CDuration::FromString(freq_op.getValue());
484         if (hasOutputFile) this->freq_write     = CDuration::FromString(this->file->output_freq.getValue());
485         if (hasFieldOut) 
486         {
487           this->freq_write = CDuration::FromString(this->fieldOut->freq_op.getValue());
488         }
489         this->last_Write     = boost::shared_ptr<CDate>
490                        (new CDate(context->getCalendar()->getInitDate()));
491         this->last_operation = boost::shared_ptr<CDate>
492                        (new CDate(context->getCalendar()->getInitDate()));
493                       
494         const CDuration toffset = this->freq_operation - freq_offset_ - context->getCalendar()->getTimeStep(); 
495         *this->last_operation   = *this->last_operation - toffset; 
496     
497        if (operation.get()=="once") isOnceOperation=true ;
498        else isOnceOperation=false;
499        isFirstOperation=true;
500       
501         
502#define DECLARE_FUNCTOR(MType, mtype)              \
503   if  (operation.getValue().compare(#mtype) == 0) \
504   {                                               \
505      if (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value==true) \
506      { \
507        boost::shared_ptr<func::CFunctor> foperation_(new C##MType(this->data,default_value)); \
508        this->foperation = foperation_; \
509      } \
510      else \
511      { \
512        boost::shared_ptr<func::CFunctor> foperation_(new C##MType(this->data)); \
513        this->foperation = foperation_;  \
514      } \
515      return;                                      \
516   }
517   
518#include "functor_type.conf"
519         
520         ERROR("CField::solveOperation(void)",
521               << "[ operation = " << operation.getValue() << "]"
522               << "The operation is not defined !");
523//      }
524     
525
526   }
527   
528   //----------------------------------------------------------------
529/*
530   void CField::fromBinary(StdIStream & is)
531   {
532      SuperClass::fromBinary(is);
533#define CLEAR_ATT(name_)\
534      SuperClassAttribute::operator[](#name_)->reset()
535
536         CLEAR_ATT(domain_ref);
537         CLEAR_ATT(axis_ref);
538#undef CLEAR_ATT
539
540   }
541*/
542   //----------------------------------------------------------------
543
544   void CField::solveGridReference(void)
545   {
546      CDomain* domain;
547      CAxis* axis;
548
549      if (!domain_ref.isEmpty())
550      {
551         if (CDomain::has(domain_ref.getValue()))
552            domain = CDomain::get(domain_ref.getValue()) ;
553         else
554            ERROR("CField::solveGridReference(void)",
555                  << "Reference to the domain \'"
556                  << domain_ref.getValue() << "\' is wrong") ;
557      }
558
559      if (!axis_ref.isEmpty())
560      {
561         if (CAxis::has(axis_ref.getValue()))
562            axis = CAxis::get(axis_ref.getValue()) ;
563         else
564            ERROR("CField::solveGridReference(void)",
565                  << "Reference to the axis \'"
566                  << axis_ref.getValue() <<"\' is wrong") ;
567      }
568
569      if (!grid_ref.isEmpty())
570      {
571         if (CGrid::has(grid_ref.getValue()))
572            this->grid = CGrid::get(grid_ref.getValue()) ;
573         else
574            ERROR("CField::solveGridReference(void)",
575                  << "Reference to the grid \'"
576                  << grid_ref.getValue() << "\' is wrong");
577      }
578     
579      if (grid_ref.isEmpty() &&  domain_ref.isEmpty())
580      {
581            ERROR("CField::solveGridReference(void)",
582                  << "The horizontal domain for this field is not defined");
583
584     }
585     
586     CType<string> goodDomain ;
587     CType<string> goodAxis ;
588     if (!grid_ref.isEmpty())
589     {
590       if (!grid->domain_ref.isEmpty()) goodDomain=grid->domain_ref ;
591       if (!grid->axis_ref.isEmpty()) goodAxis=grid->axis_ref ;
592     }
593     if (!domain_ref.isEmpty()) goodDomain=domain_ref ;
594     if (!axis_ref.isEmpty()) goodAxis=axis_ref ;
595     
596     
597     if (goodDomain.isEmpty()) 
598     {
599       ERROR("CField::solveGridReference(void)", << "The horizontal domain for this field is not defined");
600     }
601     else 
602     {
603       if (CDomain::has(goodDomain)) domain = CDomain::get(goodDomain) ;
604       else ERROR("CField::solveGridReference(void)",<< "Reference to the domain \'"<<goodDomain.get() << "\' is wrong") ;
605     }
606 
607     if (!goodAxis.isEmpty())
608     {
609       if (CAxis::has(goodAxis))  axis = CAxis::get(goodAxis) ;
610       else  ERROR("CField::solveGridReference(void)", << "Reference to the axis \'"
611                  << goodAxis.get() <<"\' is wrong") ;
612     } 
613   
614     bool nothingToDo=false ;
615     
616     if (!grid_ref.isEmpty())
617     {
618       if (!grid->domain_ref.isEmpty() && goodDomain.get() == grid->domain_ref.get())
619         if (goodAxis.isEmpty()) nothingToDo=true ;
620         else if (!grid->axis_ref.isEmpty()) 
621                 if (grid->axis_ref.get()==goodAxis.get()) nothingToDo=true ;
622     }
623     
624     if (!nothingToDo)
625     {
626       if (!goodAxis.isEmpty())
627       {
628         this->grid = CGrid::createGrid(domain, axis) ;
629         this->grid_ref.setValue(this->grid->getId());
630       }
631       else
632       {
633         this->grid = CGrid::createGrid(domain) ;
634         this->grid_ref.setValue(this->grid->getId());
635       }   
636     }
637
638     grid->solveReference() ;
639
640   }
641
642
643   ///-------------------------------------------------------------------
644
645   template <>
646      void CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)
647   {
648      if (this->group_ref.isEmpty()) return;
649      StdString gref = this->group_ref.getValue();
650
651      if (!CFieldGroup::has(gref))
652         ERROR("CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)",
653               << "[ gref = " << gref << "]"
654               << " invalid group name !");
655
656      CFieldGroup* group = CFieldGroup::get(gref);
657      CFieldGroup* owner = CFieldGroup::get(boost::polymorphic_downcast<CFieldGroup*>(this));
658
659      std::vector<CField*> allChildren  = group->getAllChildren();
660      std::vector<CField*>::iterator
661         it = allChildren.begin(), end = allChildren.end();
662     
663      for (; it != end; it++)
664      {
665         CField* child = *it;
666         if (child->hasId()) owner->createChild()->field_ref.setValue(child->getId()) ;
667           
668      }
669   }
670   
671   void CField::scaleFactorAddOffset(double scaleFactor, double addOffset)
672   {
673     map<int, CArray<double,1>* >::iterator it;
674     for(it=data_srv.begin();it!=data_srv.end();it++) *it->second = (*it->second -addOffset) * 1./scaleFactor  ;
675   }
676   
677   void CField::outputField(CArray<double,3>& fieldOut)
678   {
679      map<int, CArray<double,1>* >::iterator it;
680      for(it=data_srv.begin();it!=data_srv.end();it++)
681         grid->outputField(it->first,*it->second, fieldOut) ;
682     
683   }
684   
685   void CField::outputField(CArray<double,2>& fieldOut)
686   {
687      map<int, CArray<double,1>* >::iterator it;
688
689      for(it=data_srv.begin();it!=data_srv.end();it++)
690      {
691         grid->outputField(it->first,*it->second, fieldOut) ;
692      }
693   }
694   ///-------------------------------------------------------------------
695
696   void CField::parse(xml::CXMLNode & node)
697   {
698      SuperClass::parse(node);
699      if (! node.getContent(this->content)) 
700      {
701        if (node.goToChildElement())
702        {
703          do
704          {
705            if (node.getElementName()=="variable" || node.getElementName()=="variable_group") this->getVirtualVariableGroup()->parseChild(node);
706          } while (node.goToNextElement()) ;
707          node.goToParentElement();
708        }
709      }
710    }
711   
712  CArray<double,1>* CField::getInstantData(void)
713  {
714    if (!hasInstantData) 
715    {
716      instantData.resize(grid->storeIndex_client.numElements()) ;
717      hasInstantData=true ;
718    }
719    return &instantData ;
720  }
721 
722  void CField::addReference(CField* field)
723  {
724    refObject.push_back(field) ;
725  }
726 
727  void CField::addDependency(CField* field, int slotId)
728  {
729    fieldDependency.push_back(pair<CField*,int>(field,slotId)) ;
730  }
731 
732  void CField::buildExpression(void)
733  {
734    if (content.size() > 0) 
735    {
736      CSimpleNodeExpr* simpleExpr=parseExpr(content+'\0') ;
737      expression=CFieldNode::newNode(simpleExpr) ;
738      delete simpleExpr ;
739      set<string> instantFieldIds ;
740      map<string,CField*> associatedInstantFieldIds ;
741      expression->getInstantFieldIds(instantFieldIds) ;
742      for (set<string>::iterator it=instantFieldIds.begin() ; it!=instantFieldIds.end();++it) 
743      {
744        if (*it!="this") 
745        {
746          if (CField::has(*it)) 
747          {
748            CField* field=CField::get(*it) ;
749            field->processEnabledField() ;
750            associatedInstantFieldIds[*it]=field ;
751          }
752          else  ERROR("void CField::buildExpression(void)",<<" Field "<<*it<<" does not exist") ;
753        }
754      }
755     
756      set<string> averageFieldIds ;
757      map<string,CField*> associatedAverageFieldIds ;
758
759      expression->getAverageFieldIds(averageFieldIds) ;
760      for (set<string>::iterator it=averageFieldIds.begin() ; it!=averageFieldIds.end();++it) 
761      {     
762        if (CField::has(*it)) 
763        {
764           CFieldGroup* root=CFieldGroup::get("field_definition") ;
765           CField* averageField=root->createChild() ;
766           CField* instantField=root->createChild() ;
767           averageField->field_ref=*it ;
768           averageField->hasFieldOut=true ;
769           averageField->fieldOut=instantField ;
770           instantField->freq_op=freq_op ;
771           averageField-> processEnabledField() ;
772           cout<<" outputfreq of averageField "<<  freq_op <<"  "<<instantField->freq_op<<"  "<< averageField->freq_write << endl ;
773           instantField->SuperClassAttribute::setAttributes(averageField, true);
774           instantField->field_ref.reset() ;
775           instantField->operation.reset() ;
776
777           instantField-> processEnabledField() ;
778           associatedAverageFieldIds[*it]=instantField  ;
779        }
780        else ERROR("void CField::buildExpression(void)",<<" Field "<<*it<<" does not exist") ;
781      }
782
783      expression->reduce(this,associatedInstantFieldIds,associatedAverageFieldIds) ;
784
785      slots.resize(instantFieldIds.size()+averageFieldIds.size()) ;
786      resetSlots() ;
787      int slotId=0 ;
788      set<CField*> fields ;
789      expression->getFields(fields) ;
790      for (set<CField*>::iterator it=fields.begin() ; it!=fields.end();++it,++slotId) (*it)->addDependency(this,slotId) ;
791      hasExpression=true; 
792    }
793  }
794 
795  void CField::resetSlots(void)
796  {
797    for(vector<bool>::iterator it=slots.begin();it!=slots.end();++it) *it=false ;
798  }
799 
800  bool CField::slotsFull(void)
801  {
802    bool ret=true ;
803    for(vector<bool>::iterator it=slots.begin();it!=slots.end();++it) ret &= *it;
804    return ret ;
805  }
806
807 
808  void CField::setSlot(int slotId)
809  {
810    CContext* context = CContext::getCurrent() ;
811    const CDate & currDate = context->getCalendar()->getCurrentDate();
812    if (slotUpdateDate==NULL || currDate!=*slotUpdateDate) 
813    {
814      resetSlots() ;
815      if (slotUpdateDate==NULL) slotUpdateDate=new CDate(currDate) ;
816      else *slotUpdateDate=currDate ;
817    }
818    slots[slotId]=true ;
819    if (slotsFull())
820    {
821      CArray<double,1> expr(expression->compute()) ;
822     
823      if (hasInstantData) 
824      {
825        instantData=expr ;
826        for(list< pair<CField *,int> >::iterator it=fieldDependency.begin(); it!=fieldDependency.end(); ++it) 
827          if (it->first!=this) it->first->setSlot(it->second) ;
828      }
829     
830      if (hasOutputFile) updateDataFromExpression(expr) ;
831     
832    }
833  }
834
835
836
837   CVariable* CField::addVariable(const string& id)
838   {
839     return vVariableGroup->createChild(id) ;
840   }
841
842   CVariableGroup* CField::addVariableGroup(const string& id)
843   {
844     return vVariableGroup->createChildGroup(id) ;
845   }
846
847
848   void CField::sendAddVariable(const string& id)
849   {
850    CContext* context=CContext::getCurrent() ;
851   
852    if (! context->hasServer )
853    {
854       CContextClient* client=context->client ;
855
856       CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE) ;   
857       if (client->isServerLeader())
858       {
859         CMessage msg ;
860         msg<<this->getId() ;
861         msg<<id ;
862         event.push(client->getServerLeader(),1,msg) ;
863         client->sendEvent(event) ;
864       }
865       else client->sendEvent(event) ;
866    }
867     
868   }
869 
870   
871   void CField::sendAddVariableGroup(const string& id)
872   {
873    CContext* context=CContext::getCurrent() ;
874    if (! context->hasServer )
875    {
876       CContextClient* client=context->client ;
877
878       CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE_GROUP) ;   
879       if (client->isServerLeader())
880       {
881         CMessage msg ;
882         msg<<this->getId() ;
883         msg<<id ;
884         event.push(client->getServerLeader(),1,msg) ;
885         client->sendEvent(event) ;
886       }
887       else client->sendEvent(event) ;
888    }
889     
890   }
891   
892   void CField::recvAddVariable(CEventServer& event)
893   {
894     
895      CBufferIn* buffer=event.subEvents.begin()->buffer;
896      string id;
897      *buffer>>id ;
898      get(id)->recvAddVariable(*buffer) ;
899   }
900   
901   
902   void CField::recvAddVariable(CBufferIn& buffer)
903   {
904      string id ;
905      buffer>>id ;
906      addVariable(id) ;
907   }
908
909   void CField::recvAddVariableGroup(CEventServer& event)
910   {
911     
912      CBufferIn* buffer=event.subEvents.begin()->buffer;
913      string id;
914      *buffer>>id ;
915      get(id)->recvAddVariableGroup(*buffer) ;
916   }
917   
918   
919   void CField::recvAddVariableGroup(CBufferIn& buffer)
920   {
921      string id ;
922      buffer>>id ;
923      addVariableGroup(id) ;
924   }
925
926
927
928 
929} // namespace xios
Note: See TracBrowser for help on using the repository browser.