1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
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)
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)
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):_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::getHeapMemorySizeWithoutChildren() const
117 std::vector<const BigMemoryObject *> MEDCouplingDefinitionTimeSlice::getDirectChildrenWithNull() const
119 return std::vector<const BigMemoryObject *>();
122 bool MEDCouplingDefinitionTimeSlice::isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
124 double t1=getStartTime();
125 double t2=getEndTime();
126 double o1=other->getStartTime();
127 double o2=other->getEndTime();
128 return o1>t1-eps && o2<t2+eps;
131 bool MEDCouplingDefinitionTimeSlice::isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
133 double t1=getStartTime();
134 double t2=getEndTime();
135 double o1=other->getStartTime();
136 double o2=other->getEndTime();
137 return (o1<t1+eps && o2<t1+eps) || (o1>t2-eps && o2>t2-eps);
140 bool MEDCouplingDefinitionTimeSlice::isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
142 double t2=getEndTime();
143 double o1=other->getStartTime();
144 double o2=other->getEndTime();
145 return (o1>t2-eps && o2>t2-eps);
148 bool MEDCouplingDefinitionTimeSlice::isBeforeMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const
150 double t1=getStartTime();
151 double o1=other->getStartTime();
152 double o2=other->getEndTime();
153 return (o1<t1+eps && o2<t1+eps);
156 MEDCouplingDefinitionTimeSliceInst *MEDCouplingDefinitionTimeSliceInst::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
158 MEDCouplingDefinitionTimeSliceInst *ret=new MEDCouplingDefinitionTimeSliceInst;
159 ret->unserialize(tiI,tiD);
163 void MEDCouplingDefinitionTimeSliceInst::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
166 tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id;
171 void MEDCouplingDefinitionTimeSliceInst::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
173 _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2];
177 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceInst::getTimeType() const
182 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceInst::copy() const
184 return new MEDCouplingDefinitionTimeSliceInst(*this);
187 bool MEDCouplingDefinitionTimeSliceInst::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
189 if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
191 const MEDCouplingDefinitionTimeSliceInst *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceInst *>(&other);
194 return fabs(otherC->_instant-_instant)<eps;
197 void MEDCouplingDefinitionTimeSliceInst::getHotSpotsTime(std::vector<double>& ret) const
203 void MEDCouplingDefinitionTimeSliceInst::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const
211 bool MEDCouplingDefinitionTimeSliceInst::isContaining(double tmp, double eps) const
213 return fabs(tmp-_instant)<eps;
216 void MEDCouplingDefinitionTimeSliceInst::appendRepr(std::ostream& stream) const
218 stream << "single point " << _instant;
219 MEDCouplingDefinitionTimeSlice::appendRepr(stream);
222 double MEDCouplingDefinitionTimeSliceInst::getStartTime() const
227 double MEDCouplingDefinitionTimeSliceInst::getEndTime() const
232 MEDCouplingDefinitionTimeSliceInst::MEDCouplingDefinitionTimeSliceInst(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId)
235 double t1=f->getStartTime(tmp1,tmp2);
236 double t2=f->getEndTime(tmp1,tmp2);
237 double eps=f->getTimeTolerance();
239 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSliceInst : times differs in this");
243 MEDCouplingDefinitionTimeSliceCstOnTI *MEDCouplingDefinitionTimeSliceCstOnTI::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
245 MEDCouplingDefinitionTimeSliceCstOnTI *ret=new MEDCouplingDefinitionTimeSliceCstOnTI;
246 ret->unserialize(tiI,tiD);
250 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceCstOnTI::copy() const
252 return new MEDCouplingDefinitionTimeSliceCstOnTI(*this);
255 bool MEDCouplingDefinitionTimeSliceCstOnTI::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
257 if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
259 const MEDCouplingDefinitionTimeSliceCstOnTI *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceCstOnTI *>(&other);
262 if(fabs(otherC->_start-_start)>eps)
264 return fabs(otherC->_end-_end)<eps;
267 void MEDCouplingDefinitionTimeSliceCstOnTI::getHotSpotsTime(std::vector<double>& ret) const
270 ret[0]=(_start+_end)/2.;
273 void MEDCouplingDefinitionTimeSliceCstOnTI::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const
281 bool MEDCouplingDefinitionTimeSliceCstOnTI::isContaining(double tmp, double eps) const
283 return _start-eps<tmp && _end+eps>tmp;
286 void MEDCouplingDefinitionTimeSliceCstOnTI::appendRepr(std::ostream& stream) const
288 stream << "Constant on time interval [" << _start << "," << _end << "]";
289 MEDCouplingDefinitionTimeSlice::appendRepr(stream);
292 double MEDCouplingDefinitionTimeSliceCstOnTI::getStartTime() const
297 double MEDCouplingDefinitionTimeSliceCstOnTI::getEndTime() const
302 void MEDCouplingDefinitionTimeSliceCstOnTI::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
305 tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id;
307 tiD[0]=_start; tiD[1]=_end;
310 void MEDCouplingDefinitionTimeSliceCstOnTI::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
312 _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2];
313 _start=tiD[0]; _end=tiD[1];
316 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceCstOnTI::getTimeType() const
318 return CONST_ON_TIME_INTERVAL;
321 MEDCouplingDefinitionTimeSliceCstOnTI::MEDCouplingDefinitionTimeSliceCstOnTI(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId)
324 double t1=f->getStartTime(tmp1,tmp2);
325 double t2=f->getEndTime(tmp1,tmp2);
330 MEDCouplingDefinitionTimeSliceLT *MEDCouplingDefinitionTimeSliceLT::New(const std::vector<int>& tiI, const std::vector<double>& tiD)
332 MEDCouplingDefinitionTimeSliceLT *ret=new MEDCouplingDefinitionTimeSliceLT;
333 ret->unserialize(tiI,tiD);
337 MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceLT::copy() const
339 return new MEDCouplingDefinitionTimeSliceLT(*this);
342 bool MEDCouplingDefinitionTimeSliceLT::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const
344 if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps))
346 const MEDCouplingDefinitionTimeSliceLT *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceLT *>(&other);
349 if(_array_id_end!=otherC->_array_id_end)
351 if(fabs(otherC->_start-_start)>eps)
353 return fabs(otherC->_end-_end)<eps;
356 void MEDCouplingDefinitionTimeSliceLT::getHotSpotsTime(std::vector<double>& ret) const
363 void MEDCouplingDefinitionTimeSliceLT::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const
365 if(fabs(tm-_start)<eps)
373 if(fabs(tm-_end)<eps)
381 throw INTERP_KERNEL::Exception("LinearTime request not in boundary of this ! use hot spots !");
384 bool MEDCouplingDefinitionTimeSliceLT::isContaining(double tmp, double eps) const
386 return _start-eps<tmp && _end+eps>tmp;
389 void MEDCouplingDefinitionTimeSliceLT::appendRepr(std::ostream& stream) const
391 stream << "Linear on time interval [" << _start << "," << _end << "]";
392 MEDCouplingDefinitionTimeSlice::appendRepr(stream);
393 stream << " EndArrayId : " << _array_id_end;
396 double MEDCouplingDefinitionTimeSliceLT::getStartTime() const
401 double MEDCouplingDefinitionTimeSliceLT::getEndTime() const
406 int MEDCouplingDefinitionTimeSliceLT::getEndId() const
408 return _array_id_end;
411 void MEDCouplingDefinitionTimeSliceLT::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const
414 tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; tiI[3]=_array_id_end;
416 tiD[0]=_start; tiD[1]=_end;
419 void MEDCouplingDefinitionTimeSliceLT::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD)
421 _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; _array_id_end=tiI[3];
422 _start=tiD[0]; _end=tiD[1];
425 TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceLT::getTimeType() const
430 MEDCouplingDefinitionTimeSliceLT::MEDCouplingDefinitionTimeSliceLT(const MEDCouplingFieldDouble *f, int meshId, int arrId, int arr2Id, int fieldId):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId),_array_id_end(arr2Id)
433 double t1=f->getStartTime(tmp1,tmp2);
434 double t2=f->getEndTime(tmp1,tmp2);
439 MEDCouplingDefinitionTime::MEDCouplingDefinitionTime():_eps(EPS_DFT)
443 MEDCouplingDefinitionTime::MEDCouplingDefinitionTime(const std::vector<const MEDCouplingFieldDouble *>& fs, const std::vector<int>& meshRefs, const std::vector<std::vector<int> >& arrRefs)
445 std::size_t sz=fs.size();
446 if(sz!=arrRefs.size())
447 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : internal error ! should never happen !");
449 for(std::size_t i=0;i<sz;i++)
452 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : A field is null in list impossible to build a time definition !");
453 _slices[i]=MEDCouplingDefinitionTimeSlice::New(fs[i],meshRefs[i],arrRefs[i],(int)i);
457 const MEDCouplingDefinitionTimeSlice *ref=_slices[0];
458 _eps=fs[0]->getTimeTolerance();
459 for(std::size_t i=1;i<sz;i++)
461 if(!ref->isAfterMe(_slices[i],_eps))
462 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructors : the sequences of fields does NOT defines a stricly ascendant monotonic time sequence !");
463 // double t1=ref->getEndTime();
464 // double t2=_slices[i]->getStartTime();
465 // if(fabs(t1-t2)<_eps)
466 // if(ref->getEndId() != _slices[i]->getStartId())
467 // throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : 2 slices refers to the same time and underlying arrays differs !");
472 std::size_t MEDCouplingDefinitionTime::getHeapMemorySizeWithoutChildren() const
474 return _slices.capacity()*(sizeof(MEDCouplingDefinitionTimeSlice)+sizeof(int));
477 std::vector<const BigMemoryObject *> MEDCouplingDefinitionTime::getDirectChildrenWithNull() const
479 return std::vector<const BigMemoryObject *>();
482 void MEDCouplingDefinitionTime::assign(const MEDCouplingDefinitionTime& other)
484 std::size_t sz=other._slices.size();
486 for(std::size_t i=0;i<sz;i++)
487 _slices[i]=other._slices[i]->copy();
490 bool MEDCouplingDefinitionTime::isEqual(const MEDCouplingDefinitionTime& other) const
492 std::size_t sz=_slices.size();
493 if(sz!=other._slices.size())
495 for(std::size_t i=0;i<sz;i++)
496 if(!_slices[i]->isEqual(*other._slices[i],_eps))
501 void MEDCouplingDefinitionTime::getIdsOnTimeRight(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const
503 std::vector<int> meshIds;
504 std::vector<int> arrIds;
505 std::vector<int> arrIdsInField;
506 std::vector<int> fieldIds;
507 getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds);
508 meshId=meshIds.back();
510 arrIdInField=arrIdsInField.back();
511 fieldId=fieldIds.back();
514 void MEDCouplingDefinitionTime::getIdsOnTimeLeft(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const
516 std::vector<int> meshIds;
517 std::vector<int> arrIds;
518 std::vector<int> arrIdsInField;
519 std::vector<int> fieldIds;
520 getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds);
521 meshId=meshIds.front();
522 arrId=arrIds.front();
523 arrIdInField=arrIdsInField.front();
524 fieldId=fieldIds.front();
527 void MEDCouplingDefinitionTime::getIdsOnTime(double tm, std::vector<int>& meshIds, std::vector<int>& arrIds, std::vector<int>& arrIdsInField, std::vector<int>& fieldIds) const
529 std::vector<int> ids;
531 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++,id++)
532 if((*it)->isContaining(tm,_eps))
535 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : No matching slice for such time !");
536 std::size_t sz=ids.size();
538 throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : Too many slices match this time !");
542 arrIdsInField.resize(sz);
544 for(std::size_t i=0;i<sz;i++)
545 _slices[ids[i]]->getIdsOnTime(tm,_eps,meshIds[i],arrIds[i],arrIdsInField[i],fieldIds[i]);
548 std::vector<double> MEDCouplingDefinitionTime::getHotSpotsTime() const
550 std::vector<double> ret;
551 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++)
553 std::vector<double> tmp;
554 (*it)->getHotSpotsTime(tmp);
557 if(fabs(ret.back()-tmp.front())>_eps)
558 ret.insert(ret.end(),tmp.begin(),tmp.end());
560 ret.insert(ret.end(),tmp.begin()+1,tmp.end());
563 ret.insert(ret.end(),tmp.begin(),tmp.end());
568 void MEDCouplingDefinitionTime::appendRepr(std::ostream& stream) const
570 stream << "Time definition :\n";
571 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++)
574 (*it)->appendRepr(stream);
579 void MEDCouplingDefinitionTime::getTinySerializationInformation(std::vector<int>& tinyInfoI, std::vector<double>& tinyInfoD) const
581 int sz=(int)_slices.size();
584 tinyInfoI.resize(3*sz+2);
586 std::vector<int> coreData;
587 for(int i=0;i<sz;i++)
589 std::vector<int> tmp1;
590 std::vector<double> tmp2;
591 tinyInfoI[i+2]=(int)_slices[i]->getTimeType();
592 _slices[i]->getTinySerializationInformation(tmp1,tmp2);
593 tinyInfoI[i+sz+2]=(int)tmp1.size();
594 tinyInfoI[i+2*sz+2]=(int)tmp2.size();
595 coreData.insert(coreData.end(),tmp1.begin(),tmp1.end());
596 tinyInfoD.insert(tinyInfoD.end(),tmp2.begin(),tmp2.end());
598 tinyInfoI[1]=(int)coreData.size();
599 tinyInfoI.insert(tinyInfoI.end(),coreData.begin(),coreData.end());
602 void MEDCouplingDefinitionTime::unserialize(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD)
609 for(int i=0;i<sz;i++)
611 TypeOfTimeDiscretization ty=(TypeOfTimeDiscretization) tinyInfoI[i+2];
612 int sz1=tinyInfoI[i+sz+2];
613 int sz2=tinyInfoI[i+2*sz+2];
614 std::vector<int> tmp1(tinyInfoI.begin()+3*sz+2+offset1,tinyInfoI.begin()+3*sz+2+offset1+sz1);
615 std::vector<double> tmp2(tinyInfoD.begin()+offset2,tinyInfoD.begin()+offset2+sz2);
616 MEDCouplingDefinitionTimeSlice *pt=MEDCouplingDefinitionTimeSlice::New(ty,tmp1,tmp2);