1 // Copyright (C) 2007-2013 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
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCouplingDefinitionTime.hxx"
22 #include "MEDCouplingFieldDouble.hxx"
26 using namespace ParaMEDMEM;
28 const double MEDCouplingDefinitionTime::EPS_DFT=1e-15;
30 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(const MEDCouplingFieldDouble *f, int meshId, const std::vector<int>& arrId, int fieldId) throw(INTERP_KERNEL::Exception)
32 static const char msg[]="TimeSlice::New : mismatch of arrays number of a fieldDouble and its policy !!! Internal error !!!";
34 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : empty field !");
35 switch(f->getTimeDiscretization())
40 throw INTERP_KERNEL::Exception(msg);
41 return new MEDCouplingDefinitionTimeSliceInst(f,meshId,arrId[0],fieldId);
43 case CONST_ON_TIME_INTERVAL:
46 throw INTERP_KERNEL::Exception(msg);
47 return new MEDCouplingDefinitionTimeSliceCstOnTI(f,meshId,arrId[0],fieldId);
52 throw INTERP_KERNEL::Exception(msg);
53 return new MEDCouplingDefinitionTimeSliceLT(f,meshId,arrId[0],arrId[1],fieldId);
56 throw INTERP_KERNEL::Exception("Invalide time discretization ! NO_TIME ! Impossible to build a definition time slice !");
58 throw INTERP_KERNEL::Exception("Invalide time discretization : Not recognized !");
62 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(TypeOfTimeDiscretization type, const std::vector<int>& tiI, const std::vector<double>& tiD) throw(INTERP_KERNEL::Exception)
67 return MEDCouplingDefinitionTimeSliceInst::New(tiI,tiD);
68 case CONST_ON_TIME_INTERVAL:
69 return MEDCouplingDefinitionTimeSliceCstOnTI::New(tiI,tiD);
71 return MEDCouplingDefinitionTimeSliceLT::New(tiI,tiD);
73 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : unrecognized time discretization type !");
77 bool MEDCouplingDefinitionTimeSlice::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
79 if(_mesh_id!=other._mesh_id)
81 if(_array_id!=other._array_id)
83 if(_field_id!=other._field_id)
88 int MEDCouplingDefinitionTimeSlice::getStartId() const
93 int MEDCouplingDefinitionTimeSlice::getEndId() const
98 void MEDCouplingDefinitionTimeSlice::appendRepr(std::ostream& stream) const
100 stream << " *** MeshId : " << _mesh_id << " ArrayId : " << _array_id;
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)
106 double t1=f->getStartTime(tmp1,tmp2);
107 double t2=f->getEndTime(tmp1,tmp2);
109 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice : End time strictly before Start time ...");
112 std::size_t MEDCouplingDefinitionTimeSlice::getHeapMemorySize() const
117 bool MEDCouplingDefinitionTimeSlice::isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
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;
126 bool MEDCouplingDefinitionTimeSlice::isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
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);
135 bool MEDCouplingDefinitionTimeSlice::isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
137 double t2=getEndTime();
138 double o1=other->getStartTime();
139 double o2=other->getEndTime();
140 return (o1>t2-eps && o2>t2-eps);
143 bool MEDCouplingDefinitionTimeSlice::isBeforeMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
145 double t1=getStartTime();
146 double o1=other->getStartTime();
147 double o2=other->getEndTime();
148 return (o1<t1+eps && o2<t1+eps);
151 MEDCouplingDefinitionTimeSliceInst *MEDCouplingDefinitionTimeSliceInst::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
153 MEDCouplingDefinitionTimeSliceInst *ret=new MEDCouplingDefinitionTimeSliceInst;
154 ret->unserialize(tiI,tiD);
158 void MEDCouplingDefinitionTimeSliceInst::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
161 tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id;
166 void MEDCouplingDefinitionTimeSliceInst::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
168 _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2];
172 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceInst::getTimeType() const
177 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceInst::copy() const
179 return new MEDCouplingDefinitionTimeSliceInst(*this);
182 bool MEDCouplingDefinitionTimeSliceInst::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
184 if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
186 const MEDCouplingDefinitionTimeSliceInst *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceInst *>(&other);
189 return fabs(otherC->_instant-_instant)<eps;
192 void MEDCouplingDefinitionTimeSliceInst::getHotSpotsTime(std::vector<double>& ret) const
198 void MEDCouplingDefinitionTimeSliceInst::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
206 bool MEDCouplingDefinitionTimeSliceInst::isContaining(double tmp, double eps) const
208 return fabs(tmp-_instant)<eps;
211 void MEDCouplingDefinitionTimeSliceInst::appendRepr(std::ostream& stream) const
213 stream << "single point " << _instant;
214 MEDCouplingDefinitionTimeSlice::appendRepr(stream);
217 double MEDCouplingDefinitionTimeSliceInst::getStartTime() const
222 double MEDCouplingDefinitionTimeSliceInst::getEndTime() const
227 MEDCouplingDefinitionTimeSliceInst::MEDCouplingDefinitionTimeSliceInst(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId) throw(INTERP_KERNEL::Exception):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId)
230 double t1=f->getStartTime(tmp1,tmp2);
231 double t2=f->getEndTime(tmp1,tmp2);
232 double eps=f->getTimeTolerance();
234 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSliceInst : times differs in this");
238 MEDCouplingDefinitionTimeSliceCstOnTI *MEDCouplingDefinitionTimeSliceCstOnTI::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
240 MEDCouplingDefinitionTimeSliceCstOnTI *ret=new MEDCouplingDefinitionTimeSliceCstOnTI;
241 ret->unserialize(tiI,tiD);
245 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceCstOnTI::copy() const
247 return new MEDCouplingDefinitionTimeSliceCstOnTI(*this);
250 bool MEDCouplingDefinitionTimeSliceCstOnTI::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
252 if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
254 const MEDCouplingDefinitionTimeSliceCstOnTI *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceCstOnTI *>(&other);
257 if(fabs(otherC->_start-_start)>eps)
259 return fabs(otherC->_end-_end)<eps;
262 void MEDCouplingDefinitionTimeSliceCstOnTI::getHotSpotsTime(std::vector<double>& ret) const
265 ret[0]=(_start+_end)/2.;
268 void MEDCouplingDefinitionTimeSliceCstOnTI::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
276 bool MEDCouplingDefinitionTimeSliceCstOnTI::isContaining(double tmp, double eps) const
278 return _start-eps<tmp && _end+eps>tmp;
281 void MEDCouplingDefinitionTimeSliceCstOnTI::appendRepr(std::ostream& stream) const
283 stream << "Constant on time interval [" << _start << "," << _end << "]";
284 MEDCouplingDefinitionTimeSlice::appendRepr(stream);
287 double MEDCouplingDefinitionTimeSliceCstOnTI::getStartTime() const
292 double MEDCouplingDefinitionTimeSliceCstOnTI::getEndTime() const
297 void MEDCouplingDefinitionTimeSliceCstOnTI::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
300 tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id;
302 tiD[0]=_start; tiD[1]=_end;
305 void MEDCouplingDefinitionTimeSliceCstOnTI::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
307 _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2];
308 _start=tiD[0]; _end=tiD[1];
311 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceCstOnTI::getTimeType() const
313 return CONST_ON_TIME_INTERVAL;
316 MEDCouplingDefinitionTimeSliceCstOnTI::MEDCouplingDefinitionTimeSliceCstOnTI(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId) throw(INTERP_KERNEL::Exception):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId)
319 double t1=f->getStartTime(tmp1,tmp2);
320 double t2=f->getEndTime(tmp1,tmp2);
325 MEDCouplingDefinitionTimeSliceLT *MEDCouplingDefinitionTimeSliceLT::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
327 MEDCouplingDefinitionTimeSliceLT *ret=new MEDCouplingDefinitionTimeSliceLT;
328 ret->unserialize(tiI,tiD);
332 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceLT::copy() const
334 return new MEDCouplingDefinitionTimeSliceLT(*this);
337 bool MEDCouplingDefinitionTimeSliceLT::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
339 if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
341 const MEDCouplingDefinitionTimeSliceLT *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceLT *>(&other);
344 if(_array_id_end!=otherC->_array_id_end)
346 if(fabs(otherC->_start-_start)>eps)
348 return fabs(otherC->_end-_end)<eps;
351 void MEDCouplingDefinitionTimeSliceLT::getHotSpotsTime(std::vector<double>& ret) const
358 void MEDCouplingDefinitionTimeSliceLT::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
360 if(fabs(tm-_start)<eps)
368 if(fabs(tm-_end)<eps)
376 throw INTERP_KERNEL::Exception("LinearTime request not in boundary of this ! use hot spots !");
379 bool MEDCouplingDefinitionTimeSliceLT::isContaining(double tmp, double eps) const
381 return _start-eps<tmp && _end+eps>tmp;
384 void MEDCouplingDefinitionTimeSliceLT::appendRepr(std::ostream& stream) const
386 stream << "Linear on time interval [" << _start << "," << _end << "]";
387 MEDCouplingDefinitionTimeSlice::appendRepr(stream);
388 stream << " EndArrayId : " << _array_id_end;
391 double MEDCouplingDefinitionTimeSliceLT::getStartTime() const
396 double MEDCouplingDefinitionTimeSliceLT::getEndTime() const
401 int MEDCouplingDefinitionTimeSliceLT::getEndId() const
403 return _array_id_end;
406 void MEDCouplingDefinitionTimeSliceLT::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
409 tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; tiI[3]=_array_id_end;
411 tiD[0]=_start; tiD[1]=_end;
414 void MEDCouplingDefinitionTimeSliceLT::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
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];
420 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceLT::getTimeType() const
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)
428 double t1=f->getStartTime(tmp1,tmp2);
429 double t2=f->getEndTime(tmp1,tmp2);
434 MEDCouplingDefinitionTime::MEDCouplingDefinitionTime():_eps(EPS_DFT)
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)
440 std::size_t sz=fs.size();
441 if(sz!=arrRefs.size())
442 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : internal error ! should never happen !");
444 for(std::size_t i=0;i<sz;i++)
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);
452 const MEDCouplingDefinitionTimeSlice *ref=_slices[0];
453 _eps=fs[0]->getTimeTolerance();
454 for(std::size_t i=1;i<sz;i++)
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 !");
467 std::size_t MEDCouplingDefinitionTime::getHeapMemorySize() const
469 return _slices.capacity()*(sizeof(MEDCouplingDefinitionTimeSlice)+sizeof(int));
472 void MEDCouplingDefinitionTime::assign(const MEDCouplingDefinitionTime& other)
474 std::size_t sz=other._slices.size();
476 for(std::size_t i=0;i<sz;i++)
477 _slices[i]=other._slices[i]->copy();
480 bool MEDCouplingDefinitionTime::isEqual(const MEDCouplingDefinitionTime& other) const
482 std::size_t sz=_slices.size();
483 if(sz!=other._slices.size())
485 for(std::size_t i=0;i<sz;i++)
486 if(!_slices[i]->isEqual(*other._slices[i],_eps))
491 void MEDCouplingDefinitionTime::getIdsOnTimeRight(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
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();
500 arrIdInField=arrIdsInField.back();
501 fieldId=fieldIds.back();
504 void MEDCouplingDefinitionTime::getIdsOnTimeLeft(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const throw(INTERP_KERNEL::Exception)
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();
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)
519 std::vector<int> ids;
521 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++,id++)
522 if((*it)->isContaining(tm,_eps))
525 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : No matching slice for such time !");
526 std::size_t sz=ids.size();
528 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : Too many slices match this time !");
532 arrIdsInField.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]);
538 std::vector<double> MEDCouplingDefinitionTime::getHotSpotsTime() const
540 std::vector<double> ret;
541 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++)
543 std::vector<double> tmp;
544 (*it)->getHotSpotsTime(tmp);
547 if(fabs(ret.back()-tmp.front())>_eps)
548 ret.insert(ret.end(),tmp.begin(),tmp.end());
550 ret.insert(ret.end(),tmp.begin()+1,tmp.end());
553 ret.insert(ret.end(),tmp.begin(),tmp.end());
558 void MEDCouplingDefinitionTime::appendRepr(std::ostream& stream) const
560 stream << "Time definition :\n";
561 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++)
564 (*it)->appendRepr(stream);
569 void MEDCouplingDefinitionTime::getTinySerializationInformation(std::vector<int>& tinyInfoI, std::vector<double>& tinyInfoD) const
571 int sz=(int)_slices.size();
574 tinyInfoI.resize(3*sz+2);
576 std::vector<int> coreData;
577 for(int i=0;i<sz;i++)
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());
588 tinyInfoI[1]=(int)coreData.size();
589 tinyInfoI.insert(tinyInfoI.end(),coreData.begin(),coreData.end());
592 void MEDCouplingDefinitionTime::unserialize(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD)
599 for(int i=0;i<sz;i++)
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);