]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Addition of LINEAR_TIME time policy in MEDCoupling.
authorageay <ageay>
Tue, 29 Jun 2010 12:52:16 +0000 (12:52 +0000)
committerageay <ageay>
Tue, 29 Jun 2010 12:52:16 +0000 (12:52 +0000)
src/MEDCoupling/MEDCouplingFieldDouble.cxx
src/MEDCoupling/MEDCouplingFieldDouble.hxx
src/MEDCoupling/MEDCouplingTimeDiscretization.cxx
src/MEDCoupling/MEDCouplingTimeDiscretization.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx
src/MEDCoupling_Swig/libMEDCoupling_Swig.i

index fcbfd84f72727e9e350441b6d33021a5a2eb9e75..a15d59df8c139ef5ee8374c1dcb21dfe5a69831d 100644 (file)
@@ -118,8 +118,7 @@ void MEDCouplingFieldDouble::checkCoherency() const throw(INTERP_KERNEL::Excepti
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !");
-  if(!getArray())
-    throw INTERP_KERNEL::Exception("Field invalid because no values set !");
+  _time_discr->checkCoherency();
   _type->checkCoherencyBetween(_mesh,getArray());
 }
 
@@ -300,6 +299,11 @@ void MEDCouplingFieldDouble::setArray(DataArrayDouble *array)
   _time_discr->setArray(array,this);
 }
 
+void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array)
+{
+  _time_discr->setEndArray(array,this);
+}
+
 void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
 {
   tinyInfo.clear();
@@ -412,6 +416,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::addFields(const MEDCouplingField
   if(!f1->areCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply addFields on them !");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr);
+  td->copyTinyAttrFrom(*f1->_time_discr);
   MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField());
   ret->setMesh(f1->getMesh());
   return ret;
@@ -429,6 +434,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::substractFields(const MEDCouplin
   if(!f1->areCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply substractFields on them !");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr);
+  td->copyTinyAttrFrom(*f1->_time_discr);
   MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField());
   ret->setMesh(f1->getMesh());
   return ret;
@@ -446,6 +452,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCoupling
   if(!f1->areCompatibleForMul(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply multiplyFields on them !");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr);
+  td->copyTinyAttrFrom(*f1->_time_discr);
   MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField());
   ret->setMesh(f1->getMesh());
   return ret;
@@ -463,6 +470,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::divideFields(const MEDCouplingFi
   if(!f1->areCompatible(f2))
     throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply divideFields on them !");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr);
+  td->copyTinyAttrFrom(*f1->_time_discr);
   MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField());
   ret->setMesh(f1->getMesh());
   return ret;
index bffdc3e17ed743765c7a52a2ccf3ee22e8f94251..857211ed0fc4de67a01d9738830b6cf97e7768b9 100644 (file)
@@ -49,7 +49,9 @@ namespace ParaMEDMEM
     double getEndTime(int& dt, int& it) const { return _time_discr->getEndTime(dt,it); }
     double getIJ(int tupleId, int compoId) const { return getArray()->getIJ(tupleId,compoId); }
     void setArray(DataArrayDouble *array);
+    void setEndArray(DataArrayDouble *array);
     DataArrayDouble *getArray() const { return _time_discr->getArray(); }
+    DataArrayDouble *getEndArray() const { return _time_discr->getEndArray(); }
     double accumulate(int compId) const;
     void accumulate(double *res) const;
     double measureAccumulate(int compId, bool isWAbs) const;
index dccfc4c93e8c09272b8381c5535558fd5cccad89..ff1a30ad39ce51cb6612936a86ab760254769f03 100644 (file)
@@ -33,6 +33,8 @@ const char MEDCouplingWithTimeStep::EXCEPTION_MSG[]="No data on this time.";
 
 const char MEDCouplingConstOnTimeInterval::EXCEPTION_MSG[]="No data on this time.";
 
+const char MEDCouplingTwoTimeSteps::EXCEPTION_MSG[]="No data on this time.";
+
 const double MEDCouplingTimeDiscretization::TIME_TOLERANCE_DFT=1.e-12;
 
 MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::New(TypeOfTimeDiscretization type)
@@ -45,11 +47,26 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::New(TypeOfTimeDisc
       return new MEDCouplingWithTimeStep;
     case MEDCouplingConstOnTimeInterval::DISCRETIZATION:
       return new MEDCouplingConstOnTimeInterval;
+    case MEDCouplingLinearTime::DISCRETIZATION:
+      return new MEDCouplingLinearTime;
     default:
       throw INTERP_KERNEL::Exception("Time discretization not implemented yet");
     }
 }
 
+void MEDCouplingTimeDiscretization::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other)
+{
+  _time_tolerance=other._time_tolerance;
+}
+
+void MEDCouplingTimeDiscretization::checkCoherency() const throw(INTERP_KERNEL::Exception)
+{
+  if(!_array)
+    throw INTERP_KERNEL::Exception("Field invalid because no values set !");
+  if(_time_tolerance<0.)
+    throw INTERP_KERNEL::Exception("time tolerance is expected to be greater than 0. !");
+}
+
 void MEDCouplingTimeDiscretization::updateTime()
 {
   if(_array)
@@ -190,6 +207,16 @@ void MEDCouplingTimeDiscretization::setArray(DataArrayDouble *array, TimeLabel *
     }
 }
 
+DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() const
+{
+  throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !");
+}
+
+void MEDCouplingTimeDiscretization::setEndArray(DataArrayDouble *array, TimeLabel *owner)
+{
+  throw INTERP_KERNEL::Exception("setEndArray not available for this type of time discretization !");
+}
+
 void MEDCouplingTimeDiscretization::setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception)
 {
   if(arrays.size()!=1)
@@ -572,6 +599,15 @@ bool MEDCouplingWithTimeStep::isEqual(const MEDCouplingTimeDiscretization *other
   return MEDCouplingTimeDiscretization::isEqual(other,prec);
 }
 
+void MEDCouplingWithTimeStep::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other)
+{
+  MEDCouplingTimeDiscretization::copyTinyAttrFrom(other);
+  const MEDCouplingWithTimeStep& otherC=dynamic_cast<const MEDCouplingWithTimeStep& >(other);
+  _time=otherC._time;
+  _dt=otherC._dt;
+  _it=otherC._it;
+}
+
 MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCouplingTimeDiscretization *other) const
 {
   const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other);
@@ -994,6 +1030,68 @@ void MEDCouplingConstOnTimeInterval::divideEqual(const MEDCouplingTimeDiscretiza
   getArray()->divideEqual(other->getArray());
 }
 
+MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy),
+                                                                                                     _start_time(other._start_time),_end_time(other._end_time),
+                                                                                                     _start_dt(other._start_dt),_end_dt(other._end_dt),
+                                                                                                     _start_it(other._start_it),_end_it(other._end_it)
+{
+  if(other._end_array)
+    _end_array=other._end_array->performCpy(deepCpy);
+  else
+    _end_array=0;
+}
+
+void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other)
+{
+  MEDCouplingTimeDiscretization::copyTinyAttrFrom(other);
+  const MEDCouplingTwoTimeSteps& otherC=dynamic_cast<const MEDCouplingTwoTimeSteps& >(other);
+  _start_time=otherC._start_time;
+  _end_time=otherC._end_time;
+  _start_dt=otherC._start_dt;
+  _end_dt=otherC._end_dt;
+  _start_it=otherC._start_it;
+  _end_it=otherC._end_it;
+}
+
+DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() const
+{
+  return _end_array;
+}
+
+void MEDCouplingTwoTimeSteps::checkCoherency() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTimeDiscretization::checkCoherency();
+  if(!_end_array)
+    throw INTERP_KERNEL::Exception("No end array specified !");
+  if(_array->getNumberOfComponents()!=_end_array->getNumberOfComponents())
+    throw INTERP_KERNEL::Exception("The number of components mismatch between the start and the end arrays !");
+  if(_array->getNumberOfTuples()!=_end_array->getNumberOfTuples())
+    throw INTERP_KERNEL::Exception("The number of tuples mismatch between the start and the end arrays !");
+}
+
+bool MEDCouplingTwoTimeSteps::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const
+{
+  const MEDCouplingTwoTimeSteps *otherC=dynamic_cast<const MEDCouplingTwoTimeSteps *>(other);
+  if(!otherC)
+    return false;
+  if(_start_dt!=otherC->_start_dt)
+    return false;
+  if(_end_dt!=otherC->_end_dt)
+    return false;
+  if(_start_it!=otherC->_start_it)
+    return false;
+  if(_end_it!=otherC->_end_it)
+    return false;
+  if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance)
+    return false;
+  if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance)
+    return false;
+  if(_end_array!=otherC->_end_array)
+    if(!_end_array->isEqual(*otherC->_end_array,prec))
+      return false;
+  return MEDCouplingTimeDiscretization::isEqual(other,prec);
+}
+
 MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps():_start_time(0.),_end_time(0.),_start_dt(-1),_end_dt(-1),_start_it(-1),_end_it(-1),_end_array(0)
 {
 }
@@ -1027,6 +1125,55 @@ void MEDCouplingTwoTimeSteps::getArrays(std::vector<DataArrayDouble *>& arrays)
   arrays[1]=_end_array;
 }
 
+void MEDCouplingTwoTimeSteps::setEndArray(DataArrayDouble *array, TimeLabel *owner)
+{
+  if(array!=_end_array)
+    {
+      if(_end_array)
+        _end_array->decrRef();
+      _end_array=array;
+      if(_end_array)
+        _end_array->incrRef();
+      if(owner)
+        owner->declareAsNew();
+    }
+}
+
+void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
+{
+  MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo);
+  tinyInfo.push_back(_start_dt);
+  tinyInfo.push_back(_start_it);
+  tinyInfo.push_back(_end_dt);
+  tinyInfo.push_back(_end_it);
+  if(_end_array)
+    {
+      tinyInfo.push_back(_end_array->getNumberOfTuples());
+      tinyInfo.push_back(_end_array->getNumberOfComponents());
+    }
+  else
+    {
+      tinyInfo.push_back(-1);
+      tinyInfo.push_back(-1);
+    }
+}
+
+void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
+{
+  MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo);
+  tinyInfo.push_back(_start_time);
+  tinyInfo.push_back(_end_time);
+}
+
+void MEDCouplingTwoTimeSteps::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
+{
+  int nbOfCompo=_array->getNumberOfComponents();
+  for(int i=0;i<nbOfCompo;i++)
+    tinyInfo.push_back(_array->getInfoOnComponent(i));
+  for(int i=0;i<nbOfCompo;i++)
+    tinyInfo.push_back(_end_array->getInfoOnComponent(i));
+}
+
 void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector<int>& tinyInfoI, std::vector<DataArrayDouble *>& arrays)
 {
   arrays.resize(2);
@@ -1043,10 +1190,10 @@ void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector<int>& t
   _array=arr;
   arrays[0]=arr;
   arr=0;
-  if(tinyInfoI[2]!=-1 && tinyInfoI[3]!=-1)
+  if(tinyInfoI[6]!=-1 && tinyInfoI[7]!=-1)
     {
       arr=DataArrayDouble::New();
-      arr->alloc(tinyInfoI[2],tinyInfoI[3]);
+      arr->alloc(tinyInfoI[6],tinyInfoI[7]);
     }
   _end_array=arr;
   arrays[1]=arr;
@@ -1058,7 +1205,224 @@ void MEDCouplingTwoTimeSteps::finishUnserialization(const std::vector<int>& tiny
   _start_time=tinyInfoD[1];
   _end_time=tinyInfoD[2];
   _start_dt=tinyInfoI[2];
-  _end_dt=tinyInfoI[3];
-  _start_it=tinyInfoI[4];
+  _start_it=tinyInfoI[3];
+  _end_dt=tinyInfoI[4];
   _end_it=tinyInfoI[5];
 }
+
+std::vector< const DataArrayDouble *> MEDCouplingTwoTimeSteps::getArraysForTime(double time) const throw(INTERP_KERNEL::Exception)
+{
+   if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance)
+    {
+      std::vector< const DataArrayDouble *> ret(2);
+      ret[0]=_array;
+      ret[1]=_end_array;
+      return ret;
+    }
+  else
+    throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
+}
+
+void MEDCouplingTwoTimeSteps::setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception)
+{
+  if(arrays.size()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::setArrays : number of arrays must be two.");
+  setArray(arrays.front(),owner);
+  setArray(arrays.back(),owner);
+}
+
+MEDCouplingLinearTime::MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy):MEDCouplingTwoTimeSteps(other,deepCpy)
+{
+}
+
+MEDCouplingLinearTime::MEDCouplingLinearTime()
+{
+}
+
+void MEDCouplingLinearTime::checkCoherency() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingTwoTimeSteps::checkCoherency();
+  if(std::fabs(_start_time-_end_time)<_time_tolerance)
+    throw INTERP_KERNEL::Exception("Start time and end time are equals regarding time tolerance.");
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::performCpy(bool deepCpy) const
+{
+  return new MEDCouplingLinearTime(*this,deepCpy);
+}
+
+bool MEDCouplingLinearTime::areCompatible(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areCompatible(other))
+    return false;
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  return otherC!=0;
+}
+
+bool MEDCouplingLinearTime::areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const
+{
+  if(!MEDCouplingTimeDiscretization::areCompatibleForMul(other))
+    return false;
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  return otherC!=0;
+}
+
+/*!
+ * vals is expected to be of size 2*_array->getNumberOfTuples()==_array->getNumberOfTuples()+_end_array->getNumberOfTuples()
+ */
+void MEDCouplingLinearTime::getValueForTime(double time, const std::vector<double>& vals, double *res) const
+{
+  double alpha=(_end_time-time)/(_end_time-_start_time);
+  int nbComp=vals.size()/2;
+  std::transform(vals.begin(),vals.begin()+nbComp,res,std::bind2nd(std::multiplies<double>(),alpha));
+  std::vector<double> tmp(nbComp);
+  std::transform(vals.begin()+nbComp,vals.end(),tmp.begin(),std::bind2nd(std::multiplies<double>(),1-alpha));
+  std::transform(tmp.begin(),tmp.end(),res,res,std::plus<double>());
+}
+
+void MEDCouplingLinearTime::getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception)
+{
+  double alpha=(_end_time-time)/(_end_time-_start_time);
+  int nbComp;
+  if(_array)
+    _array->getTuple(eltId,value);
+  else
+    throw INTERP_KERNEL::Exception("No start array existing.");
+  nbComp=_array->getNumberOfComponents();
+  std::transform(value,value+nbComp,value,std::bind2nd(std::multiplies<double>(),alpha));
+  std::vector<double> tmp(nbComp);
+  if(_end_array)
+    _end_array->getTuple(eltId,&tmp[0]);
+  else
+    throw INTERP_KERNEL::Exception("No end array existing.");
+  std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::multiplies<double>(),1-alpha));
+  std::transform(tmp.begin(),tmp.end(),value,value,std::plus<double>());
+}
+
+void MEDCouplingLinearTime::getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception)
+{
+  if(dt==_start_dt && it==_start_it)
+    if(_array)
+      _array->getTuple(eltId,value);
+    else
+      throw INTERP_KERNEL::Exception("dt it match with start time but no start array existing.");
+  if(dt==_end_dt && it==_end_it)
+    if(_end_array)
+      _end_array->getTuple(eltId,value);
+    else
+      throw INTERP_KERNEL::Exception("dt it match with end time but no end array existing.");
+  else
+    throw INTERP_KERNEL::Exception(EXCEPTION_MSG);
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::aggregation on mismatched time discretization !");
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  ret->setTimeTolerance(getTimeTolerance());
+  DataArrayDouble *arr1=DataArrayDouble::aggregate(getArray(),other->getArray());
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  DataArrayDouble *arr2=DataArrayDouble::aggregate(getEndArray(),other->getEndArray());
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::add(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::add on mismatched time discretization !");
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  DataArrayDouble *arr1=DataArrayDouble::add(getArray(),other->getArray());
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  DataArrayDouble *arr2=DataArrayDouble::add(getEndArray(),other->getEndArray());
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+void MEDCouplingLinearTime::addEqual(const MEDCouplingTimeDiscretization *other)
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !");
+  getArray()->addEqual(other->getArray());
+  getEndArray()->addEqual(other->getEndArray());
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::substract(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::substract on mismatched time discretization !");
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  DataArrayDouble *arr1=DataArrayDouble::substract(getArray(),other->getArray());
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  DataArrayDouble *arr2=DataArrayDouble::substract(getEndArray(),other->getEndArray());
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+void MEDCouplingLinearTime::substractEqual(const MEDCouplingTimeDiscretization *other)
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !");
+  getArray()->substractEqual(other->getArray());
+  getEndArray()->substractEqual(other->getEndArray());
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::multiply(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::multiply on mismatched time discretization !");
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  DataArrayDouble *arr1=DataArrayDouble::multiply(getArray(),other->getArray());
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  DataArrayDouble *arr2=DataArrayDouble::multiply(getEndArray(),other->getEndArray());
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+void MEDCouplingLinearTime::multiplyEqual(const MEDCouplingTimeDiscretization *other)
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !");
+  getArray()->multiplyEqual(other->getArray());
+  getEndArray()->multiplyEqual(other->getEndArray());
+}
+
+MEDCouplingTimeDiscretization *MEDCouplingLinearTime::divide(const MEDCouplingTimeDiscretization *other) const
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::divide on mismatched time discretization !");
+  MEDCouplingLinearTime *ret=new MEDCouplingLinearTime;
+  DataArrayDouble *arr1=DataArrayDouble::divide(getArray(),other->getArray());
+  ret->setArray(arr1,0);
+  arr1->decrRef();
+  DataArrayDouble *arr2=DataArrayDouble::divide(getEndArray(),other->getEndArray());
+  ret->setEndArray(arr2,0);
+  arr2->decrRef();
+  return ret;
+}
+
+void MEDCouplingLinearTime::divideEqual(const MEDCouplingTimeDiscretization *other)
+{
+  const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !");
+  getArray()->divideEqual(other->getArray());
+  getEndArray()->divideEqual(other->getEndArray());
+}
index 8ea2f8c6df465abcf9ea0cbfbaedfe723774b969..925cb07338825759a625cfd0fbf941ea183dc1d6 100644 (file)
@@ -40,6 +40,8 @@ namespace ParaMEDMEM
   public:
     void updateTime();
     static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type);
+    virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other);
+    virtual void checkCoherency() const throw(INTERP_KERNEL::Exception);
     virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
     virtual bool areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
     virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const;
@@ -66,9 +68,10 @@ namespace ParaMEDMEM
     virtual void checkNoTimePresence() const throw(INTERP_KERNEL::Exception) = 0;
     virtual void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception) = 0;
     virtual void setArray(DataArrayDouble *array, TimeLabel *owner);
+    virtual void setEndArray(DataArrayDouble *array, TimeLabel *owner);
     virtual void setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception);
     DataArrayDouble *getArray() const { return _array; }
-    virtual DataArrayDouble *getEndArray() const { return _array; }
+    virtual DataArrayDouble *getEndArray() const;
     virtual std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception) = 0;
     virtual void getValueForTime(double time, const std::vector<double>& vals, double *res) const = 0; 
     virtual void getArrays(std::vector<DataArrayDouble *>& arrays) const;
@@ -139,6 +142,7 @@ namespace ParaMEDMEM
     MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy);
   public:
     MEDCouplingWithTimeStep();
+    void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other);
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
     MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
     MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const;
@@ -226,19 +230,31 @@ namespace ParaMEDMEM
   class MEDCOUPLING_EXPORT MEDCouplingTwoTimeSteps : public MEDCouplingTimeDiscretization
   {
   protected:
+    MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy);
     MEDCouplingTwoTimeSteps();
     ~MEDCouplingTwoTimeSteps();
   public:
+    void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other);
+    DataArrayDouble *getEndArray() const;
+    void checkCoherency() const throw(INTERP_KERNEL::Exception);
+    bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const;
     void checkNoTimePresence() const throw(INTERP_KERNEL::Exception);
     void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception);
     void getArrays(std::vector<DataArrayDouble *>& arrays) const;
-    DataArrayDouble *getEndArray() const { return _end_array; }
+    void setEndArray(DataArrayDouble *array, TimeLabel *owner);
     void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_dt=dt; _start_it=it; }
     void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_dt=dt; _end_it=it; }
     double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_start_dt; it=_start_it; return _start_time; }
     double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_end_dt; it=_end_it; return _end_time; }
+    void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
+    void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const;
+    void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const;
     void resizeForUnserialization(const std::vector<int>& tinyInfoI, std::vector<DataArrayDouble *>& arrays);
     void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS);
+    std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception);
+    void setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception);
+  protected:
+    static const char EXCEPTION_MSG[];
   protected:
     double _start_time;
     double _end_time;
@@ -251,8 +267,28 @@ namespace ParaMEDMEM
 
   class MEDCOUPLING_EXPORT MEDCouplingLinearTime : public MEDCouplingTwoTimeSteps
   {
+  protected:
+    MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy);
   public:
+    MEDCouplingLinearTime();
     TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; }
+    void checkCoherency() const throw(INTERP_KERNEL::Exception);
+    MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const;
+    bool areCompatible(const MEDCouplingTimeDiscretization *other) const;
+    bool areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const;
+    void getValueForTime(double time, const std::vector<double>& vals, double *res) const;
+    void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception);
+    void getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception);
+    MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const;
+    MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const;
+    void addEqual(const MEDCouplingTimeDiscretization *other);
+    MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const;
+    void substractEqual(const MEDCouplingTimeDiscretization *other);
+    MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const;
+    void multiplyEqual(const MEDCouplingTimeDiscretization *other);
+    MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const;
+    void divideEqual(const MEDCouplingTimeDiscretization *other);
+  public:
     static const TypeOfTimeDiscretization DISCRETIZATION=LINEAR_TIME;
   };
 }
index 44657d5231a317c4ddbc2ee77cdf57b9a27ae1b8..14435a3c2d2b2d43f391c9dbe191066f3dfb0aaf 100644 (file)
@@ -63,6 +63,7 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testOperationsOnFields );
     CPPUNIT_TEST( testOperationsOnFields2 );
     CPPUNIT_TEST( testOperationsOnFields3 );
+    CPPUNIT_TEST( testOperationsOnFields4 );
     CPPUNIT_TEST( testMergeNodesOnField );
     CPPUNIT_TEST( testCheckConsecutiveCellTypes );
     CPPUNIT_TEST( testBuildOrthogonalField );
@@ -165,6 +166,7 @@ namespace ParaMEDMEM
     void testOperationsOnFields();
     void testOperationsOnFields2();
     void testOperationsOnFields3();
+    void testOperationsOnFields4();
     void testMergeNodesOnField();
     void testCheckConsecutiveCellTypes();
     void testBuildOrthogonalField();
index dbd2a6ff95ed8e23d3e36e60de0eef70a6013c52..0926cd44c4c901953c64dca3c2d7d4c8fee14f8f 100644 (file)
@@ -1525,6 +1525,105 @@ void MEDCouplingBasicsTest::testOperationsOnFields3()
   m->decrRef();
 }
 
+/*!
+ * Check of LINEAR_TIME and CONST_ON_TIME_INTERVAL policies
+ */
+void MEDCouplingBasicsTest::testOperationsOnFields4()
+{
+  MEDCouplingUMesh *m=build2DTargetMesh_1();
+  int nbOfCells=m->getNumberOfCells();
+  MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL);
+  f1->setMesh(m);
+  DataArrayDouble *array=DataArrayDouble::New();
+  array->alloc(nbOfCells,3);
+  f1->setArray(array);
+  CPPUNIT_ASSERT_THROW(f1->setEndArray(array),INTERP_KERNEL::Exception);
+  CPPUNIT_ASSERT_THROW(f1->getEndArray(),INTERP_KERNEL::Exception);
+  array->decrRef();
+  double *tmp=array->getPointer();
+  const double arr1[15]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.};
+  const double arr2[15]={5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.};
+  std::copy(arr1,arr1+15,tmp);
+  f1->setStartTime(2.,0,0);
+  f1->setEndTime(3.,0,0);
+  f1->checkCoherency();
+  double res[3];
+  const double pos[2]={0.3,-0.2};
+  f1->getValueOn(pos,res);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12);
+  std::fill(res,res+3,0.);
+  f1->getValueOn(pos,2.2,res);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12);
+  std::fill(res,res+3,0.);
+  CPPUNIT_ASSERT_THROW(f1->getValueOn(pos,3.2,res),INTERP_KERNEL::Exception);
+  MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME);
+  f2->setMesh(m);
+  f2->setArray(f1->getArray());
+  f2->setStartTime(2.,3,0);
+  f2->setEndTime(4.,13,0);
+  CPPUNIT_ASSERT_THROW(f2->checkCoherency(),INTERP_KERNEL::Exception);
+  DataArrayDouble *array2=DataArrayDouble::New();
+  array2->alloc(nbOfCells,3);
+  tmp=array2->getPointer();
+  std::copy(arr2,arr2+15,tmp);
+  f2->setEndArray(array2);
+  array2->decrRef();
+  f2->checkCoherency();
+  //
+  std::fill(res,res+3,0.);
+  f2->getValueOn(pos,3.21,res);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(4.025,res[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(14.025,res[1],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(24.025,res[2],1.e-12);
+  MEDCouplingFieldDouble *f3=f2->clone(true);
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-12));
+  f3->getEndArray()->getPointer()[0]=5.001;
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-12));
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2));
+  f3->setStartTime(2.1,3,0);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setStartTime(2.,3,0);
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2));
+  f3->setStartTime(2.,4,0);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setStartTime(2.,3,1);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setStartTime(2.,3,0);
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2));
+  f3->setEndTime(4.1,13,0);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setEndTime(4.,13,0);
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2));
+  f3->setEndTime(4.,14,0);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setEndTime(4.,13,1);
+  CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2));
+  f3->setEndTime(4.,13,0);
+  CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2));
+  f3->decrRef();
+  MEDCouplingFieldDouble *f4=(*f2)+(*f2);
+  std::fill(res,res+3,0.);
+  f4->getValueOn(pos,3.21,res);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(8.05,res[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(28.05,res[1],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(48.05,res[2],1.e-12);
+  (*f4)+=*f2;
+  std::fill(res,res+3,0.);
+  f4->getValueOn(pos,3.21,res);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(12.075,res[0],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(42.075,res[1],1.e-12);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(72.075,res[2],1.e-12);
+  f4->decrRef();
+  //
+  f2->decrRef();
+  f1->decrRef();
+  m->decrRef();
+}
+
 bool func4(const double *pt, double *res)
 {
   res[0]=pt[0]+pt[1]+pt[2];
index ec02326ac897617a120b499043f345312df71046..6ccbbb9353cca40ff180556c9747b7f8399a5bca 100644 (file)
@@ -178,6 +178,7 @@ namespace ParaMEDMEM
     void checkCoherency() const throw(INTERP_KERNEL::Exception);
     double getIJ(int tupleId, int compoId) const;
     void setArray(DataArrayDouble *array);
+    void setEndArray(DataArrayDouble *array);
     void setTime(double val, int dt, int it);
     void setStartTime(double val, int dt, int it);
     void setEndTime(double val, int dt, int it);