From: ageay Date: Tue, 29 Jun 2010 12:52:16 +0000 (+0000) Subject: Addition of LINEAR_TIME time policy in MEDCoupling. X-Git-Tag: V5_1_main_FINAL~106 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=95f55a9b0b6d77cb62f3d1a1ae77e7b487ac0280;p=tools%2Fmedcoupling.git Addition of LINEAR_TIME time policy in MEDCoupling. --- diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index fcbfd84f7..a15d59df8 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -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& 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; diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index bffdc3e17..857211ed0 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -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; diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx index dccfc4c93..ff1a30ad3 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx @@ -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& 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(other); + _time=otherC._time; + _dt=otherC._dt; + _it=otherC._it; +} + MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCouplingTimeDiscretization *other) const { const MEDCouplingWithTimeStep *otherC=dynamic_cast(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(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(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& 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& 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& tinyInfo) const +{ + MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); + tinyInfo.push_back(_start_time); + tinyInfo.push_back(_end_time); +} + +void MEDCouplingTwoTimeSteps::getTinySerializationStrInformation(std::vector& tinyInfo) const +{ + int nbOfCompo=_array->getNumberOfComponents(); + for(int i=0;igetInfoOnComponent(i)); + for(int i=0;igetInfoOnComponent(i)); +} + void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) { arrays.resize(2); @@ -1043,10 +1190,10 @@ void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector& 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& 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& 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(other); + return otherC!=0; +} + +bool MEDCouplingLinearTime::areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatibleForMul(other)) + return false; + const MEDCouplingLinearTime *otherC=dynamic_cast(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& 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(),alpha)); + std::vector tmp(nbComp); + std::transform(vals.begin()+nbComp,vals.end(),tmp.begin(),std::bind2nd(std::multiplies(),1-alpha)); + std::transform(tmp.begin(),tmp.end(),res,res,std::plus()); +} + +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(),alpha)); + std::vector 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(),1-alpha)); + std::transform(tmp.begin(),tmp.end(),value,value,std::plus()); +} + +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(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(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(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(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(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(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(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(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(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); + getArray()->divideEqual(other->getArray()); + getEndArray()->divideEqual(other->getEndArray()); +} diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx index 8ea2f8c6d..925cb0733 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx @@ -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& 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& vals, double *res) const = 0; virtual void getArrays(std::vector& 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& 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& tinyInfo) const; + void getTinySerializationDbleInformation(std::vector& tinyInfo) const; + void getTinySerializationStrInformation(std::vector& tinyInfo) const; void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays); void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); + std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); + void setArrays(const std::vector& 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& 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; }; } diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx index 44657d523..14435a3c2 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx @@ -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(); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx index dbd2a6ff9..0926cd44c 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx @@ -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]; diff --git a/src/MEDCoupling_Swig/libMEDCoupling_Swig.i b/src/MEDCoupling_Swig/libMEDCoupling_Swig.i index ec02326ac..6ccbbb935 100644 --- a/src/MEDCoupling_Swig/libMEDCoupling_Swig.i +++ b/src/MEDCoupling_Swig/libMEDCoupling_Swig.i @@ -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);