Salome HOME
Merge from V6_main 11/02/2013
[modules/med.git] / src / MEDCoupling / MEDCouplingDefinitionTime.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingDefinitionTime.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
23
24 #include <cmath>
25
26 using namespace ParaMEDMEM;
27
28 const double MEDCouplingDefinitionTime::EPS_DFT=1e-15;
29
30 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(const MEDCouplingFieldDouble *f, int meshId, const std::vector<int>& arrId, int fieldId) throw(INTERP_KERNEL::Exception)
31 {
32   static const char msg[]="TimeSlice::New : mismatch of arrays number of a fieldDouble and its policy !!! Internal error !!!";
33   if(!f)
34     throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : empty field !");
35   switch(f->getTimeDiscretization())
36     {
37     case ONE_TIME:
38       {
39         if(arrId.size()!=1)
40           throw INTERP_KERNEL::Exception(msg);
41         return new MEDCouplingDefinitionTimeSliceInst(f,meshId,arrId[0],fieldId);
42       }
43     case CONST_ON_TIME_INTERVAL:
44       {
45         if(arrId.size()!=1)
46           throw INTERP_KERNEL::Exception(msg);
47         return new MEDCouplingDefinitionTimeSliceCstOnTI(f,meshId,arrId[0],fieldId);
48       }
49     case LINEAR_TIME:
50       {
51         if(arrId.size()!=2)
52           throw INTERP_KERNEL::Exception(msg);
53         return new MEDCouplingDefinitionTimeSliceLT(f,meshId,arrId[0],arrId[1],fieldId);
54       }
55     case NO_TIME:
56       throw INTERP_KERNEL::Exception("Invalide time discretization ! NO_TIME ! Impossible to build a definition time slice !");
57     default:
58       throw INTERP_KERNEL::Exception("Invalide time discretization : Not recognized !");
59     }
60 }
61
62 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(TypeOfTimeDiscretization type, const std::vector<int>& tiI, const std::vector<double>& tiD) throw(INTERP_KERNEL::Exception)
63 {
64   switch(type)
65     {
66     case ONE_TIME:
67       return MEDCouplingDefinitionTimeSliceInst::New(tiI,tiD);
68     case CONST_ON_TIME_INTERVAL:
69       return MEDCouplingDefinitionTimeSliceCstOnTI::New(tiI,tiD);
70     case LINEAR_TIME:
71       return MEDCouplingDefinitionTimeSliceLT::New(tiI,tiD);
72     default:
73       throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : unrecognized time discretization type !");
74     }
75 }
76
77 bool MEDCouplingDefinitionTimeSlice::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
78 {
79   if(_mesh_id!=other._mesh_id)
80     return false;
81   if(_array_id!=other._array_id)
82     return false;
83   if(_field_id!=other._field_id)
84     return false;
85   return true;
86 }
87
88 int MEDCouplingDefinitionTimeSlice::getStartId() const
89 {
90   return _array_id;
91 }
92
93 int MEDCouplingDefinitionTimeSlice::getEndId() const
94 {
95   return _array_id;
96 }
97
98 void MEDCouplingDefinitionTimeSlice::appendRepr(std::ostream& stream) const
99 {
100   stream << " *** MeshId : " << _mesh_id << " ArrayId : " << _array_id;
101 }
102
103 MEDCouplingDefinitionTimeSlice::MEDCouplingDefinitionTimeSlice(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId) throw(INTERP_KERNEL::Exception):_mesh_id(meshId),_array_id(arrId),_field_id(fieldId)
104 {
105   int tmp1,tmp2;
106   double t1=f->getStartTime(tmp1,tmp2);
107   double t2=f->getEndTime(tmp1,tmp2);
108   if(t2<t1)
109     throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice : End time strictly before Start time ...");
110 }
111
112 std::size_t MEDCouplingDefinitionTimeSlice::getHeapMemorySize() const
113 {
114   return 0;
115 }
116
117 bool MEDCouplingDefinitionTimeSlice::isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
118 {
119   double t1=getStartTime();
120   double t2=getEndTime();
121   double o1=other->getStartTime();
122   double o2=other->getEndTime();
123   return o1>t1-eps && o2<t2+eps;
124 }
125
126 bool MEDCouplingDefinitionTimeSlice::isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
127 {
128   double t1=getStartTime();
129   double t2=getEndTime();
130   double o1=other->getStartTime();
131   double o2=other->getEndTime();
132   return (o1<t1+eps && o2<t1+eps) || (o1>t2-eps && o2>t2-eps);
133 }
134
135 bool MEDCouplingDefinitionTimeSlice::isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
136 {
137   double t2=getEndTime();
138   double o1=other->getStartTime();
139   double o2=other->getEndTime();
140   return (o1>t2-eps && o2>t2-eps);
141 }
142
143 bool MEDCouplingDefinitionTimeSlice::isBeforeMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
144 {
145   double t1=getStartTime();
146   double o1=other->getStartTime();
147   double o2=other->getEndTime();
148   return (o1<t1+eps && o2<t1+eps);
149 }
150
151 MEDCouplingDefinitionTimeSliceInst *MEDCouplingDefinitionTimeSliceInst::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
152 {
153   MEDCouplingDefinitionTimeSliceInst *ret=new MEDCouplingDefinitionTimeSliceInst;
154   ret->unserialize(tiI,tiD);
155   return ret;
156 }
157
158 void MEDCouplingDefinitionTimeSliceInst::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
159 {
160   tiI.resize(3);
161   tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id;
162   tiD.resize(1);
163   tiD[0]=_instant;
164 }
165
166 void MEDCouplingDefinitionTimeSliceInst::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
167 {
168   _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2];
169   _instant=tiD[0];
170 }
171
172 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceInst::getTimeType() const
173 {
174   return ONE_TIME;
175 }
176
177 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceInst::copy() const
178 {
179   return new MEDCouplingDefinitionTimeSliceInst(*this);
180 }
181
182 bool MEDCouplingDefinitionTimeSliceInst::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
183 {
184   if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
185     return false;
186   const MEDCouplingDefinitionTimeSliceInst *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceInst *>(&other);
187   if(!otherC)
188     return false;
189   return fabs(otherC->_instant-_instant)<eps;
190 }
191
192 void MEDCouplingDefinitionTimeSliceInst::getHotSpotsTime(std::vector<double>& ret) const
193 {
194   ret.resize(1);
195   ret[0]=_instant;
196 }
197
198 void MEDCouplingDefinitionTimeSliceInst::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
199 {
200   meshId=_mesh_id;
201   arrId=_array_id;
202   arrIdInField=0;
203   fieldId=_field_id;
204 }
205
206 bool MEDCouplingDefinitionTimeSliceInst::isContaining(double tmp, double eps) const
207 {
208   return fabs(tmp-_instant)<eps;
209 }
210
211 void MEDCouplingDefinitionTimeSliceInst::appendRepr(std::ostream& stream) const
212 {
213   stream << "single point " << _instant;
214   MEDCouplingDefinitionTimeSlice::appendRepr(stream);
215 }
216
217 double MEDCouplingDefinitionTimeSliceInst::getStartTime() const
218 {
219   return _instant;
220 }
221
222 double MEDCouplingDefinitionTimeSliceInst::getEndTime() const
223 {
224   return _instant;
225 }
226
227 MEDCouplingDefinitionTimeSliceInst::MEDCouplingDefinitionTimeSliceInst(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId) throw(INTERP_KERNEL::Exception):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId)
228 {
229   int tmp1,tmp2;
230   double t1=f->getStartTime(tmp1,tmp2);
231   double t2=f->getEndTime(tmp1,tmp2);
232   double eps=f->getTimeTolerance();
233   if(fabs(t1-t2)>eps)
234     throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSliceInst : times differs in this");
235   _instant=t1;
236 }
237
238 MEDCouplingDefinitionTimeSliceCstOnTI *MEDCouplingDefinitionTimeSliceCstOnTI::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
239 {
240   MEDCouplingDefinitionTimeSliceCstOnTI *ret=new MEDCouplingDefinitionTimeSliceCstOnTI;
241   ret->unserialize(tiI,tiD);
242   return ret;
243 }
244
245 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceCstOnTI::copy() const
246 {
247   return new MEDCouplingDefinitionTimeSliceCstOnTI(*this);
248 }
249
250 bool MEDCouplingDefinitionTimeSliceCstOnTI::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
251 {
252   if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
253     return false;
254   const MEDCouplingDefinitionTimeSliceCstOnTI *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceCstOnTI *>(&other);
255   if(!otherC)
256     return false;
257   if(fabs(otherC->_start-_start)>eps)
258     return false;
259   return fabs(otherC->_end-_end)<eps;
260 }
261
262 void MEDCouplingDefinitionTimeSliceCstOnTI::getHotSpotsTime(std::vector<double>& ret) const
263 {
264   ret.resize(1);
265   ret[0]=(_start+_end)/2.;
266 }
267
268 void MEDCouplingDefinitionTimeSliceCstOnTI::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
269 {
270   meshId=_mesh_id;
271   arrId=_array_id;
272   arrIdInField=0;
273   fieldId=_field_id;
274 }
275
276 bool MEDCouplingDefinitionTimeSliceCstOnTI::isContaining(double tmp, double eps) const
277 {
278   return _start-eps<tmp && _end+eps>tmp;
279 }
280
281 void MEDCouplingDefinitionTimeSliceCstOnTI::appendRepr(std::ostream& stream) const
282 {
283   stream << "Constant on time interval [" << _start << "," << _end << "]";
284   MEDCouplingDefinitionTimeSlice::appendRepr(stream);
285 }
286
287 double MEDCouplingDefinitionTimeSliceCstOnTI::getStartTime() const
288 {
289   return _start;
290 }
291
292 double MEDCouplingDefinitionTimeSliceCstOnTI::getEndTime() const
293 {
294   return _end;
295 }
296
297 void MEDCouplingDefinitionTimeSliceCstOnTI::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
298 {
299   tiI.resize(3);
300   tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id;
301   tiD.resize(2);
302   tiD[0]=_start; tiD[1]=_end;
303 }
304
305 void MEDCouplingDefinitionTimeSliceCstOnTI::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
306 {
307   _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2];
308   _start=tiD[0]; _end=tiD[1];
309 }
310
311 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceCstOnTI::getTimeType() const
312 {
313   return CONST_ON_TIME_INTERVAL;
314 }
315
316 MEDCouplingDefinitionTimeSliceCstOnTI::MEDCouplingDefinitionTimeSliceCstOnTI(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId) throw(INTERP_KERNEL::Exception):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId)
317 {
318   int tmp1,tmp2;
319   double t1=f->getStartTime(tmp1,tmp2);
320   double t2=f->getEndTime(tmp1,tmp2);
321   _start=t1;
322   _end=t2;
323 }
324
325 MEDCouplingDefinitionTimeSliceLT *MEDCouplingDefinitionTimeSliceLT::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
326 {
327   MEDCouplingDefinitionTimeSliceLT *ret=new MEDCouplingDefinitionTimeSliceLT;
328   ret->unserialize(tiI,tiD);
329   return ret;
330 }
331
332 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceLT::copy() const
333 {
334   return new MEDCouplingDefinitionTimeSliceLT(*this);
335 }
336
337 bool MEDCouplingDefinitionTimeSliceLT::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
338 {
339   if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
340     return false;
341   const MEDCouplingDefinitionTimeSliceLT *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceLT *>(&other);
342   if(!otherC)
343     return false;
344   if(_array_id_end!=otherC->_array_id_end)
345     return false;
346   if(fabs(otherC->_start-_start)>eps)
347     return false;
348   return fabs(otherC->_end-_end)<eps;
349 }
350
351 void MEDCouplingDefinitionTimeSliceLT::getHotSpotsTime(std::vector<double>& ret) const
352 {
353   ret.resize(2);
354   ret[0]=_start;
355   ret[1]=_end;
356 }
357
358 void MEDCouplingDefinitionTimeSliceLT::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
359 {
360   if(fabs(tm-_start)<eps)
361     {
362       meshId=_mesh_id;
363       arrId=_array_id;
364       arrIdInField=0;
365       fieldId=_field_id;
366       return ;
367     }
368   if(fabs(tm-_end)<eps)
369     {
370       meshId=_mesh_id;
371       arrId=_array_id_end;
372       arrIdInField=1;
373       fieldId=_field_id;
374       return ;
375     }
376   throw INTERP_KERNEL::Exception("LinearTime request not in boundary of this ! use hot spots !");
377 }
378
379 bool MEDCouplingDefinitionTimeSliceLT::isContaining(double tmp, double eps) const
380 {
381   return _start-eps<tmp && _end+eps>tmp;
382 }
383
384 void MEDCouplingDefinitionTimeSliceLT::appendRepr(std::ostream& stream) const
385 {
386   stream << "Linear on time interval [" << _start << "," << _end << "]";
387   MEDCouplingDefinitionTimeSlice::appendRepr(stream);
388   stream << " EndArrayId : " << _array_id_end;
389 }
390
391 double MEDCouplingDefinitionTimeSliceLT::getStartTime() const
392 {
393   return _start;
394 }
395
396 double MEDCouplingDefinitionTimeSliceLT::getEndTime() const
397 {
398   return _end;
399 }
400
401 int MEDCouplingDefinitionTimeSliceLT::getEndId() const
402 {
403   return _array_id_end;
404 }
405
406 void MEDCouplingDefinitionTimeSliceLT::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
407 {
408   tiI.resize(4);
409   tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; tiI[3]=_array_id_end;
410   tiD.resize(2);
411   tiD[0]=_start; tiD[1]=_end;
412 }
413
414 void MEDCouplingDefinitionTimeSliceLT::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
415 {
416   _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; _array_id_end=tiI[3];
417   _start=tiD[0]; _end=tiD[1];
418 }
419
420 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceLT::getTimeType() const
421 {
422   return LINEAR_TIME;
423 }
424
425 MEDCouplingDefinitionTimeSliceLT::MEDCouplingDefinitionTimeSliceLT(const MEDCouplingFieldDouble *f, int meshId, int arrId, int arr2Id, int fieldId) throw(INTERP_KERNEL::Exception):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId),_array_id_end(arr2Id)
426 {
427   int tmp1,tmp2;
428   double t1=f->getStartTime(tmp1,tmp2);
429   double t2=f->getEndTime(tmp1,tmp2);
430   _start=t1;
431   _end=t2;
432 }
433
434 MEDCouplingDefinitionTime::MEDCouplingDefinitionTime():_eps(EPS_DFT)
435 {
436 }
437
438 MEDCouplingDefinitionTime::MEDCouplingDefinitionTime(const std::vector<const MEDCouplingFieldDouble *>& fs, const std::vector<int>& meshRefs, const std::vector<std::vector<int> >& arrRefs) throw(INTERP_KERNEL::Exception)
439 {
440   std::size_t sz=fs.size();
441   if(sz!=arrRefs.size())
442     throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : internal error ! should never happen !");
443   _slices.resize(sz);
444   for(std::size_t i=0;i<sz;i++)
445     {
446       if(arrRefs.empty())
447         throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : A field is null in list impossible to build a time definition !");
448       _slices[i]=MEDCouplingDefinitionTimeSlice::New(fs[i],meshRefs[i],arrRefs[i],(int)i);
449     }
450   if(sz<=1)
451     return ;
452   const MEDCouplingDefinitionTimeSlice *ref=_slices[0];
453   _eps=fs[0]->getTimeTolerance();
454   for(std::size_t i=1;i<sz;i++)
455     {
456       if(!ref->isAfterMe(_slices[i],_eps))
457         throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructors : the sequences of fields does NOT defines a stricly ascendant monotonic time sequence !");
458       // double t1=ref->getEndTime();
459       // double t2=_slices[i]->getStartTime();
460       // if(fabs(t1-t2)<_eps)
461       //   if(ref->getEndId() != _slices[i]->getStartId())
462       //     throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : 2 slices refers to the same time and underlying arrays differs !");
463       ref=_slices[i];
464     }
465 }
466
467 std::size_t MEDCouplingDefinitionTime::getHeapMemorySize() const
468 {
469   return _slices.capacity()*(sizeof(MEDCouplingDefinitionTimeSlice)+sizeof(int));
470 }
471
472 void MEDCouplingDefinitionTime::assign(const MEDCouplingDefinitionTime& other)
473 {
474   std::size_t sz=other._slices.size();
475   _slices.resize(sz);
476   for(std::size_t i=0;i<sz;i++)
477     _slices[i]=other._slices[i]->copy();
478 }
479
480 bool MEDCouplingDefinitionTime::isEqual(const MEDCouplingDefinitionTime& other) const
481 {
482   std::size_t sz=_slices.size();
483   if(sz!=other._slices.size())
484     return false;
485   for(std::size_t i=0;i<sz;i++)
486     if(!_slices[i]->isEqual(*other._slices[i],_eps))
487       return false;
488   return true;
489 }
490
491 void MEDCouplingDefinitionTime::getIdsOnTimeRight(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
492 {
493   std::vector<int> meshIds;
494   std::vector<int> arrIds;
495   std::vector<int> arrIdsInField;
496   std::vector<int> fieldIds;
497   getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds);
498   meshId=meshIds.back();
499   arrId=arrIds.back();
500   arrIdInField=arrIdsInField.back();
501   fieldId=fieldIds.back();
502 }
503
504 void MEDCouplingDefinitionTime::getIdsOnTimeLeft(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
505 {
506   std::vector<int> meshIds;
507   std::vector<int> arrIds;
508   std::vector<int> arrIdsInField;
509   std::vector<int> fieldIds;
510   getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds);
511   meshId=meshIds.front();
512   arrId=arrIds.front();
513   arrIdInField=arrIdsInField.front();
514   fieldId=fieldIds.front();
515 }
516
517 void MEDCouplingDefinitionTime::getIdsOnTime(double tm, std::vector<int>& meshIds, std::vector<int>& arrIds, std::vector<int>& arrIdsInField, std::vector<int>& fieldIds) const throw(INTERP_KERNEL::Exception)
518 {
519   std::vector<int> ids;
520   int id=0;
521   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++,id++)
522     if((*it)->isContaining(tm,_eps))
523       ids.push_back(id);
524   if(ids.empty())
525     throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : No matching slice for such time !");
526   std::size_t sz=ids.size();
527   if(sz>2)
528     throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : Too many slices match this time !");
529   //
530   meshIds.resize(sz);
531   arrIds.resize(sz);
532   arrIdsInField.resize(sz);
533   fieldIds.resize(sz);
534   for(std::size_t i=0;i<sz;i++)
535     _slices[ids[i]]->getIdsOnTime(tm,_eps,meshIds[i],arrIds[i],arrIdsInField[i],fieldIds[i]);
536 }
537
538 std::vector<double> MEDCouplingDefinitionTime::getHotSpotsTime() const
539 {
540   std::vector<double> ret;
541   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++)
542     {
543       std::vector<double> tmp;
544       (*it)->getHotSpotsTime(tmp);
545       if(!ret.empty())
546         {
547           if(fabs(ret.back()-tmp.front())>_eps)
548             ret.insert(ret.end(),tmp.begin(),tmp.end());
549           else
550             ret.insert(ret.end(),tmp.begin()+1,tmp.end());
551         }
552       else
553         ret.insert(ret.end(),tmp.begin(),tmp.end());
554     }
555   return ret;
556 }
557
558 void MEDCouplingDefinitionTime::appendRepr(std::ostream& stream) const
559 {
560   stream << "Time definition :\n";
561   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++)
562     {
563       stream << " - ";
564       (*it)->appendRepr(stream);
565       stream << std::endl;
566     }
567 }
568
569 void MEDCouplingDefinitionTime::getTinySerializationInformation(std::vector<int>& tinyInfoI, std::vector<double>& tinyInfoD) const
570 {
571   int sz=(int)_slices.size();
572   tinyInfoD.resize(1);
573   tinyInfoD[0]=_eps;
574   tinyInfoI.resize(3*sz+2);
575   tinyInfoI[0]=sz;
576   std::vector<int> coreData;
577   for(int i=0;i<sz;i++)
578     {
579       std::vector<int> tmp1;
580       std::vector<double> tmp2;
581       tinyInfoI[i+2]=(int)_slices[i]->getTimeType();
582       _slices[i]->getTinySerializationInformation(tmp1,tmp2);
583       tinyInfoI[i+sz+2]=(int)tmp1.size();
584       tinyInfoI[i+2*sz+2]=(int)tmp2.size();
585       coreData.insert(coreData.end(),tmp1.begin(),tmp1.end());
586       tinyInfoD.insert(tinyInfoD.end(),tmp2.begin(),tmp2.end());
587     }
588   tinyInfoI[1]=(int)coreData.size();
589   tinyInfoI.insert(tinyInfoI.end(),coreData.begin(),coreData.end());
590 }
591
592 void MEDCouplingDefinitionTime::unserialize(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD)
593 {
594   int sz=tinyInfoI[0];
595   _slices.resize(sz);
596   _eps=tinyInfoD[0];
597   int offset1=0;
598   int offset2=1;
599   for(int i=0;i<sz;i++)
600     {
601       TypeOfTimeDiscretization ty=(TypeOfTimeDiscretization) tinyInfoI[i+2];  
602       int sz1=tinyInfoI[i+sz+2];
603       int sz2=tinyInfoI[i+2*sz+2];
604       std::vector<int> tmp1(tinyInfoI.begin()+3*sz+2+offset1,tinyInfoI.begin()+3*sz+2+offset1+sz1);
605       std::vector<double> tmp2(tinyInfoD.begin()+offset2,tinyInfoD.begin()+offset2+sz2);
606       MEDCouplingDefinitionTimeSlice *pt=MEDCouplingDefinitionTimeSlice::New(ty,tmp1,tmp2);
607       _slices[i]=pt;
608       offset1+=sz1;
609       offset2+=sz2;
610     }
611 }
612