Salome HOME
Copyrights update 2015.
[modules/med.git] / src / MEDCoupling / MEDCouplingPartDefinition.cxx
1 // Copyright (C) 2007-2015  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 #include "MEDCouplingPartDefinition.hxx"
22
23 using namespace ParaMEDMEM;
24
25 PartDefinition *PartDefinition::New(int start, int stop, int step)
26 {
27   return SlicePartDefinition::New(start,stop,step);
28 }
29
30 PartDefinition *PartDefinition::New(DataArrayInt *listOfIds)
31 {
32   return DataArrayPartDefinition::New(listOfIds);
33 }
34
35 PartDefinition::~PartDefinition()
36 {
37 }
38
39 DataArrayPartDefinition *DataArrayPartDefinition::New(DataArrayInt *listOfIds)
40 {
41   return new DataArrayPartDefinition(listOfIds);
42 }
43
44 int DataArrayPartDefinition::getNumberOfElems() const
45 {
46   checkInternalArrayOK();
47   return _arr->getNumberOfTuples();
48 }
49
50 PartDefinition *DataArrayPartDefinition::operator+(const PartDefinition& other) const
51 {
52   const PartDefinition *otherPt(&other);
53   if(!otherPt)
54     throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : NULL input !");
55   const DataArrayPartDefinition *other1(dynamic_cast<const DataArrayPartDefinition *>(otherPt));
56   if(other1)
57     return add1(other1);
58   const SlicePartDefinition *other2(dynamic_cast<const SlicePartDefinition *>(otherPt));
59   if(other2)
60     return add2(other2);
61   throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : unrecognized type in input !");
62 }
63
64 std::string DataArrayPartDefinition::getRepr() const
65 {
66   std::ostringstream oss; oss << "DataArray Part : ";
67   const DataArrayInt *arr(_arr);
68   if(arr)
69     arr->reprQuickOverview(oss);
70   else
71     oss << "No Data !";
72   return oss.str();
73 }
74
75 /*!
76  * This method operates FoG where F is \a this and G is \a other.
77  * Example : if \a other is SlicePart(4,14,1) and if \a this is DataArrayPartDefinition([0,1,2,3,6,7,8,9]) -> DataArrayPartDefinition([4,5,6,7,11,12,13]) will be returned
78  */
79 PartDefinition *DataArrayPartDefinition::composeWith(const PartDefinition *other) const
80 {
81   if(!other)
82     throw INTERP_KERNEL::Exception("DataArrayPartDefinition::composeWith : input PartDef must be not NULL !");
83   checkCoherency();
84   other->checkCoherency();
85   const SlicePartDefinition *spd(dynamic_cast<const SlicePartDefinition *>(other));
86   if(spd)
87     {//special case for optim
88       int a(0),b(0),c(0);
89       spd->getSlice(a,b,c);
90       if(c==1)
91         {
92           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New());
93           arr->alloc(_arr->getNumberOfTuples(),1);
94           std::transform(_arr->begin(),_arr->end(),arr->getPointer(),std::bind2nd(std::plus<int>(),a));
95           return DataArrayPartDefinition::New(arr);
96         }
97     }
98   //
99   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr1(other->toDAI());
100   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2(arr1->selectByTupleIdSafe(_arr->begin(),_arr->end()));
101   return DataArrayPartDefinition::New(arr2);
102 }
103
104 void DataArrayPartDefinition::checkCoherency() const
105 {
106   CheckInternalArrayOK(_arr);
107 }
108
109 /*!
110  * This method tries to simplify \a this if possible.
111  * 
112  * \return a new reference (equal to this) to be decrRefed.
113  */
114 PartDefinition *DataArrayPartDefinition::tryToSimplify() const
115 {
116   checkCoherency();
117   int a(0),b(0),c(0);
118   if(_arr->isRange(a,b,c))
119     {
120       return SlicePartDefinition::New(a,b,c);
121     }
122   else
123     {
124       PartDefinition *ret(const_cast<DataArrayPartDefinition *>(this));
125       ret->incrRef();
126       return ret;
127     }
128 }
129
130 DataArrayInt *DataArrayPartDefinition::toDAI() const
131 {
132   checkInternalArrayOK();
133   const DataArrayInt *arr(_arr);
134   DataArrayInt *arr2(const_cast<DataArrayInt *>(arr));
135   arr2->incrRef();
136   return arr2;
137 }
138
139 DataArrayPartDefinition::DataArrayPartDefinition(DataArrayInt *listOfIds)
140 {
141   CheckInternalArrayOK(listOfIds);
142   _arr=listOfIds;
143   _arr->incrRef();
144 }
145
146 void DataArrayPartDefinition::checkInternalArrayOK() const
147 {
148   CheckInternalArrayOK(_arr);
149 }
150
151 void DataArrayPartDefinition::CheckInternalArrayOK(const DataArrayInt *listOfIds)
152 {
153   if(!listOfIds || !listOfIds->isAllocated() || listOfIds->getNumberOfComponents()!=1)
154     throw INTERP_KERNEL::Exception("DataArrayPartDefinition::CheckInternalArrayOK : Input list must be not null allocated and with one components !");
155 }
156
157 void DataArrayPartDefinition::updateTime() const
158 {
159   if((const DataArrayInt *)_arr)
160     updateTimeWith(*_arr);
161 }
162
163 std::size_t DataArrayPartDefinition::getHeapMemorySizeWithoutChildren() const
164 {
165   return sizeof(DataArrayPartDefinition);
166 }
167
168 std::vector<const BigMemoryObject *> DataArrayPartDefinition::getDirectChildrenWithNull() const
169 {
170   std::vector<const BigMemoryObject *> ret(1,(const DataArrayInt *)_arr);
171   return ret;
172 }
173
174 DataArrayPartDefinition *DataArrayPartDefinition::add1(const DataArrayPartDefinition *other) const
175 {
176   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a1(toDAI()),a2(other->toDAI());
177   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a3(DataArrayInt::Aggregate(a1,a2,0));
178   a3->sort();
179   return DataArrayPartDefinition::New(a3);
180 }
181
182 DataArrayPartDefinition *DataArrayPartDefinition::add2(const SlicePartDefinition *other) const
183 {
184   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a1(toDAI()),a2(other->toDAI());
185   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a3(DataArrayInt::Aggregate(a1,a2,0));
186   a3->sort();
187   return DataArrayPartDefinition::New(a3);
188 }
189
190 DataArrayPartDefinition::~DataArrayPartDefinition()
191 {
192 }
193
194 SlicePartDefinition *SlicePartDefinition::New(int start, int stop, int step)
195 {
196   return new SlicePartDefinition(start,stop,step);
197 }
198
199 DataArrayInt *SlicePartDefinition::toDAI() const
200 {
201   return DataArrayInt::Range(_start,_stop,_step);
202 }
203
204 int SlicePartDefinition::getNumberOfElems() const
205 {
206   return DataArray::GetNumberOfItemGivenBES(_start,_stop,_step,"SlicePartDefinition::getNumberOfElems");
207 }
208
209 PartDefinition *SlicePartDefinition::operator+(const PartDefinition& other) const
210 {
211   const PartDefinition *otherPt(&other);
212   if(!otherPt)
213     throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : NULL input !");
214   const DataArrayPartDefinition *other1(dynamic_cast<const DataArrayPartDefinition *>(otherPt));
215   if(other1)
216     return add1(other1);
217   const SlicePartDefinition *other2(dynamic_cast<const SlicePartDefinition *>(otherPt));
218   if(other2)
219     return add2(other2);
220   throw INTERP_KERNEL::Exception("SlicePartDefinition::operator+ : unrecognized type in input !");
221 }
222
223 /*!
224  * This method operates FoG where F is \a this and G is \a other.
225  * Example : if \a this is SlicePart(4,6,1) and if \a other is DataArrayPartDefinition([12,13,17,18,22,28,34,44]) -> DataArrayPartDefinition([22,28]) will be returned
226  */
227 PartDefinition *SlicePartDefinition::composeWith(const PartDefinition *other) const
228 {
229   if(!other)
230     throw INTERP_KERNEL::Exception("SlicePartDefinition::composeWith : input PartDef must be not NULL !");
231   checkCoherency();
232   other->checkCoherency();
233   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(other->toDAI());
234   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr1(arr->selectByTupleId2(_start,_stop,_step));
235   return DataArrayPartDefinition::New(arr1);
236 }
237
238 /*!
239  * Do nothing it is not a bug.
240  */
241 void SlicePartDefinition::checkCoherency() const
242 {
243 }
244
245 /*!
246  * Return \a this (because it cannot be simplified)
247  * 
248  * \return a new reference (equal to this) to be decrRefed.
249  */
250 PartDefinition *SlicePartDefinition::tryToSimplify() const
251 {
252   PartDefinition *ret(const_cast<SlicePartDefinition *>(this));
253   ret->incrRef();
254   return ret;
255 }
256
257 std::string SlicePartDefinition::getRepr() const
258 {
259   std::ostringstream oss;
260   oss << "Slice is defined with : start=" << _start << " stop=" << _stop << " step=" << _step;
261   return oss.str();
262 }
263
264 int SlicePartDefinition::getEffectiveStop() const
265 {
266   int nbElems(DataArray::GetNumberOfItemGivenBES(_start,_stop,_step,"SlicePartDefinition::getEffectiveStop"));
267   return _start+nbElems*_step;
268 }
269
270 void SlicePartDefinition::getSlice(int& start, int& stop, int& step) const
271 {
272   start=_start;
273   stop=_stop;
274   step=_step;
275 }
276
277 SlicePartDefinition::SlicePartDefinition(int start, int stop, int step):_start(start),_stop(stop),_step(step)
278 {
279 }
280
281 /*!
282  * No child ! It is the leaf ! So no implementation.
283  */
284 void SlicePartDefinition::updateTime() const
285 {
286 }
287
288 std::size_t SlicePartDefinition::getHeapMemorySizeWithoutChildren() const
289 {
290   return sizeof(SlicePartDefinition);
291 }
292
293 std::vector<const BigMemoryObject *> SlicePartDefinition::getDirectChildrenWithNull() const
294 {
295   return std::vector<const BigMemoryObject *>();
296 }
297
298 DataArrayPartDefinition *SlicePartDefinition::add1(const DataArrayPartDefinition *other) const
299 {
300   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a1(toDAI()),a2(other->toDAI());
301   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a3(DataArrayInt::Aggregate(a1,a2,0));
302   a3->sort();
303   return DataArrayPartDefinition::New(a3);
304 }
305
306 PartDefinition *SlicePartDefinition::add2(const SlicePartDefinition *other) const
307 {
308   if(_step==other->_step && getEffectiveStop()==other->_start)
309     {
310       return SlicePartDefinition::New(_start,other->_stop,_step);
311     }
312   else
313     {
314       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a1(toDAI()),a2(other->toDAI());
315       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a3(DataArrayInt::Aggregate(a1,a2,0));
316       a3->sort();
317       return DataArrayPartDefinition::New(a3);
318     }
319 }
320
321 SlicePartDefinition::~SlicePartDefinition()
322 {
323 }