]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_nArray.hxx
Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.git] / src / MEDMEM / MEDMEM_nArray.hxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #ifndef MEDMEM_ARRAY_HXX
24 #define MEDMEM_ARRAY_HXX
25
26 #include "MEDMEM.hxx"
27
28 #include "MEDMEM_InterlacingPolicy.hxx"
29 #include "MEDMEM_IndexCheckingPolicy.hxx"
30
31 #include "MEDMEM_PointerOf.hxx"
32 #include "MEDMEM_define.hxx"
33
34 namespace MEDMEM {
35
36 class MEDMEM_EXPORT MEDMEM_Array_ {
37 public:
38   //virtual void dummy() {};
39   virtual bool getGaussPresence() const { return false; }
40   virtual MED_EN::medModeSwitch getInterlacingType() const {return MED_EN::MED_UNDEFINED_INTERLACE;}
41   virtual ~MEDMEM_Array_() {}; //Indispensable pour détruire le vrai objet pointé
42 };
43
44 template < class ARRAY_ELEMENT_TYPE,
45            class INTERLACING_POLICY=FullInterlaceNoGaussPolicy,
46            class CHECKING_POLICY=IndexCheckPolicy >
47 class MEDMEM_Array : public INTERLACING_POLICY, public CHECKING_POLICY, public MEDMEM_Array_ {
48
49 public :
50
51   typedef ARRAY_ELEMENT_TYPE  ElementType;
52   typedef INTERLACING_POLICY  InterlacingPolicy;
53   typedef CHECKING_POLICY     CheckingPolicy;
54
55 public  :
56   MEDMEM_Array():_array( ( ElementType *) NULL)  {}; //Interdit le constructeur par défaut, peut pas à  cause du FIELD
57
58   ~MEDMEM_Array() {
59     // PointerOf s'occupe de la desallocation.
60   };
61
62   // Le mot clé inline permettra d'instancier le constructeur uniquement
63   // s'il est appelé ( ...NoGaussPolicy)
64   // Rem : Le constructeur de la policy demandée est appelé
65   inline MEDMEM_Array(int dim, int nbelem) : InterlacingPolicy(nbelem,dim)
66   {
67     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
68     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
69     _array.set(InterlacingPolicy::_arraySize);
70   };
71
72   // Le mot clé inline permettra d'instancier le constructeur uniquement
73   // s'il est appelé NoInterlaceByTypeNoGaussPolicy(...)
74   // Rem : Le constructeur de la policy demandée est appelé
75   inline MEDMEM_Array(int dim, int nbelem,
76                       int nbtypegeo, const int * const nbelgeoc)
77     : InterlacingPolicy(nbelem, dim, nbtypegeo, nbelgeoc)
78   {
79     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
80     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
81     _array.set(InterlacingPolicy::_arraySize);
82   };
83
84   // Le mot clé inline permettra d'instancier le constructeur uniquement
85   // s'il est appelé ( ...NoGaussPolicy)
86   // Rem : Le constructeur de la policy demandée est appelé
87   inline MEDMEM_Array( ElementType * values, int dim, int nbelem,
88                        bool shallowCopy=false,
89                        bool ownershipOfValues=false) : InterlacingPolicy(nbelem,dim)
90   {
91     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
92     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
93     if(shallowCopy)
94
95       if(ownershipOfValues)
96         _array.setShallowAndOwnership((const ElementType *)values);
97       else
98         _array.set((const ElementType*)values);
99
100     else // Cas par défaut
101       _array.set(InterlacingPolicy::_arraySize,values);
102
103   }
104
105   // Le mot clé inline permettra d'instancier le constructeur uniquement
106   // s'il est appelé NoInterlaceByTypeNoGaussPolicy(...)
107   // Rem : Le constructeur de la policy demandée est appelé
108   inline MEDMEM_Array( ElementType * values, int dim, int nbelem,
109                        int nbtypegeo, const int * const  nbelgeoc,
110                        bool shallowCopy=false,
111                        bool ownershipOfValues=false) 
112     : InterlacingPolicy(nbelem, dim, nbtypegeo, nbelgeoc)
113   {
114     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
115     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
116     if(shallowCopy)
117
118       if(ownershipOfValues)
119         _array.setShallowAndOwnership((const ElementType *)values);
120       else
121         _array.set((const ElementType*)values);
122
123     else // Cas par défaut
124       _array.set(InterlacingPolicy::_arraySize,values);
125
126   }
127
128   // Le mot clé inline permettra d'instancier le constructeur uniquement
129   // s'il est appelé ( ...GaussPolicy)
130   // Rem : Le constructeur de la policy demandée est appelé
131   inline MEDMEM_Array(int dim, int nbelem, int nbtypegeo,
132                       const int * const  nbelgeoc, const int * const nbgaussgeo)
133     : InterlacingPolicy(nbelem, dim, nbtypegeo, nbelgeoc, nbgaussgeo)
134   {
135     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
136     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
137     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbtypegeo);
138     _array.set(InterlacingPolicy::_arraySize);
139   };
140
141
142   // Le mot clé inline permettra d'instancier le constructeur uniquement
143   // s'il est appelé ( ...GaussPolicy)
144   // Rem : Le constructeur de la policy demandée est appelé
145   inline MEDMEM_Array(ElementType * values, int dim, int nbelem, int nbtypegeo,
146                       const int * const  nbelgeoc, const int * const  nbgaussgeo,
147                       bool shallowCopy=false,
148                       bool ownershipOfValues=false)
149     : InterlacingPolicy(nbelem, dim, nbtypegeo, nbelgeoc, nbgaussgeo)
150   {
151     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
152     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
153     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbtypegeo);
154
155     if(shallowCopy)
156
157       if(ownershipOfValues)
158         _array.setShallowAndOwnership((const ElementType *)values);
159       else
160         _array.set((const ElementType*)values);
161
162     else
163       _array.set(InterlacingPolicy::_arraySize,values);
164
165   };
166
167   // Constructeur de recopie pour un MEDMEM_Array avec les mêmes
168   // paramètres template qu'à la construction
169   inline MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false)
170     :InterlacingPolicy(array,shallowCopy)
171   {
172     if (shallowCopy)
173       this->_array.set(array._array); // Le propriétaire reste le ARRAY initial
174     else
175       this->_array.set(InterlacingPolicy::_arraySize,array._array);
176   }
177
178
179   // L'utilisation d'une copie superficielle pour l'opérateur d'affectation
180   // ne me parait pas être une bonne ideé : Compatibilité ancienne version MEDARRAY?
181   inline MEDMEM_Array<ElementType,InterlacingPolicy,CheckingPolicy> &
182          operator=( const MEDMEM_Array & array) {
183     if ( this == &array) return *this;
184   const char* LOC = "MEDMEM_Array  operator =";
185   BEGIN_OF_MED(LOC);
186     InterlacingPolicy::operator=(array); //Appel des classes de base ?
187
188     this->_array.set(array._array); // Le propriétaire reste le ARRAY initial
189
190     return *this;
191   }
192
193   MED_EN::medModeSwitch getInterlacingType() const {
194     return InterlacingPolicy::getInterlacingType();
195   }
196
197   bool getGaussPresence() const {
198     return InterlacingPolicy::getGaussPresence();
199   }
200
201   ElementType * getPtr() {
202     return  _array;
203   }
204
205   const ElementType * getPtr() const {
206     return  _array;
207   }
208
209   void setPtr(ElementType * values, bool shallowCopy=false,
210               bool ownershipOfValues=false) {
211
212     if(shallowCopy)
213
214       if(ownershipOfValues)
215         _array.setShallowAndOwnership((const ElementType *)values);
216       else
217         _array.set((const ElementType*)values);
218
219     else
220       _array.set(InterlacingPolicy::_arraySize,values);
221   }
222
223   inline const ElementType * getRow(int i) const {
224     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
225     // Empêche l'utilisation de getRow en mode MED_NO_INTERLACE
226     // Ne devrait pas dépendre de la politique check
227     CHECKING_POLICY::checkEquality("MEDMEM_Array (Interlace test)",
228                                    MED_EN::MED_NO_INTERLACE,
229                                    InterlacingPolicy::_interlacing );
230     return &(_array[ InterlacingPolicy::getIndex(i,1) ]);
231
232   }
233
234   void setRow(int i,const ElementType * const value) {
235     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
236     // setRow fonctionne
237     // dans les deux modes d'entrelacement.
238
239     // int index = -1;
240     for (int j =1; j <= InterlacingPolicy::getDim(); j++) {
241       for (int k = 1 ; k <= InterlacingPolicy::getNbGauss(i); k++) {
242         _array[InterlacingPolicy::getIndex(i,j,k)] = value[InterlacingPolicy::getIndex(1,j,k)];
243         //index++;
244         //_array[InterlacingPolicy::getIndex(i,j,k)] = value[index];
245       }
246     }
247   }
248
249   inline const ElementType * getColumn(int j) const {
250     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
251     CHECKING_POLICY::checkEquality("MEDMEM_Array (Interlace test)",
252                                    MED_EN::MED_FULL_INTERLACE, InterlacingPolicy::_interlacing );
253     return &(_array[ InterlacingPolicy::getIndex(1,j) ]);
254   }
255
256   void setColumn(int j, const ElementType * const value) {
257     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
258     // setColumn fonctionne
259     // dans les deux modes d'entrelacement.
260
261     int index = -1;
262     for (int i=1; i <= InterlacingPolicy::getNbElem(); i++) {
263       for (int k = 1 ; k <= InterlacingPolicy::getNbGauss(i); k++) {
264         //_array[InterlacingPolicy::getIndex(i,j,k)] = value[InterlacingPolicy::getIndex(i,1,k)];
265         index++;
266         _array[InterlacingPolicy::getIndex(i,j,k)] = value[index];
267       }
268     }
269   }
270
271
272   inline const ElementType & getIJ(int i, int j) const  {
273     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
274     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
275     return _array[ InterlacingPolicy::getIndex(i,j) ];
276   }
277
278   inline const ElementType & getIJK(int i, int j, int k ) const {
279     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
280     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
281     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGauss(i),k);
282
283     return _array[ InterlacingPolicy::getIndex(i,j,k) ];
284   };
285
286   inline const ElementType & getIJByType(int i, int j, int t) const  {
287     if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
288       throw MEDEXCEPTION(LOCALIZED(STRING("Wrong interlacing type ") << getInterlacingType()));
289     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
290     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
291     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGeoType(),t);
292     if ( InterlacingPolicy::getGaussPresence() )
293       return _array[ ((NoInterlaceByTypeGaussPolicy*)this)->getIndexByType(i,j,t) ];
294     else
295       return _array[ ((NoInterlaceByTypeNoGaussPolicy*)this)->getIndexByType(i,j,t) ];
296   }
297
298   inline const ElementType & getIJKByType(int i, int j, int k, int t) const {
299     if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
300       throw MEDEXCEPTION(LOCALIZED(STRING("Wrong interlacing type ") << getInterlacingType()));
301     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
302     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGeoType(),t);
303     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
304
305     if ( InterlacingPolicy::getGaussPresence() ) {
306         // not compilable on Debian40
307 //       CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",
308 //                             1,((NoInterlaceByTypeGaussPolicy*)this)->getNbGaussByType(t),k);
309       int kmax = ((NoInterlaceByTypeGaussPolicy*)this)->getNbGaussByType(t);
310       if ( k < 1 || k > kmax )
311         throw MEDEXCEPTION(LOCALIZED(STRING("MEDMEM_Array::getIJKByType(), ")
312                                      << " k : " << k << " not in rang [1," << kmax <<"]"));
313       return _array[ ((NoInterlaceByTypeGaussPolicy*)this)->getIndexByType(i,j,k,t) ];
314     }
315     else {
316       CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGauss(i),k);
317       return _array[ ((NoInterlaceByTypeNoGaussPolicy*)this)->getIndexByType(i,j,k,t) ];
318     }
319   };
320
321   inline void setIJ(int i, int j, const ElementType & value) {   //autre signature avec
322     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
323     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
324
325     _array[ InterlacingPolicy::getIndex(i,j) ] = value;                      // retour ElementType & ?
326   };
327
328   inline void setIJByType(int i, int j, int t, const ElementType & value) {   //autre signature avec
329     if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
330       throw MEDEXCEPTION(LOCALIZED(STRING("Wrong interlacing type ") << getInterlacingType()));
331     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
332     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
333     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGeoType(),t);
334
335     if ( InterlacingPolicy::getGaussPresence() )
336       _array[ ((NoInterlaceByTypeGaussPolicy*)this)->getIndexByType(i,j,t) ] = value;
337     else
338       _array[ ((NoInterlaceByTypeNoGaussPolicy*)this)->getIndexByType(i,j,t) ] = value;
339   };
340
341   inline void setIJK(int i, int j, int k, const ElementType & value) {   //autre signature avec
342     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
343     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
344     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGauss(i),k);
345
346     _array[ InterlacingPolicy::getIndex(i,j,k) ] = value;                      // retour ElementType & ?
347   };
348
349   inline void setIJKByType(int i, int j, int k, int t, const ElementType & value) {   //autre signature avec
350     if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
351       throw MEDEXCEPTION(LOCALIZED(STRING("Wrong interlacing type ") << getInterlacingType()));
352     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
353     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
354     CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGeoType(),t);
355
356     if ( InterlacingPolicy::getGaussPresence() ) {
357         // not compilable on Debian40
358 //       CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",
359 //                             1,((NoInterlaceByTypeGaussPolicy*)this)->getNbGaussByType(t),k);
360       int kmax = ((NoInterlaceByTypeGaussPolicy*)this)->getNbGaussByType(t);
361       if ( k < 1 || k > kmax )
362         throw MEDEXCEPTION(LOCALIZED(STRING("MEDMEM_Array::getIJKByType(), ")
363                                      << " k : " << k << " not in rang [1," << kmax <<"]"));
364       _array[ ((NoInterlaceByTypeGaussPolicy*)this)->getIndexByType(i,j,k,t) ] = value;
365     }
366     else {
367       CHECKING_POLICY::checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGauss(i),k);
368       _array[ ((NoInterlaceByTypeNoGaussPolicy*)this)->getIndexByType(i,j,k,t) ] = value;
369     }
370   };
371
372   bool operator == (const MEDMEM_Array & array ) const {
373
374     if ( this == &array ) return true;
375
376     int size = array.getArraySize();
377     if ( size != this->getArraySize() ) return false;
378
379     ARRAY_ELEMENT_TYPE * arrayPtr =
380       const_cast<MEDMEM_Array &>(array).getPtr();
381     for (int i=0; i < size; ++i)
382       if (_array[i] != arrayPtr[i]) return false;
383
384     return true;
385   }
386
387   friend ostream & operator<<(ostream & os, const MEDMEM_Array & array) {
388
389     for (int i=1;i<=array.getNbElem();++i) {
390       for (int j=1; j<=array.getDim();++j)
391         for (int k=1;k<=array.getNbGauss(i);++k)
392           os << "Value [" << i << "," << j << "," << k << "] = " << array.getIJK(i,j,k) << ", ";
393       os << endl;
394     }
395     return os;
396   }
397
398 private:
399
400   PointerOf<ElementType> _array;
401 };
402
403 } //END NAMESPACE
404 #endif