Salome HOME
d17900a4de25dc94dc9d4a4cbd28009977ed5069
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingTimeDiscretization.txx
1 // Copyright (C) 2007-2019  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (EDF R&D)
20
21 #ifndef __MEDCOUPLINGTIMEDISCRETIZATION_TXX__
22 #define __MEDCOUPLINGTIMEDISCRETIZATION_TXX__
23
24 #include "MEDCouplingTimeDiscretization.hxx"
25 #include "MEDCouplingMemArray.txx"
26
27 #include <cmath>
28 #include <sstream>
29
30 namespace MEDCoupling
31 {
32   template<class T>
33   const char MEDCouplingTimeDiscretizationSimple<T>::REPR[]="One time label.";
34
35   template<class T>
36   const double MEDCouplingTimeDiscretizationTemplate<T>::TIME_TOLERANCE_DFT=1.e-12;
37   
38   template<class T>
39   void MEDCouplingTimeDiscretizationTemplate<T>::updateTime() const
40   {
41     if(_array)
42       updateTimeWith(*_array);
43   }
44   
45   template<class T>
46   void MEDCouplingTimeDiscretizationTemplate<T>::setArray(typename Traits<T>::ArrayType *array, TimeLabel *owner)
47   {
48     if(array!=_array)
49       {
50         if(_array)
51         _array->decrRef();
52         _array=array;
53         if(_array)
54           _array->incrRef();
55         if(owner)
56           owner->declareAsNew();
57       }
58   }
59   
60   template<class T>
61   void MEDCouplingTimeDiscretizationTemplate<T>::copyTinyAttrFrom(const MEDCouplingTimeDiscretizationTemplate<T>& other)
62   {
63     TimeHolder::copyTinyAttrFrom(other);
64     _time_tolerance=other._time_tolerance;
65   }
66   
67   template<class T>
68   void MEDCouplingTimeDiscretizationTemplate<T>::copyTinyStringsFrom(const MEDCouplingTimeDiscretizationTemplate<T>& other)
69   {
70     TimeHolder::copyTinyAttrFrom(other);
71     if(_array && other._array)
72       _array->copyStringInfoFrom(*other._array);
73   }
74
75   template<class T>
76   std::size_t MEDCouplingTimeDiscretizationTemplate<T>::getHeapMemorySizeWithoutChildren() const
77   {
78     return getTimeUnit().capacity();
79   }
80   
81   template<class T>
82   void MEDCouplingTimeDiscretizationTemplate<T>::checkConsistencyLight() const
83   {
84     if(!_array)
85       throw INTERP_KERNEL::Exception("Field invalid because no values set !");
86     if(_time_tolerance<0.)
87       throw INTERP_KERNEL::Exception("time tolerance is expected to be greater than 0. !");
88   }
89   
90   template<class T>
91   std::vector<const BigMemoryObject *> MEDCouplingTimeDiscretizationTemplate<T>::getDirectChildrenWithNull() const
92   {
93     std::vector<const BigMemoryObject *> ret;
94     ret.push_back(_array);
95     return ret;
96   }
97   
98   template<class T>
99   bool MEDCouplingTimeDiscretizationTemplate<T>::areStrictlyCompatible(const MEDCouplingTimeDiscretizationTemplate<T> *other, std::string& reason) const
100   {
101     std::ostringstream oss; oss.precision(15);
102     if(getTimeUnit()!=other->getTimeUnit())
103       {
104         oss << "Field discretizations differ : this time unit = \"" << getTimeUnit() << "\" and other time unit = \"" << other->getTimeUnit() << "\" !";
105         reason=oss.str();
106         return false;
107       }
108     if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16)
109       {
110         oss << "Field discretizations differ : this time tolerance = \"" << _time_tolerance << "\" and other time tolerance = \"" << other->_time_tolerance << "\" !";
111         reason=oss.str();
112         return false;
113       }
114     if(_array==0 && other->_array==0)
115       return true;
116     if(_array==0 || other->_array==0)
117       {
118         reason="Field discretizations differ : Only one timediscretization between the two this and other has a DataArrayDouble for values defined";
119         return false;
120       }
121     if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents())
122       return false;
123     if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples())
124       return false;
125     return true;
126   }
127   
128   template<class T>
129   bool MEDCouplingTimeDiscretizationTemplate<T>::areCompatible(const MEDCouplingTimeDiscretizationTemplate<T> *other) const
130   {
131     if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16)
132       return false;
133     if(_array==0 && other->_array==0)
134       return true;
135     if(_array==0 || other->_array==0)
136       return false;
137     if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents())
138       return false;
139     return true;
140   }
141   
142   template<class T>
143   bool MEDCouplingTimeDiscretizationTemplate<T>::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretizationTemplate<T> *other) const
144   {
145     if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16)
146       return false;
147     if(_array==0 && other->_array==0)
148       return true;
149     if(_array==0 || other->_array==0)
150       return false;
151     std::size_t nbC1(_array->getNumberOfComponents()),nbC2(other->_array->getNumberOfComponents());
152     std::size_t nbMin(std::min(nbC1,nbC2));
153     if(nbC1!=nbC2 && nbMin!=1)
154       return false;
155     return true;
156   }
157   
158   template<class T>
159   bool MEDCouplingTimeDiscretizationTemplate<T>::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretizationTemplate<T> *other) const
160   {
161     if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16)
162       return false;
163     if(_array==0 && other->_array==0)
164       return true;
165     if(_array==0 || other->_array==0)
166       return false;
167     std::size_t nbC1(_array->getNumberOfComponents()),nbC2(other->_array->getNumberOfComponents());
168     if(nbC1!=nbC2 && nbC2!=1)
169       return false;
170     return true;
171   }
172
173   template<class T>
174   MEDCouplingTimeDiscretizationTemplate<T>::MEDCouplingTimeDiscretizationTemplate():_time_tolerance(TIME_TOLERANCE_DFT),_array(0)
175   {
176   }
177
178   template<class T>
179   MEDCouplingTimeDiscretizationTemplate<T>::MEDCouplingTimeDiscretizationTemplate(const MEDCouplingTimeDiscretizationTemplate<T>& other, bool deepCopy):TimeHolder(other),_time_tolerance(other._time_tolerance)
180   {
181     if(other._array)
182       _array=other._array->performCopyOrIncrRef(deepCopy);
183     else
184       _array=0;
185   }
186   
187   template<class T>
188   MEDCouplingTimeDiscretizationTemplate<T>::~MEDCouplingTimeDiscretizationTemplate()
189   {
190     if(_array)
191       _array->decrRef();
192   }
193   
194   template<class T>
195   void MEDCouplingTimeDiscretizationTemplate<T>::setEndArray(typename Traits<T>::ArrayType *array, TimeLabel *owner)
196   {
197     throw INTERP_KERNEL::Exception("setEndArray not available for this type of time discretization !");
198   }
199   
200   template<class T>
201   void MEDCouplingTimeDiscretizationTemplate<T>::setArrays(const std::vector<typename Traits<T>::ArrayType *>& arrays, TimeLabel *owner)
202   {
203     if(arrays.size()!=1)
204       throw INTERP_KERNEL::Exception("MEDCouplingTimeDiscretization::setArrays : number of arrays must be one.");
205     setArray(arrays.back(),owner);
206   }
207   
208   template<class T>
209   const typename Traits<T>::ArrayType *MEDCouplingTimeDiscretizationTemplate<T>::getEndArray() const
210   {
211     throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !");
212   }
213   
214   template<class T>
215   typename Traits<T>::ArrayType *MEDCouplingTimeDiscretizationTemplate<T>::getEndArray()
216   {
217     throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !");
218   }
219   
220   template<class T>
221   void MEDCouplingTimeDiscretizationTemplate<T>::getArrays(std::vector<typename Traits<T>::ArrayType *>& arrays) const
222   {
223     arrays.resize(1);
224     arrays[0]=_array;
225   }
226   
227   template<class T>
228   void MEDCouplingTimeDiscretizationTemplate<T>::getTinySerializationIntInformation(std::vector<mcIdType>& tinyInfo) const
229   {
230     if(_array)
231       {
232         tinyInfo.push_back(_array->getNumberOfTuples());
233         tinyInfo.push_back(ToIdType(_array->getNumberOfComponents()));
234       }
235     else
236       {
237         tinyInfo.push_back(-1);
238         tinyInfo.push_back(-1);
239       }
240   }
241   
242   template<class T>
243   void MEDCouplingTimeDiscretizationTemplate<T>::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const
244   {
245     tinyInfo.push_back(_time_tolerance);
246   }
247   
248   template<class T>
249   void MEDCouplingTimeDiscretizationTemplate<T>::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
250   {
251     std::size_t nbOfCompo(_array->getNumberOfComponents());
252     for(std::size_t i=0;i<nbOfCompo;i++)
253       tinyInfo.push_back(_array->getInfoOnComponent(i));
254   }
255   
256   template<class T>
257   void MEDCouplingTimeDiscretizationTemplate<T>::resizeForUnserialization(const std::vector<mcIdType>& tinyInfoI, std::vector<typename Traits<T>::ArrayType *>& arrays)
258   {
259     arrays.resize(1);
260     if(_array!=0)
261       _array->decrRef();
262     typename Traits<T>::ArrayType *arr=0;
263     if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1)
264       {
265         arr=Traits<T>::ArrayType::New();
266         arr->alloc(tinyInfoI[0],tinyInfoI[1]);
267       }
268     _array=arr;
269     arrays[0]=arr;
270   }
271   
272   template<class T>
273   void MEDCouplingTimeDiscretizationTemplate<T>::checkForUnserialization(const std::vector<mcIdType>& tinyInfoI, const std::vector<typename Traits<T>::ArrayType *>& arrays)
274   {
275     static const char MSG[]="MEDCouplingTimeDiscretization::checkForUnserialization : arrays in input is expected to have size one !";
276     if(arrays.size()!=1)
277       throw INTERP_KERNEL::Exception(MSG);
278     if(_array!=0)
279       _array->decrRef();
280     _array=0;
281     if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1)
282       {
283         if(!arrays[0])
284           throw INTERP_KERNEL::Exception(MSG);
285         arrays[0]->checkNbOfTuplesAndComp(tinyInfoI[0],tinyInfoI[1],MSG);
286         _array=arrays[0];
287         _array->incrRef();
288       }
289   }
290   
291   template<class T>
292   void MEDCouplingTimeDiscretizationTemplate<T>::finishUnserialization(const std::vector<mcIdType>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS)
293   {
294     _time_tolerance=tinyInfoD[0];
295     std::size_t nbOfCompo=_array->getNumberOfComponents();
296     for(std::size_t i=0;i<nbOfCompo;i++)
297       _array->setInfoOnComponent(i,tinyInfoS[i]);
298   }
299   
300   /////////////////////////
301   
302   template<class T>
303   std::string MEDCouplingTimeDiscretizationSimple<T>::getStringRepr() const
304   {
305     std::ostringstream stream;
306     stream << REPR << " Time is defined by iteration=" << _tk.getIteration() << " order=" << _tk.getOrder() << " and time=" << _tk.getTimeValue() << ".";
307     stream << "\nTime unit is : \"" << this->getTimeUnit() << "\"";
308     return stream.str();
309   }
310   
311   template<class T>
312   double MEDCouplingTimeDiscretizationSimple<T>::getEndTime(int& iteration, int& order) const
313   {
314     throw INTERP_KERNEL::Exception("getEndTime : invalid for this type of time discr !");
315   }
316   
317   template<class T>
318   void MEDCouplingTimeDiscretizationSimple<T>::setEndIteration(int it)
319   {
320     throw INTERP_KERNEL::Exception("setEndIteration : invalid for this type of time discr !");
321   }
322   
323   template<class T>
324   void MEDCouplingTimeDiscretizationSimple<T>::setEndOrder(int order)
325   {
326     throw INTERP_KERNEL::Exception("setEndOrder : invalid for this type of time discr !");
327   }
328   
329   template<class T>
330   void MEDCouplingTimeDiscretizationSimple<T>::setEndTimeValue(double time)
331   {
332     throw INTERP_KERNEL::Exception("setEndTimeValue : invalid for this type of time discr !");
333   }
334   
335   template<class T>
336   void MEDCouplingTimeDiscretizationSimple<T>::setEndTime(double time, int iteration, int order)
337   {
338     throw INTERP_KERNEL::Exception("setEndTime : invalid for this type of time discr !");
339   }
340
341   template<class T>
342   MEDCouplingTimeDiscretizationSimple<T>::MEDCouplingTimeDiscretizationSimple(const MEDCouplingTimeDiscretizationSimple<T>& other, bool deepCopy):MEDCouplingTimeDiscretizationTemplate<T>(other,deepCopy),_tk(other._tk)
343   {
344   }
345 }
346
347 #endif