1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "MEDCouplingDefinitionTime.hxx"
21 #include "MEDCouplingFieldDouble.hxx"
25 using namespace ParaMEDMEM;
27 const double MEDCouplingDefinitionTime::EPS_DFT=1e-15;
29 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(const MEDCouplingFieldDouble *f, int meshId, const std::vector<int>& arrId, int fieldId) throw(INTERP_KERNEL::Exception)
31 static const char msg[]="TimeSlice::New : mismatch of arrays number of a fieldDouble and its policy !!! Internal error !!!";
33 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : empty field !");
34 switch(f->getTimeDiscretization())
39 throw INTERP_KERNEL::Exception(msg);
40 return new MEDCouplingDefinitionTimeSliceInst(f,meshId,arrId[0],fieldId);
42 case CONST_ON_TIME_INTERVAL:
45 throw INTERP_KERNEL::Exception(msg);
46 return new MEDCouplingDefinitionTimeSliceCstOnTI(f,meshId,arrId[0],fieldId);
51 throw INTERP_KERNEL::Exception(msg);
52 return new MEDCouplingDefinitionTimeSliceLT(f,meshId,arrId[0],arrId[1],fieldId);
55 throw INTERP_KERNEL::Exception("Invalide time discretization ! NO_TIME ! Impossible to build a definition time slice !");
57 throw INTERP_KERNEL::Exception("Invalide time discretization : Not recognized !");
61 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(TypeOfTimeDiscretization type, const std::vector<int>& tiI, const std::vector<double>& tiD) throw(INTERP_KERNEL::Exception)
66 return MEDCouplingDefinitionTimeSliceInst::New(tiI,tiD);
67 case CONST_ON_TIME_INTERVAL:
68 return MEDCouplingDefinitionTimeSliceCstOnTI::New(tiI,tiD);
70 return MEDCouplingDefinitionTimeSliceLT::New(tiI,tiD);
72 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : unrecognized time discretization type !");
76 bool MEDCouplingDefinitionTimeSlice::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
78 if(_mesh_id!=other._mesh_id)
80 if(_array_id!=other._array_id)
82 if(_field_id!=other._field_id)
87 int MEDCouplingDefinitionTimeSlice::getStartId() const
92 int MEDCouplingDefinitionTimeSlice::getEndId() const
97 void MEDCouplingDefinitionTimeSlice::appendRepr(std::ostream& stream) const
99 stream << " *** MeshId : " << _mesh_id << " ArrayId : " << _array_id;
102 MEDCouplingDefinitionTimeSlice::MEDCouplingDefinitionTimeSlice(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId) throw(INTERP_KERNEL::Exception):_mesh_id(meshId),_array_id(arrId),_field_id(fieldId)
105 double t1=f->getStartTime(tmp1,tmp2);
106 double t2=f->getEndTime(tmp1,tmp2);
108 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice : End time strictly before Start time ...");
111 bool MEDCouplingDefinitionTimeSlice::isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
113 double t1=getStartTime();
114 double t2=getEndTime();
115 double o1=other->getStartTime();
116 double o2=other->getEndTime();
117 return o1>t1-eps && o2<t2+eps;
120 bool MEDCouplingDefinitionTimeSlice::isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
122 double t1=getStartTime();
123 double t2=getEndTime();
124 double o1=other->getStartTime();
125 double o2=other->getEndTime();
126 return (o1<t1+eps && o2<t1+eps) || (o1>t2-eps && o2>t2-eps);
129 bool MEDCouplingDefinitionTimeSlice::isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
131 double t2=getEndTime();
132 double o1=other->getStartTime();
133 double o2=other->getEndTime();
134 return (o1>t2-eps && o2>t2-eps);
137 bool MEDCouplingDefinitionTimeSlice::isBeforeMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
139 double t1=getStartTime();
140 double o1=other->getStartTime();
141 double o2=other->getEndTime();
142 return (o1<t1+eps && o2<t1+eps);
145 MEDCouplingDefinitionTimeSliceInst *MEDCouplingDefinitionTimeSliceInst::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
147 MEDCouplingDefinitionTimeSliceInst *ret=new MEDCouplingDefinitionTimeSliceInst;
148 ret->unserialize(tiI,tiD);
152 void MEDCouplingDefinitionTimeSliceInst::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
155 tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id;
160 void MEDCouplingDefinitionTimeSliceInst::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
162 _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2];
166 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceInst::getTimeType() const
171 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceInst::copy() const
173 return new MEDCouplingDefinitionTimeSliceInst(*this);
176 bool MEDCouplingDefinitionTimeSliceInst::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
178 if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
180 const MEDCouplingDefinitionTimeSliceInst *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceInst *>(&other);
183 return fabs(otherC->_instant-_instant)<eps;
186 void MEDCouplingDefinitionTimeSliceInst::getHotSpotsTime(std::vector<double>& ret) const
192 void MEDCouplingDefinitionTimeSliceInst::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
200 bool MEDCouplingDefinitionTimeSliceInst::isContaining(double tmp, double eps) const
202 return fabs(tmp-_instant)<eps;
205 void MEDCouplingDefinitionTimeSliceInst::appendRepr(std::ostream& stream) const
207 stream << "single point " << _instant;
208 MEDCouplingDefinitionTimeSlice::appendRepr(stream);
211 double MEDCouplingDefinitionTimeSliceInst::getStartTime() const
216 double MEDCouplingDefinitionTimeSliceInst::getEndTime() const
221 MEDCouplingDefinitionTimeSliceInst::MEDCouplingDefinitionTimeSliceInst(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId) throw(INTERP_KERNEL::Exception):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId)
224 double t1=f->getStartTime(tmp1,tmp2);
225 double t2=f->getEndTime(tmp1,tmp2);
226 double eps=f->getTimeTolerance();
228 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSliceInst : times differs in this");
232 MEDCouplingDefinitionTimeSliceCstOnTI *MEDCouplingDefinitionTimeSliceCstOnTI::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
234 MEDCouplingDefinitionTimeSliceCstOnTI *ret=new MEDCouplingDefinitionTimeSliceCstOnTI;
235 ret->unserialize(tiI,tiD);
239 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceCstOnTI::copy() const
241 return new MEDCouplingDefinitionTimeSliceCstOnTI(*this);
244 bool MEDCouplingDefinitionTimeSliceCstOnTI::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
246 if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
248 const MEDCouplingDefinitionTimeSliceCstOnTI *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceCstOnTI *>(&other);
251 if(fabs(otherC->_start-_start)>eps)
253 return fabs(otherC->_end-_end)<eps;
256 void MEDCouplingDefinitionTimeSliceCstOnTI::getHotSpotsTime(std::vector<double>& ret) const
259 ret[0]=(_start+_end)/2.;
262 void MEDCouplingDefinitionTimeSliceCstOnTI::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
270 bool MEDCouplingDefinitionTimeSliceCstOnTI::isContaining(double tmp, double eps) const
272 return _start-eps<tmp && _end+eps>tmp;
275 void MEDCouplingDefinitionTimeSliceCstOnTI::appendRepr(std::ostream& stream) const
277 stream << "Constant on time interval [" << _start << "," << _end << "]";
278 MEDCouplingDefinitionTimeSlice::appendRepr(stream);
281 double MEDCouplingDefinitionTimeSliceCstOnTI::getStartTime() const
286 double MEDCouplingDefinitionTimeSliceCstOnTI::getEndTime() const
291 void MEDCouplingDefinitionTimeSliceCstOnTI::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
294 tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id;
296 tiD[0]=_start; tiD[1]=_end;
299 void MEDCouplingDefinitionTimeSliceCstOnTI::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
301 _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2];
302 _start=tiD[0]; _end=tiD[1];
305 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceCstOnTI::getTimeType() const
307 return CONST_ON_TIME_INTERVAL;
310 MEDCouplingDefinitionTimeSliceCstOnTI::MEDCouplingDefinitionTimeSliceCstOnTI(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId) throw(INTERP_KERNEL::Exception):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId)
313 double t1=f->getStartTime(tmp1,tmp2);
314 double t2=f->getEndTime(tmp1,tmp2);
319 MEDCouplingDefinitionTimeSliceLT *MEDCouplingDefinitionTimeSliceLT::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
321 MEDCouplingDefinitionTimeSliceLT *ret=new MEDCouplingDefinitionTimeSliceLT;
322 ret->unserialize(tiI,tiD);
326 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceLT::copy() const
328 return new MEDCouplingDefinitionTimeSliceLT(*this);
331 bool MEDCouplingDefinitionTimeSliceLT::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
333 if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
335 const MEDCouplingDefinitionTimeSliceLT *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceLT *>(&other);
338 if(_array_id_end!=otherC->_array_id_end)
340 if(fabs(otherC->_start-_start)>eps)
342 return fabs(otherC->_end-_end)<eps;
345 void MEDCouplingDefinitionTimeSliceLT::getHotSpotsTime(std::vector<double>& ret) const
352 void MEDCouplingDefinitionTimeSliceLT::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
354 if(fabs(tm-_start)<eps)
362 if(fabs(tm-_end)<eps)
370 throw INTERP_KERNEL::Exception("LinearTime request not in boundary of this ! use hot spots !");
373 bool MEDCouplingDefinitionTimeSliceLT::isContaining(double tmp, double eps) const
375 return _start-eps<tmp && _end+eps>tmp;
378 void MEDCouplingDefinitionTimeSliceLT::appendRepr(std::ostream& stream) const
380 stream << "Linear on time interval [" << _start << "," << _end << "]";
381 MEDCouplingDefinitionTimeSlice::appendRepr(stream);
382 stream << " EndArrayId : " << _array_id_end;
385 double MEDCouplingDefinitionTimeSliceLT::getStartTime() const
390 double MEDCouplingDefinitionTimeSliceLT::getEndTime() const
395 int MEDCouplingDefinitionTimeSliceLT::getEndId() const
397 return _array_id_end;
400 void MEDCouplingDefinitionTimeSliceLT::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
403 tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; tiI[3]=_array_id_end;
405 tiD[0]=_start; tiD[1]=_end;
408 void MEDCouplingDefinitionTimeSliceLT::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
410 _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; _array_id_end=tiI[3];
411 _start=tiD[0]; _end=tiD[1];
414 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceLT::getTimeType() const
419 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)
422 double t1=f->getStartTime(tmp1,tmp2);
423 double t2=f->getEndTime(tmp1,tmp2);
428 MEDCouplingDefinitionTime::MEDCouplingDefinitionTime():_eps(EPS_DFT)
432 MEDCouplingDefinitionTime::MEDCouplingDefinitionTime(const std::vector<const MEDCouplingFieldDouble *>& fs, const std::vector<int>& meshRefs, const std::vector<std::vector<int> >& arrRefs) throw(INTERP_KERNEL::Exception)
434 std::size_t sz=fs.size();
435 if(sz!=arrRefs.size())
436 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : internal error ! should never happen !");
438 for(std::size_t i=0;i<sz;i++)
441 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : A field is null in list impossible to build a time definition !");
442 _slices[i]=MEDCouplingDefinitionTimeSlice::New(fs[i],meshRefs[i],arrRefs[i],(int)i);
446 const MEDCouplingDefinitionTimeSlice *ref=_slices[0];
447 _eps=fs[0]->getTimeTolerance();
448 for(std::size_t i=1;i<sz;i++)
450 if(!ref->isAfterMe(_slices[i],_eps))
451 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructors : the sequences of fields does NOT defines a stricly ascendant monotonic time sequence !");
452 // double t1=ref->getEndTime();
453 // double t2=_slices[i]->getStartTime();
454 // if(fabs(t1-t2)<_eps)
455 // if(ref->getEndId() != _slices[i]->getStartId())
456 // throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : 2 slices refers to the same time and underlying arrays differs !");
461 void MEDCouplingDefinitionTime::assign(const MEDCouplingDefinitionTime& other)
463 std::size_t sz=other._slices.size();
465 for(std::size_t i=0;i<sz;i++)
466 _slices[i]=other._slices[i]->copy();
469 bool MEDCouplingDefinitionTime::isEqual(const MEDCouplingDefinitionTime& other) const
471 std::size_t sz=_slices.size();
472 if(sz!=other._slices.size())
474 for(std::size_t i=0;i<sz;i++)
475 if(!_slices[i]->isEqual(*other._slices[i],_eps))
480 void MEDCouplingDefinitionTime::getIdsOnTimeRight(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
482 std::vector<int> meshIds;
483 std::vector<int> arrIds;
484 std::vector<int> arrIdsInField;
485 std::vector<int> fieldIds;
486 getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds);
487 meshId=meshIds.back();
489 arrIdInField=arrIdsInField.back();
490 fieldId=fieldIds.back();
493 void MEDCouplingDefinitionTime::getIdsOnTimeLeft(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
495 std::vector<int> meshIds;
496 std::vector<int> arrIds;
497 std::vector<int> arrIdsInField;
498 std::vector<int> fieldIds;
499 getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds);
500 meshId=meshIds.front();
501 arrId=arrIds.front();
502 arrIdInField=arrIdsInField.front();
503 fieldId=fieldIds.front();
506 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)
508 std::vector<int> ids;
510 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++,id++)
511 if((*it)->isContaining(tm,_eps))
514 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : No matching slice for such time !");
515 std::size_t sz=ids.size();
517 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : Too many slices match this time !");
521 arrIdsInField.resize(sz);
523 for(std::size_t i=0;i<sz;i++)
524 _slices[ids[i]]->getIdsOnTime(tm,_eps,meshIds[i],arrIds[i],arrIdsInField[i],fieldIds[i]);
527 std::vector<double> MEDCouplingDefinitionTime::getHotSpotsTime() const
529 std::vector<double> ret;
530 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++)
532 std::vector<double> tmp;
533 (*it)->getHotSpotsTime(tmp);
536 if(fabs(ret.back()-tmp.front())>_eps)
537 ret.insert(ret.end(),tmp.begin(),tmp.end());
539 ret.insert(ret.end(),tmp.begin()+1,tmp.end());
542 ret.insert(ret.end(),tmp.begin(),tmp.end());
547 void MEDCouplingDefinitionTime::appendRepr(std::ostream& stream) const
549 stream << "Time definition :\n";
550 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++)
553 (*it)->appendRepr(stream);
558 void MEDCouplingDefinitionTime::getTinySerializationInformation(std::vector<int>& tinyInfoI, std::vector<double>& tinyInfoD) const
560 int sz=(int)_slices.size();
563 tinyInfoI.resize(3*sz+2);
565 std::vector<int> coreData;
566 for(int i=0;i<sz;i++)
568 std::vector<int> tmp1;
569 std::vector<double> tmp2;
570 tinyInfoI[i+2]=(int)_slices[i]->getTimeType();
571 _slices[i]->getTinySerializationInformation(tmp1,tmp2);
572 tinyInfoI[i+sz+2]=(int)tmp1.size();
573 tinyInfoI[i+2*sz+2]=(int)tmp2.size();
574 coreData.insert(coreData.end(),tmp1.begin(),tmp1.end());
575 tinyInfoD.insert(tinyInfoD.end(),tmp2.begin(),tmp2.end());
577 tinyInfoI[1]=(int)coreData.size();
578 tinyInfoI.insert(tinyInfoI.end(),coreData.begin(),coreData.end());
581 void MEDCouplingDefinitionTime::unserialize(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD)
588 for(int i=0;i<sz;i++)
590 TypeOfTimeDiscretization ty=(TypeOfTimeDiscretization) tinyInfoI[i+2];
591 int sz1=tinyInfoI[i+sz+2];
592 int sz2=tinyInfoI[i+2*sz+2];
593 std::vector<int> tmp1(tinyInfoI.begin()+3*sz+2+offset1,tinyInfoI.begin()+3*sz+2+offset1+sz1);
594 std::vector<double> tmp2(tinyInfoD.begin()+offset2,tinyInfoD.begin()+offset2+sz2);
595 MEDCouplingDefinitionTimeSlice *pt=MEDCouplingDefinitionTimeSlice::New(ty,tmp1,tmp2);