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

Last change on this file since 620 was 620, checked in by mhnguyen, 6 years ago

Implementing generic transformation algorithm (local commit)

+) Implement 3 important classes:

-gridTransformation to read transformation info from grid and interface with the rest of XIOS
-transformationMapping to be in charge of sending/receiving transformation info among clients
-transformationAlgorithm to represent various algorithms

+) Make some change on field to use the new classes

Test
+) Only test_new_features with inversed axis

  • 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
  • Property svn:executable set to *
File size: 43.8 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 "xios_spl.hpp"
11#include "type.hpp"
12#include "context_client.hpp"
13#include "context_server.hpp"
14#include <set>
15#include "axis_filter.hpp"
16#include "invert_algorithm.hpp"
17
18namespace xios{
19
20   /// ////////////////////// Définitions ////////////////////// ///
21
22   CField::CField(void)
23      : CObjectTemplate<CField>(), CFieldAttributes()
24      , refObject(), baseRefObject()
25      , grid(), file()
26      , freq_operation(), freq_write()
27      , nstep(0), nstepMax(0), isEOF(false)
28      , last_Write(), last_operation()
29      , foperation(), hasInstantData(false), hasExpression(false)
30      , active(false) , hasOutputFile(false),hasFieldOut(false), slotUpdateDate(NULL)
31      , processed(false), domAxisIds_("", ""), areAllReferenceSolved(false), areAllExpressionBuilt(false), filter(0)
32      , isReadDataRequestPending(false)
33      { setVirtualVariableGroup(); }
34
35   CField::CField(const StdString& id)
36      : CObjectTemplate<CField>(id), CFieldAttributes()
37      , refObject(), baseRefObject()
38      , grid(), file()
39      , freq_operation(), freq_write()
40      , nstep(0), nstepMax(0), isEOF(false)
41      , last_Write(), last_operation()
42      , foperation(), hasInstantData(false), hasExpression(false)
43      , active(false), hasOutputFile(false), hasFieldOut(false), slotUpdateDate(NULL)
44      , processed(false), domAxisIds_("", ""), areAllReferenceSolved(false), areAllExpressionBuilt(false), filter(0)
45      , isReadDataRequestPending(false)
46   { setVirtualVariableGroup(); }
47
48   CField::~CField(void)
49   {
50//      this->grid.reset();
51//      this->file.reset();
52      this->foperation.reset();
53      if (hasExpression) delete expression;
54      if (slotUpdateDate != NULL) delete slotUpdateDate;
55      if (0 != filter) delete filter;
56
57   }
58
59
60  //----------------------------------------------------------------
61
62   void CField::setVirtualVariableGroup(CVariableGroup* newVVariableGroup)
63   {
64      this->vVariableGroup = newVVariableGroup;
65   }
66
67   void CField::setVirtualVariableGroup(void)
68   {
69      this->setVirtualVariableGroup(CVariableGroup::create());
70   }
71
72   CVariableGroup* CField::getVirtualVariableGroup(void) const
73   {
74      return this->vVariableGroup;
75   }
76
77
78   std::vector<CVariable*> CField::getAllVariables(void) const
79   {
80      return this->vVariableGroup->getAllChildren();
81   }
82
83   void CField::solveDescInheritance(bool apply, const CAttributeMap* const parent)
84   {
85      SuperClassAttribute::setAttributes(parent, apply);
86      this->getVirtualVariableGroup()->solveDescInheritance(apply, NULL);
87   }
88   //----------------------------------------------------------------
89   //----------------------------------------------------------------
90
91   bool CField::updateDataServer
92      (const CDate& currDate,
93       const std::deque< CArray<double, 1>* > storedClient)
94   {
95      const CDate opeDate      = *last_operation + freq_operation;
96      const CDate writeDate    = *last_Write     + freq_write;
97
98      if (opeDate <= currDate)
99      {
100         if (this->data.numElements() != this->grid->storeIndex[0]->numElements())
101         {
102            this->data.resize(this->grid->storeIndex[0]->numElements());
103         }
104         CArray<double,1> input(data.numElements());
105         this->grid->inputFieldServer(storedClient, input);
106         (*this->foperation)(input);
107         *last_operation = currDate;
108      }
109      if (writeDate < (currDate + freq_operation))
110      {
111         this->foperation->final();
112         this->incrementNStep();
113         *last_Write = writeDate;
114         return true;
115      }
116      return false;
117   }
118
119  bool CField::dispatchEvent(CEventServer& event)
120  {
121    if (SuperClass::dispatchEvent(event)) return true;
122    else
123    {
124      switch(event.type)
125      {
126        case EVENT_ID_UPDATE_DATA :
127          recvUpdateData(event);
128          return true;
129          break;
130
131        case EVENT_ID_READ_DATA :
132          recvReadDataRequest(event);
133          return true;
134          break;
135
136        case EVENT_ID_READ_DATA_READY :
137          recvReadDataReady(event);
138          return true;
139          break;
140
141        case EVENT_ID_ADD_VARIABLE :
142          recvAddVariable(event);
143          return true;
144          break;
145
146        case EVENT_ID_ADD_VARIABLE_GROUP :
147          recvAddVariableGroup(event);
148          return true;
149          break;
150
151        default :
152          ERROR("bool CField::dispatchEvent(CEventServer& event)", << "Unknown Event");
153          return false;
154      }
155    }
156  }
157
158  void CField::sendUpdateData(void)
159  {
160    CContext* context = CContext::getCurrent();
161    CContextClient* client = context->client;
162
163    CEventClient event(getType(),EVENT_ID_UPDATE_DATA);
164
165    map<int,CArray<int, 1>* >::iterator it;
166    list<shared_ptr<CMessage> > list_msg;
167    list< CArray<double,1>* > list_data;
168
169    if (!grid->doGridHaveDataDistributed())
170    {
171       if (0 == client->clientRank)
172       {
173          for(it=grid->storeIndex_toSrv.begin();it!=grid->storeIndex_toSrv.end();it++)
174          {
175            int rank=(*it).first ;
176            CArray<int,1>& index = *(it->second) ;
177                       std::cout << "rank " << index << std::endl;
178                       std::cout << "data " << data << std::endl;
179            CArray<double,1> data_tmp(index.numElements()) ;
180            for(int n=0;n<data_tmp.numElements();n++) data_tmp(n)=data(index(n)) ;
181
182            list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
183            list_data.push_back(new CArray<double,1>(data_tmp)) ;
184            *list_msg.back()<<getId()<<*list_data.back() ;
185            event.push(rank,1,*list_msg.back()) ;
186          }
187          client->sendEvent(event) ;
188       } else client->sendEvent(event);
189    }
190    else
191    {
192      for(it=grid->storeIndex_toSrv.begin();it!=grid->storeIndex_toSrv.end();it++)
193      {
194        int rank=(*it).first ;
195        CArray<int,1>& index = *(it->second) ;
196        CArray<double,1> data_tmp(index.numElements()) ;
197        for(int n=0;n<data_tmp.numElements();n++) data_tmp(n)=data(index(n)) ;
198        list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
199        list_data.push_back(new CArray<double,1>(data_tmp)) ;
200        *list_msg.back()<<getId()<<*list_data.back() ;
201        event.push(rank,grid->nbSenders[rank],*list_msg.back()) ;
202      }
203      client->sendEvent(event) ;
204    }
205
206    for (list< CArray<double,1>* >::iterator it = list_data.begin(); it != list_data.end(); it++) delete *it;
207  }
208
209  void CField::recvUpdateData(CEventServer& event)
210  {
211    vector<int> ranks;
212    vector<CBufferIn*> buffers;
213
214    list<CEventServer::SSubEvent>::iterator it;
215    string fieldId;
216
217    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
218    {
219      int rank = it->rank;
220      CBufferIn* buffer = it->buffer;
221      *buffer >> fieldId;
222      ranks.push_back(rank);
223      buffers.push_back(buffer);
224    }
225    get(fieldId)->recvUpdateData(ranks,buffers);
226  }
227
228  void  CField::recvUpdateData(vector<int>& ranks, vector<CBufferIn*>& buffers)
229  {
230    if (data_srv.empty())
231    {
232      for (map<int, CArray<size_t, 1>* >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
233      {
234        int rank = it->first;
235        CArray<double,1> data_tmp(it->second->numElements());
236        data_srv.insert( pair<int, CArray<double,1>* >(rank, new CArray<double,1>(data_tmp)));
237        foperation_srv.insert(pair<int,boost::shared_ptr<func::CFunctor> >(rank,boost::shared_ptr<func::CFunctor>(new func::CInstant(*data_srv[rank]))));
238      }
239    }
240
241    CContext* context = CContext::getCurrent();
242    const CDate& currDate = context->getCalendar()->getCurrentDate();
243    const CDate opeDate      = *last_operation_srv + freq_operation_srv;
244    const CDate writeDate    = *last_Write_srv     + freq_write_srv;
245
246    if (opeDate <= currDate)
247    {
248      for (int n = 0; n < ranks.size(); n++)
249      {
250        CArray<double,1> data_tmp;
251        *buffers[n] >> data_tmp;
252        (*foperation_srv[ranks[n]])(data_tmp);
253      }
254      *last_operation_srv = currDate;
255    }
256
257    if (writeDate < (currDate + freq_operation_srv))
258    {
259      for (int n = 0; n < ranks.size(); n++)
260      {
261        this->foperation_srv[ranks[n]]->final();
262      }
263
264      *last_Write_srv = writeDate;
265      writeField();
266      *lastlast_Write_srv = *last_Write_srv;
267    }
268  }
269
270  void CField::writeField(void)
271  {
272    if (!getRelFile()->allDomainEmpty)
273    {
274      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)
275      {
276        getRelFile()->checkFile();
277        this->incrementNStep();
278        getRelFile()->getDataOutput()->writeFieldData(CField::get(this));
279      }
280    }
281  }
282
283  void CField::sendReadDataRequest(void)
284  {
285    CContext* context = CContext::getCurrent();
286    CContextClient* client = context->client;
287
288    CEventClient event(getType(), EVENT_ID_READ_DATA);
289    if (client->isServerLeader())
290    {
291      CMessage msg;
292      msg << getId();
293      const std::list<int>& ranks = client->getRanksServerLeader();
294      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
295        event.push(*itRank, 1, msg);
296      client->sendEvent(event);
297    }
298    else client->sendEvent(event);
299
300    lastDataRequestedFromServer = context->getCalendar()->getCurrentDate();
301    isReadDataRequestPending = true;
302  }
303
304  /*!
305  Send request new data read from file if need be, that is the current data is out-of-date.
306  \return true if and only if some data was requested
307  */
308  bool CField::sendReadDataRequestIfNeeded(void)
309  {
310    const CDate& currentDate = CContext::getCurrent()->getCalendar()->getCurrentDate();
311
312    bool requestData = (currentDate >= lastDataRequestedFromServer + file->output_freq.getValue());
313
314    if (requestData)
315      sendReadDataRequest();
316
317    return requestData;
318  }
319
320  void CField::recvReadDataRequest(CEventServer& event)
321  {
322    CBufferIn* buffer = event.subEvents.begin()->buffer;
323    StdString fieldId;
324    *buffer >> fieldId;
325    get(fieldId)->recvReadDataRequest();
326  }
327
328  void CField::recvReadDataRequest(void)
329  {
330    CContext* context = CContext::getCurrent();
331    CContextClient* client = context->client;
332
333    CEventClient event(getType(), EVENT_ID_READ_DATA_READY);
334    std::list<CMessage> msgs;
335
336    bool hasData = readField();
337
338    map<int, CArray<double,1>* >::iterator it;
339    for (it = data_srv.begin(); it != data_srv.end(); it++)
340    {
341      msgs.push_back(CMessage());
342      CMessage& msg = msgs.back();
343      msg << getId();
344      if (hasData)
345        msg << getNStep() - 1 << *it->second;
346      else
347        msg << size_t(-1);
348      event.push(it->first, grid->nbSenders[it->first], msg);
349    }
350    client->sendEvent(event);
351  }
352
353  bool CField::readField(void)
354  {
355    if (!getRelFile()->allDomainEmpty)
356    {
357      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)
358      {
359        if (data_srv.empty())
360        {
361          for (map<int, CArray<size_t, 1>* >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
362            data_srv.insert(pair<int, CArray<double,1>*>(it->first, new CArray<double,1>(it->second->numElements())));
363        }
364
365        getRelFile()->checkFile();
366        this->incrementNStep();
367
368        if (!nstepMax)
369        {
370          nstepMax = getRelFile()->getDataInput()->getFieldNbRecords(CField::get(this));
371        }
372
373        if (getNStep() > nstepMax)
374          return false;
375
376        getRelFile()->getDataInput()->readFieldData(CField::get(this));
377      }
378    }
379
380    return true;
381  }
382
383  void CField::recvReadDataReady(CEventServer& event)
384  {
385    string fieldId;
386    vector<int> ranks;
387    vector<CBufferIn*> buffers;
388
389    list<CEventServer::SSubEvent>::iterator it;
390    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
391    {
392      ranks.push_back(it->rank);
393      CBufferIn* buffer = it->buffer;
394      *buffer >> fieldId;
395      buffers.push_back(buffer);
396    }
397    get(fieldId)->recvReadDataReady(ranks, buffers);
398  }
399
400  void CField::recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers)
401  {
402    CContext* context = CContext::getCurrent();
403    StdSize record;
404    for (int i = 0; i < ranks.size(); i++)
405    {
406      int rank = ranks[i];
407      *buffers[i] >> record;
408      isEOF = (record == size_t(-1));
409
410      if (!isEOF)
411      {
412        CArray<int,1>& index = *grid->storeIndex_toSrv[rank];
413        CArray<double,1> data_tmp(index.numElements());
414        *buffers[i] >> data_tmp;
415        for (int n = 0; n < data_tmp.numElements(); n++)
416          instantData(index(n)) = data_tmp(n);
417      }
418      else
419        break;
420    }
421
422    if (!isEOF)
423    {
424      for (list< pair<CField*, int> >::iterator it = fieldDependency.begin(); it != fieldDependency.end(); ++it)
425        it->first->setSlot(it->second);
426
427      if (!hasExpression) // Should be always true ?
428      {
429        const std::vector<CField*>& refField = getAllReference();
430        std::vector<CField*>::const_iterator it = refField.begin(), end = refField.end();
431
432        for (; it != end; it++) (*it)->setDataFromExpression(instantData);
433        if (hasFieldOut) updateDataFromExpression(instantData);
434      }
435    }
436
437    isReadDataRequestPending = false;
438  }
439
440   //----------------------------------------------------------------
441
442   void CField::setRelFile(CFile* _file)
443   {
444      this->file = _file;
445      hasOutputFile = true;
446   }
447
448   //----------------------------------------------------------------
449
450   StdString CField::GetName(void)    { return StdString("field"); }
451   StdString CField::GetDefName(void) { return CField::GetName(); }
452   ENodeType CField::GetType(void)    { return eField; }
453
454   //----------------------------------------------------------------
455
456   CGrid* CField::getRelGrid(void) const
457   {
458      return this->grid;
459   }
460
461   //----------------------------------------------------------------
462
463   CFile* CField::getRelFile(void) const
464   {
465      return this->file;
466   }
467
468   StdSize CField::getNStep(void) const
469   {
470      return this->nstep;
471   }
472
473   void CField::incrementNStep(void)
474   {
475      this->nstep++;
476   }
477
478   void CField::resetNStep(void)
479   {
480      this->nstep = 0;
481   }
482
483   void CField::resetNStepMax(void)
484   {
485      this->nstepMax = 0;
486   }
487
488   //----------------------------------------------------------------
489
490   const CDuration& CField::getFreqOperation(void) const
491   {
492      return this->freq_operation;
493   }
494
495   //----------------------------------------------------------------
496
497   const CDuration& CField::getFreqWrite(void) const
498   {
499      return this->freq_write;
500   }
501
502   //----------------------------------------------------------------
503
504   boost::shared_ptr<func::CFunctor> CField::getFieldOperation(void) const
505   {
506      return this->foperation;
507   }
508
509   bool CField::isActive(void) const
510   {
511      return !this->refObject.empty();
512   }
513
514   //----------------------------------------------------------------
515
516   CArray<double, 1> CField::getData(void) const
517   {
518      return(this->data);
519   }
520
521   //----------------------------------------------------------------
522
523   boost::shared_ptr<CDate> CField::getLastWriteDate(void) const
524   {
525      return(this->last_Write);
526   }
527
528   //----------------------------------------------------------------
529
530   boost::shared_ptr<CDate> CField::getLastOperationDate(void) const
531   {
532      return(this->last_operation);
533   }
534
535   void CField::solveAllReferenceEnabledField(bool doSending2Sever)
536   {
537     CContext* context = CContext::getCurrent();
538     if (!areAllReferenceSolved)
539     {
540        areAllReferenceSolved = true;
541        if (context->hasClient)
542        {
543          solveRefInheritance(true);
544          solveBaseReference();
545        }
546
547        solveOperation();
548        solveGridReference();
549     }
550     solveGridDomainAxisRef(doSending2Sever);
551     solveCheckMaskIndex(doSending2Sever);
552     if (context->hasClient)
553     {
554       solveTransformedGrid();
555     }
556   }
557
558   std::map<int, StdSize> CField::getGridDataSize()
559   {
560     return grid->getConnectedServerDataSize();
561   }
562
563   void CField::buildAllExpressionEnabledField()
564   {
565     if (!areAllReferenceSolved) solveAllReferenceEnabledField(true);
566     if (!areAllExpressionBuilt)
567     {
568       areAllExpressionBuilt = true;
569       if (hasDirectFieldReference() && (grid_ref.isEmpty())) baseRefObject->buildAllExpressionEnabledField();
570       buildExpression();
571       active = true;
572     }
573   }
574
575   //----------------------------------------------------------------
576
577   void  CField::solveOperation(void)
578   {
579      using namespace func;
580
581      if (!hasOutputFile && !hasFieldOut) return;
582
583      StdString id;
584      if (hasId()) id = getId();
585      else if (!name.isEmpty()) id = name;
586      else if (hasDirectFieldReference()) id = baseRefObject->getId();
587
588      CContext* context = CContext::getCurrent();
589
590      if (freq_op.isEmpty()) freq_op.setValue(TimeStep);
591
592      if (operation.isEmpty())
593      {
594         ERROR("CField::solveOperation(void)",
595               << "[ id = " << id << "]"
596               << "Impossible to define an operation for this field !");
597      }
598
599      if (freq_offset.isEmpty())
600        freq_offset.setValue(NoneDu);
601
602//      if (CXIOSManager::GetStatus() == CXIOSManager::LOC_SERVER)
603      if (context->hasServer)
604      {
605         if (hasOutputFile)
606         {
607           this->freq_operation_srv = this->file->output_freq.getValue();
608           this->freq_write_srv = this->file->output_freq.getValue();
609         }
610         this->lastlast_Write_srv = boost::shared_ptr<CDate>
611                        (new CDate(context->getCalendar()->getInitDate()));
612         this->last_Write_srv     = boost::shared_ptr<CDate>
613                        (new CDate(context->getCalendar()->getInitDate()));
614         this->last_operation_srv = boost::shared_ptr<CDate>
615                        (new CDate(context->getCalendar()->getInitDate()));
616//         this->foperation_srv     =
617//             boost::shared_ptr<func::CFunctor>(new CInstant(this->data_srv));
618
619         if (hasOutputFile)
620         {
621           const CDuration toffset = this->freq_operation_srv - freq_offset.getValue() - context->getCalendar()->getTimeStep();
622           *this->last_operation_srv   = *this->last_operation_srv - toffset;
623         }
624      }
625
626//      if (context->hasClient)
627//      {
628         this->freq_operation = freq_op.getValue();
629         if (hasOutputFile) this->freq_write = this->file->output_freq.getValue();
630         if (hasFieldOut)
631         {
632           this->freq_write = this->fieldOut->freq_op.getValue();
633         }
634         this->last_Write     = boost::shared_ptr<CDate>
635                        (new CDate(context->getCalendar()->getInitDate()));
636         this->last_operation = boost::shared_ptr<CDate>
637                        (new CDate(context->getCalendar()->getInitDate()));
638
639         const CDuration toffset = this->freq_operation - freq_offset.getValue() - context->getCalendar()->getTimeStep();
640         *this->last_operation   = *this->last_operation - toffset;
641
642         lastDataRequestedFromServer.setRelCalendar(*context->getCalendar());
643
644        if (operation.get() == "once") isOnceOperation = true;
645        else isOnceOperation = false;
646        isFirstOperation = true;
647
648#define DECLARE_FUNCTOR(MType, mtype) \
649   if (operation.getValue().compare(#mtype) == 0) \
650   { \
651      if (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true) \
652      { \
653        boost::shared_ptr<func::CFunctor> foperation_(new C##MType(this->data,default_value)); \
654        this->foperation = foperation_; \
655      } \
656      else \
657      { \
658        boost::shared_ptr<func::CFunctor> foperation_(new C##MType(this->data)); \
659        this->foperation = foperation_; \
660      } \
661      return; \
662   }
663
664#include "functor_type.conf"
665
666         ERROR("CField::solveOperation(void)",
667               << "[ operation = " << operation.getValue() << "]"
668               << "The operation is not defined !");
669//      }
670   }
671
672   //----------------------------------------------------------------
673/*
674   void CField::fromBinary(StdIStream& is)
675   {
676      SuperClass::fromBinary(is);
677#define CLEAR_ATT(name_)\
678      SuperClassAttribute::operator[](#name_)->reset()
679
680         CLEAR_ATT(domain_ref);
681         CLEAR_ATT(axis_ref);
682#undef CLEAR_ATT
683
684   }
685*/
686   //----------------------------------------------------------------
687
688   void CField::solveGridReference(void)
689   {
690      CDomain* domain;
691      CAxis* axis;
692      std::vector<CDomain*> vecDom;
693      std::vector<CAxis*> vecAxis;
694      std::vector<std::string> domList, axisList;
695
696      if (!domain_ref.isEmpty())
697      {
698         if (CDomain::has(domain_ref.getValue()))
699         {
700           domain = CDomain::get(domain_ref.getValue());
701           vecDom.push_back(domain);
702         }
703         else
704            ERROR("CField::solveGridReference(void)",
705                  << "Reference to the domain \'"
706                  << domain_ref.getValue() << "\' is wrong");
707      }
708
709      if (!axis_ref.isEmpty())
710      {
711         if (CAxis::has(axis_ref.getValue()))
712         {
713           axis = CAxis::get(axis_ref.getValue());
714           vecAxis.push_back(axis);
715         }
716         else
717            ERROR("CField::solveGridReference(void)",
718                  << "Reference to the axis \'"
719                  << axis_ref.getValue() <<"\' is wrong");
720      }
721
722      if (!grid_ref.isEmpty())
723      {
724         if (CGrid::has(grid_ref.getValue()))
725         {
726           this->grid = CGrid::get(grid_ref.getValue());
727           domList = grid->getDomainList();
728           axisList = grid->getAxisList();
729           if (domList.empty() && axisList.empty())
730           {
731             this->grid = CGrid::createGrid(vecDom, vecAxis);
732           }
733         }
734         else
735            ERROR("CField::solveGridReference(void)",
736                  << "Reference to the grid \'"
737                  << grid_ref.getValue() << "\' is wrong");
738      }
739      else
740      {
741         this->grid = CGrid::createGrid(vecDom, vecAxis);
742      }
743
744      if (grid_ref.isEmpty() && domain_ref.isEmpty() && axis_ref.isEmpty())
745      {
746            ERROR("CField::solveGridReference(void)",
747                  << "At least one dimension must be defined for this field.");
748      }
749   }
750
751   void CField::solveGridDomainAxisRef(bool checkAtt)
752   {
753     grid->solveDomainAxisRef(checkAtt);
754   }
755
756   void CField::solveCheckMaskIndex(bool doSendingIndex)
757   {
758     grid->checkMaskIndex(doSendingIndex);
759   }
760
761   CGrid* CField::getGridRefOfBaseReference()
762   {
763     solveRefInheritance(true);
764     solveBaseReference();
765     baseRefObject->solveGridReference();
766
767     return baseRefObject->grid;
768   }
769
770   void CField::solveTransformedGrid()
771   {
772     if (!grid_ref.isEmpty() && (!field_ref.isEmpty()))
773     {
774       CField* fieldRef  = this;
775       CGrid* gridRefOfFieldRef = 0;
776       while (fieldRef->hasDirectFieldReference())
777       {
778         if ((!(fieldRef->grid_ref.isEmpty())) &&
779             (fieldRef->grid_ref.getValue() != grid_ref.getValue()))
780         {
781           gridRefOfFieldRef = fieldRef->getGridRefOfBaseReference();
782           fieldRef->addReference(this);
783           fieldRef->solveGridDomainAxisRef(false);
784           fieldRef->solveCheckMaskIndex(false);
785           break;
786         }
787         CField* tmp = fieldRef->getDirectFieldReference();
788         fieldRef = tmp;
789       }
790
791       if ((0 == gridRefOfFieldRef) &&
792           (!(fieldRef->grid_ref.isEmpty())) &&
793           (fieldRef->grid_ref.getValue() != grid_ref.getValue()))
794       {
795         gridRefOfFieldRef = fieldRef->getGridRefOfBaseReference();
796         fieldRef->addReference(this);
797         fieldRef->solveGridDomainAxisRef(false);
798         fieldRef->solveCheckMaskIndex(false);
799       }
800
801       CGrid* relGridRef = CGrid::get(grid_ref.getValue());
802       if ((0 != gridRefOfFieldRef) && (relGridRef != gridRefOfFieldRef) && (!(relGridRef->isTransformed())))
803       {
804         gridRefOfFieldRef->transformGrid(relGridRef);
805         filterSources_.push_back(fieldRef);
806//         transformations_ = relGridRef->getTransformations();
807//         switch (gridRefOfFieldRef->getGridElementType()) {
808//         case CGrid::GRID_ONLY_AXIS:
809////           filter = new CAxisFilter(gridRefOfFieldRef, relGridRef);
810////           break;
811//         default:
812//           filter = new CAxisFilter(gridRefOfFieldRef, relGridRef);
813//           break;
814//         }
815//         setAlgorithms();
816       }
817     }
818   }
819
820
821//  void CField::setAlgorithms()
822//  {
823//    std::vector<ETransformationType>::iterator itTrans  = transformations_.begin(),
824//                                               iteTrans = transformations_.end();
825//    std::set<ETransformationType> tmp;
826//    for (; itTrans != iteTrans; ++itTrans)
827//    {
828//      if (tmp.end() == tmp.find(*itTrans))
829//      {
830//        switch (*itTrans) {
831//        case eInverse:
832//          algorithms_.push_back(new CInvertAlgorithm());
833//          break;
834//        default:
835//          break;
836//        }
837//      }
838//      tmp.insert(*itTrans);
839//    }
840//  }
841
842   const std::vector<CField*>& CField::getFilterSources()
843   {
844     return filterSources_;
845   }
846
847   void CField::applyFilter(const CArray<double, 1>& dataToSend, CArray<double,1>& dataToReceive)
848   {
849     std::vector<CField*>::iterator  itFilterSrc, iteFilterSrc;
850     if (!filterSources_.empty())
851     {
852        itFilterSrc = filterSources_.begin(); iteFilterSrc = filterSources_.end();
853        for (; itFilterSrc != iteFilterSrc; ++itFilterSrc)
854        {
855          if (0 != (*itFilterSrc)->grid->getTransformations())
856          {
857             const std::map<int, CArray<int,1>* >& localIndexToSend = (*itFilterSrc)->grid->getTransformations()->getLocalIndexToSendFromGridSource();
858             const std::map<int, std::vector<CArray<int,1>* > > localIndexToReceive = (*itFilterSrc)->grid->getTransformations()->getLocalIndexToReceiveOnGridDest();
859             sendAndReceiveTransformedData(localIndexToSend, dataToSend,
860                                           localIndexToReceive, dataToReceive);
861          }
862
863        }
864
865//        std::cout << "it data " << (*it)->data << std::endl;
866//        std::cout << "it filtered data " << (*it)->filteredData << std::endl;
867     }
868   }
869
870   void CField::sendAndReceiveTransformedData(const std::map<int, CArray<int,1>* >& localIndexToSend,
871                                              const CArray<double, 1>& dataSrc,
872                                              const std::map<int, std::vector<CArray<int,1>* > >& localIndexToReceive,
873                                              CArray<double,1>& dataDest)
874   {
875     CContext* context = CContext::getCurrent();
876     CContextClient* client=context->client;
877
878     // Sending data from field sources to do transformations
879     std::map<int, CArray<int,1>* >::const_iterator itbSend = localIndexToSend.begin(), itSend,
880                                                    iteSend = localIndexToSend.end();
881     int sendBuffSize = 0;
882     for (itSend = itbSend; itSend != iteSend; ++itSend) sendBuffSize = (sendBuffSize < (itSend->second)->numElements())
883                                                                        ? (itSend->second)->numElements(): sendBuffSize;
884     double* sendBuff;
885     if (0 != sendBuffSize) sendBuff = new double [sendBuffSize];
886     for (itSend = itbSend; itSend != iteSend; ++itSend)
887     {
888       int destRank = itSend->first;
889       CArray<int,1>* localIndex_p = itSend->second;
890       int countSize = localIndex_p->numElements();
891       for (int idx = 0; idx < countSize; ++idx)
892       {
893         sendBuff[idx] = dataSrc((*localIndex_p)(idx));
894       }
895       MPI_Send(sendBuff, countSize, MPI_DOUBLE, destRank, 12, client->intraComm);
896     }
897
898     // Receiving data on destination fields
899     std::map<int, std::vector<CArray<int,1>* > >::const_iterator itbRecv = localIndexToReceive.begin(), itRecv,
900                                                                  iteRecv = localIndexToReceive.end();
901     int recvBuffSize = 0;
902     for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize = (recvBuffSize < (itRecv->second).size())
903                                                                        ? (itRecv->second).size() : recvBuffSize;
904     double* recvBuff;
905     if (0 != recvBuffSize) recvBuff = new double [recvBuffSize];
906     for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
907     {
908       MPI_Status status;
909       int srcRank = itRecv->first;
910       int countSize = (itRecv->second).size();
911       MPI_Recv(recvBuff, recvBuffSize, MPI_DOUBLE, srcRank, 12, client->intraComm, &status);
912       for (int idx = 0; idx < countSize; ++idx)
913       {
914         CArray<int,1>* localIndex_p = (itRecv->second)[idx];
915         int numIndex = localIndex_p->numElements();
916         for (int i = 0; i < numIndex; ++i)
917         {
918           dataDest((*localIndex_p)(i)) = recvBuff[idx];
919         }
920       }
921     }
922
923     if (0 != sendBuffSize) delete [] sendBuff;
924     if (0 != recvBuffSize) delete [] recvBuff;
925   }
926
927   ///-------------------------------------------------------------------
928
929   template <>
930   void CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)
931   {
932      if (this->group_ref.isEmpty()) return;
933      StdString gref = this->group_ref.getValue();
934
935      if (!CFieldGroup::has(gref))
936         ERROR("CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)",
937               << "[ gref = " << gref << "]"
938               << " invalid group name !");
939
940      CFieldGroup* group = CFieldGroup::get(gref);
941      CFieldGroup* owner = CFieldGroup::get(boost::polymorphic_downcast<CFieldGroup*>(this));
942
943      std::vector<CField*> allChildren  = group->getAllChildren();
944      std::vector<CField*>::iterator it = allChildren.begin(), end = allChildren.end();
945
946      for (; it != end; it++)
947      {
948         CField* child = *it;
949         if (child->hasId()) owner->createChild()->field_ref.setValue(child->getId());
950
951      }
952   }
953
954   void CField::scaleFactorAddOffset(double scaleFactor, double addOffset)
955   {
956     map<int, CArray<double,1>* >::iterator it;
957     for (it = data_srv.begin(); it != data_srv.end(); it++) *it->second = (*it->second - addOffset) / scaleFactor;
958   }
959
960   void CField::invertScaleFactorAddOffset(double scaleFactor, double addOffset)
961   {
962     map<int, CArray<double,1>* >::iterator it;
963     for (it = data_srv.begin(); it != data_srv.end(); it++) *it->second = *it->second * scaleFactor + addOffset;
964   }
965
966   void CField::outputField(CArray<double,3>& fieldOut)
967   {
968      map<int, CArray<double,1>* >::iterator it;
969      for (it = data_srv.begin(); it != data_srv.end(); it++)
970      {
971        grid->outputField(it->first,*it->second, fieldOut.dataFirst());
972      }
973   }
974
975   void CField::outputField(CArray<double,2>& fieldOut)
976   {
977      map<int, CArray<double,1>* >::iterator it;
978      for(it=data_srv.begin();it!=data_srv.end();it++)
979      {
980         grid->outputField(it->first,*it->second, fieldOut.dataFirst()) ;
981      }
982   }
983
984   void CField::outputField(CArray<double,1>& fieldOut)
985   {
986      map<int, CArray<double,1>* >::iterator it;
987
988      for (it = data_srv.begin(); it != data_srv.end(); it++)
989      {
990         grid->outputField(it->first,*it->second, fieldOut.dataFirst()) ;
991      }
992   }
993
994   void CField::inputField(CArray<double,3>& fieldOut)
995   {
996      map<int, CArray<double,1>*>::iterator it;
997      for (it = data_srv.begin(); it != data_srv.end(); it++)
998      {
999        grid->inputField(it->first, fieldOut.dataFirst(), *it->second);
1000      }
1001   }
1002
1003   void CField::inputField(CArray<double,2>& fieldOut)
1004   {
1005      map<int, CArray<double,1>*>::iterator it;
1006      for(it = data_srv.begin(); it != data_srv.end(); it++)
1007      {
1008         grid->inputField(it->first, fieldOut.dataFirst(), *it->second);
1009      }
1010   }
1011
1012   void CField::inputField(CArray<double,1>& fieldOut)
1013   {
1014      map<int, CArray<double,1>*>::iterator it;
1015      for (it = data_srv.begin(); it != data_srv.end(); it++)
1016      {
1017         grid->inputField(it->first, fieldOut.dataFirst(), *it->second);
1018      }
1019   }
1020
1021   ///-------------------------------------------------------------------
1022
1023   void CField::parse(xml::CXMLNode& node)
1024   {
1025      SuperClass::parse(node);
1026      if (!node.getContent(this->content))
1027      {
1028        if (node.goToChildElement())
1029        {
1030          do
1031          {
1032            if (node.getElementName() == "variable" || node.getElementName() == "variable_group") this->getVirtualVariableGroup()->parseChild(node);
1033          } while (node.goToNextElement());
1034          node.goToParentElement();
1035        }
1036      }
1037    }
1038
1039  CArray<double,1>* CField::getInstantData(void)
1040  {
1041    if (!hasInstantData)
1042    {
1043      instantData.resize(grid->storeIndex_client.numElements());
1044      hasInstantData = true;
1045    }
1046    return &instantData;
1047  }
1048
1049  void CField::addDependency(CField* field, int slotId)
1050  {
1051    fieldDependency.push_back(pair<CField*,int>(field,slotId));
1052  }
1053
1054  void CField::buildExpression(void)
1055  {
1056    if (content.size() > 0)
1057    {
1058      CSimpleNodeExpr* simpleExpr = parseExpr(content+'\0');
1059      expression = CFieldNode::newNode(simpleExpr);
1060      delete simpleExpr;
1061      set<string> instantFieldIds;
1062      map<string,CField*> associatedInstantFieldIds;
1063      expression->getInstantFieldIds(instantFieldIds);
1064      for (set<string>::iterator it = instantFieldIds.begin(); it != instantFieldIds.end(); ++it)
1065      {
1066        if (*it != "this")
1067        {
1068          if (CField::has(*it))
1069          {
1070            CField* field = CField::get(*it);
1071//            field->processEnabledField();
1072            field->buildAllExpressionEnabledField();
1073            associatedInstantFieldIds[*it] = field;
1074          }
1075          else  ERROR("void CField::buildExpression(void)", << " Field " << *it << " does not exist");
1076        }
1077      }
1078
1079      set<string> averageFieldIds;
1080      map<string,CField*> associatedAverageFieldIds;
1081
1082      expression->getAverageFieldIds(averageFieldIds);
1083      for (set<string>::iterator it = averageFieldIds.begin(); it != averageFieldIds.end(); ++it)
1084      {
1085        if (CField::has(*it))
1086        {
1087           CFieldGroup* root = CFieldGroup::get("field_definition");
1088           CField* averageField = root->createChild();
1089           CField* instantField = root->createChild();
1090           averageField->field_ref = *it;
1091           averageField->hasFieldOut = true;
1092           averageField->fieldOut = instantField;
1093           instantField->freq_op = freq_op;
1094//           averageField-> processEnabledField();
1095           averageField->buildAllExpressionEnabledField();
1096           instantField->SuperClassAttribute::setAttributes(averageField, true);
1097           instantField->field_ref.reset();
1098           instantField->operation.reset();
1099
1100//           instantField-> processEnabledField();
1101           instantField->buildAllExpressionEnabledField();
1102           associatedAverageFieldIds[*it] = instantField;
1103        }
1104        else ERROR("void CField::buildExpression(void)", << " Field " << *it << " does not exist");
1105      }
1106
1107      expression->reduce(this,associatedInstantFieldIds,associatedAverageFieldIds);
1108
1109      slots.resize(instantFieldIds.size() + averageFieldIds.size());
1110      resetSlots();
1111      int slotId = 0;
1112      set<CField*> fields;
1113      expression->getFields(fields);
1114      for (set<CField*>::iterator it = fields.begin(); it != fields.end(); ++it, ++slotId) (*it)->addDependency(this,slotId);
1115      hasExpression = true;
1116    }
1117  }
1118
1119  void CField::resetSlots(void)
1120  {
1121    for (vector<bool>::iterator it = slots.begin(); it != slots.end(); ++it) *it = false;
1122  }
1123
1124  bool CField::slotsFull(void)
1125  {
1126    bool ret = true;
1127    for (vector<bool>::iterator it = slots.begin(); it != slots.end(); ++it) ret &= *it;
1128    return ret;
1129  }
1130
1131  void CField::setSlot(int slotId)
1132  {
1133    CContext* context = CContext::getCurrent();
1134    const CDate& currDate = context->getCalendar()->getCurrentDate();
1135    if (slotUpdateDate == NULL || currDate != *slotUpdateDate)
1136    {
1137      resetSlots();
1138      if (slotUpdateDate == NULL) slotUpdateDate = new CDate(currDate);
1139      else *slotUpdateDate = currDate;
1140    }
1141    slots[slotId] = true;
1142    if (slotsFull())
1143    {
1144      CArray<double,1> expr(expression->compute());
1145
1146      if (hasInstantData)
1147      {
1148        instantData = expr;
1149        for (list< pair<CField *,int> >::iterator it = fieldDependency.begin(); it != fieldDependency.end(); ++it)
1150          if (it->first != this) it->first->setSlot(it->second);
1151      }
1152
1153      if (hasOutputFile) updateDataFromExpression(expr);
1154
1155      const std::vector<CField*>& refField = getAllReference();
1156      for (std::vector<CField*>::const_iterator it = refField.begin(); it != refField.end(); it++)
1157      {
1158        if (!(*it)->hasExpression)
1159          (*it)->setDataFromExpression(expr);
1160      }
1161    }
1162  }
1163
1164   /*!
1165     This function retrieves Id of corresponding domain_ref and axis_ref (if any)
1166   of a field. In some cases, only domain exists but axis doesn't
1167   \return pair of Domain and Axis id
1168   */
1169   const std::pair<StdString,StdString>& CField::getRefDomainAxisIds()
1170   {
1171     CGrid* cgPtr = getRelGrid();
1172     if (NULL != cgPtr)
1173     {
1174       std::vector<StdString>::iterator it;
1175       if (!domain_ref.isEmpty())
1176       {
1177         std::vector<StdString> domainList = cgPtr->getDomainList();
1178         it = std::find(domainList.begin(), domainList.end(), domain_ref.getValue());
1179         if (domainList.end() != it) domAxisIds_.first = *it;
1180       }
1181
1182       if (!axis_ref.isEmpty())
1183       {
1184         std::vector<StdString> axisList = cgPtr->getAxisList();
1185         it = std::find(axisList.begin(), axisList.end(), axis_ref.getValue());
1186         if (axisList.end() != it) domAxisIds_.second = *it;
1187       }
1188     }
1189     return (domAxisIds_);
1190   }
1191
1192   CVariable* CField::addVariable(const string& id)
1193   {
1194     return vVariableGroup->createChild(id);
1195   }
1196
1197   CVariableGroup* CField::addVariableGroup(const string& id)
1198   {
1199     return vVariableGroup->createChildGroup(id);
1200   }
1201
1202   void CField::sendAddAllVariables()
1203   {
1204     if (!getAllVariables().empty())
1205     {
1206       // Firstly, it's necessary to add virtual variable group
1207       sendAddVariableGroup(getVirtualVariableGroup()->getId());
1208
1209       // Okie, now we can add to this variable group
1210       std::vector<CVariable*> allVar = getAllVariables();
1211       std::vector<CVariable*>::const_iterator it = allVar.begin();
1212       std::vector<CVariable*>::const_iterator itE = allVar.end();
1213
1214       for (; it != itE; ++it)
1215       {
1216         this->sendAddVariable((*it)->getId());
1217         (*it)->sendAllAttributesToServer();
1218         (*it)->sendValue();
1219       }
1220     }
1221   }
1222
1223   void CField::sendAddVariable(const string& id)
1224   {
1225    CContext* context = CContext::getCurrent();
1226
1227    if (!context->hasServer)
1228    {
1229       CContextClient* client = context->client;
1230
1231       CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE);
1232       if (client->isServerLeader())
1233       {
1234         CMessage msg;
1235         msg << this->getId();
1236         msg << id;
1237         const std::list<int>& ranks = client->getRanksServerLeader();
1238         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1239           event.push(*itRank,1,msg);
1240         client->sendEvent(event);
1241       }
1242       else client->sendEvent(event);
1243    }
1244   }
1245
1246   void CField::sendAddVariableGroup(const string& id)
1247   {
1248    CContext* context = CContext::getCurrent();
1249    if (!context->hasServer)
1250    {
1251       CContextClient* client = context->client;
1252
1253       CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE_GROUP);
1254       if (client->isServerLeader())
1255       {
1256         CMessage msg;
1257         msg << this->getId();
1258         msg << id;
1259         const std::list<int>& ranks = client->getRanksServerLeader();
1260         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1261           event.push(*itRank,1,msg);
1262         client->sendEvent(event);
1263       }
1264       else client->sendEvent(event);
1265    }
1266   }
1267
1268   void CField::recvAddVariable(CEventServer& event)
1269   {
1270
1271      CBufferIn* buffer = event.subEvents.begin()->buffer;
1272      string id;
1273      *buffer >> id;
1274      get(id)->recvAddVariable(*buffer);
1275   }
1276
1277   void CField::recvAddVariable(CBufferIn& buffer)
1278   {
1279      string id;
1280      buffer >> id;
1281      addVariable(id);
1282   }
1283
1284   void CField::recvAddVariableGroup(CEventServer& event)
1285   {
1286
1287      CBufferIn* buffer = event.subEvents.begin()->buffer;
1288      string id;
1289      *buffer >> id;
1290      get(id)->recvAddVariableGroup(*buffer);
1291   }
1292
1293   void CField::recvAddVariableGroup(CBufferIn& buffer)
1294   {
1295      string id;
1296      buffer >> id;
1297      addVariableGroup(id);
1298   }
1299
1300   DEFINE_REF_FUNC(Field,field)
1301
1302//  void CField::addReference(CField* field)
1303//  {
1304//    refObject.push_back(field);
1305//  }
1306//
1307//   //----------------------------------------------------------------
1308//
1309//   bool CField::hasDirectFieldReference(void) const
1310//   {
1311//     return !this->field_ref.isEmpty();
1312//   }
1313//
1314//   //----------------------------------------------------------------
1315//
1316//   const StdString& CField::getBaseFieldId(void) const
1317//   {
1318//      return this->getBaseFieldReference()->getId();
1319//   }
1320//
1321//   //----------------------------------------------------------------
1322//
1323//   /*!
1324//   \brief Get pointer to direct field to which the current field refers.
1325//   */
1326//   CField* CField::getDirectFieldReference(void) const
1327//   {
1328//      if (this->field_ref.isEmpty())
1329//         return this->getBaseFieldReference();
1330//
1331//      if (!CField::has(this->field_ref.getValue()))
1332//         ERROR("CField::getDirectFieldReference(void)",
1333//               << "[ ref_name = " << this->field_ref.getValue() << "]"
1334//               << " invalid field name !");
1335//
1336//      return CField::get(this->field_ref.getValue());
1337//   }
1338//
1339//   //----------------------------------------------------------------
1340//
1341//   CField* CField::getBaseFieldReference(void) const
1342//   {
1343//      return baseRefObject;
1344//   }
1345//
1346//   //----------------------------------------------------------------
1347//
1348//   const std::vector<CField*>& CField::getAllReference(void) const
1349//   {
1350//      return refObject;
1351//   }
1352//
1353//   /*!
1354//   \brief Searching for all reference of a field
1355//   If a field refers to (an)other field(s), we will search for all its referenced parents.
1356//   Moreover, if any father, direct or indirect (e.g: two levels up), has non-empty attributes,
1357//   all its attributes will be added to the current field
1358//   \param [in] apply Flag to specify whether current field uses attributes of its father
1359//               in case the attribute is empty (true) or its attributes are replaced by ones of its father (false)
1360//   */
1361//   void CField::solveRefInheritance(bool apply)
1362//   {
1363//      std::set<CField *> sset;
1364//      CField* refer_sptr;
1365//      CField* refer_ptr = this;
1366//
1367//      while (refer_ptr->hasDirectFieldReference())
1368//      {
1369//         refer_sptr = refer_ptr->getDirectFieldReference();
1370//         refer_ptr  = refer_sptr;
1371//
1372//         if(sset.end() != sset.find(refer_ptr))
1373//         {
1374//            DEBUG (<< "Circular dependency stopped for field object on "
1375//                   << "\"" + refer_ptr->getId() + "\" !");
1376//            break;
1377//         }
1378//
1379//         SuperClassAttribute::setAttributes(refer_ptr, apply);
1380//         sset.insert(refer_ptr);
1381//      }
1382//   }
1383//
1384//   /*!
1385//   \brief Only on SERVER side. Remove all field_ref from current field
1386//   On creating a new field on server side, redundant "field_ref" is still kept in the attribute list
1387//   of the current field. This function removes this from current field
1388//   */
1389//   void CField::removeRefInheritance()
1390//   {
1391//     if (this->field_ref.isEmpty()) return;
1392//     this->clearAttribute("field_ref");
1393//   }
1394//
1395//   void CField::solveBaseReference(void)
1396//   {
1397//      std::set<CField *> sset;
1398//      CField* refer_sptr;
1399//      CField* refer_ptr = this;
1400//
1401//      if (this->hasDirectFieldReference())  baseRefObject = getDirectFieldReference();
1402//      else  baseRefObject = CField::get(this);
1403//
1404//      while (refer_ptr->hasDirectFieldReference())
1405//      {
1406//         refer_sptr = refer_ptr->getDirectFieldReference();
1407//         refer_ptr  = refer_sptr;
1408//
1409//         if(sset.end() != sset.find(refer_ptr))
1410//         {
1411//            DEBUG (<< "Circular dependency stopped for field object on "
1412//                   << "\"" + refer_ptr->getId() + "\" !");
1413//            break;
1414//         }
1415//
1416//         sset.insert(refer_ptr);
1417//      }
1418//
1419//      if (hasDirectFieldReference()) baseRefObject->addReference(this);
1420//   }
1421} // namespace xios
Note: See TracBrowser for help on using the repository browser.