]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/MEDLoader/MEDFileField.txx
Salome HOME
Biking along the template road
[tools/medcoupling.git] / src / MEDLoader / MEDFileField.txx
1 // Copyright (C) 2007-2016  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 __MEDFILEFIELD_TXX__
22 #define __MEDFILEFIELD_TXX__
23
24 #include "MEDFileField.hxx"
25 #include "MEDCouplingTraits.hxx"
26
27 namespace MEDCoupling
28 {
29   template<class T>
30   void MEDFileField1TSTemplateWithoutSDA<T>::setArray(DataArray *arr)
31   {
32     if(!arr)
33       {
34         _nb_of_tuples_to_be_allocated=-1;
35         _arr=0;
36         return ;
37       }
38     typename Traits<T>::ArrayType *arrC=dynamic_cast<typename Traits<T>::ArrayType *>(arr);
39     if(!arrC)
40       throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::setArray : the input not null array is not of type DataArrayDouble !");
41     else
42       _nb_of_tuples_to_be_allocated=-3;
43     arrC->incrRef();
44     _arr=arrC;
45   }
46   
47   /*!
48    * Returns a pointer to the underground DataArrayTemplate<T>  instance. So the
49    * caller should not decrRef() it. This method allows for a direct access to the field
50    * values. This method is quite unusable if there is more than a nodal field or a cell
51    * field on single geometric cell type. 
52    *  \return DataArrayTemplate<T> * - the pointer to the field values array.
53    */
54   template<class T>
55   DataArray *MEDFileField1TSTemplateWithoutSDA<T>::getOrCreateAndGetArray()
56   {
57     return getOrCreateAndGetArrayTemplate();
58   }
59   
60   template<class T>
61   const DataArray *MEDFileField1TSTemplateWithoutSDA<T>::getOrCreateAndGetArray() const
62   {
63     return getOrCreateAndGetArrayTemplate();
64   }
65   
66   template<class T>
67   DataArray *MEDFileField1TSTemplateWithoutSDA<T>::createNewEmptyDataArrayInstance() const
68   {
69     return Traits<T>::ArrayType::New();
70   }
71   
72   template<class T>
73   typename Traits<T>::ArrayType const *MEDFileField1TSTemplateWithoutSDA<T>::getOrCreateAndGetArrayTemplate() const
74   {
75     typename Traits<T>::ArrayType const *ret(_arr);
76     if(ret)
77       return ret;
78     (const_cast< MEDFileField1TSTemplateWithoutSDA<T> *>(this))->_arr=Traits<T>::ArrayType::New();
79     return _arr;
80   }
81   
82   template<class T>
83   typename Traits<T>::ArrayType *MEDFileField1TSTemplateWithoutSDA<T>::getOrCreateAndGetArrayTemplate()
84   {
85     typename Traits<T>::ArrayType *ret(_arr);
86     if(ret)
87       return ret;
88     _arr=Traits<T>::ArrayType::New();
89     return _arr;
90   }
91
92   /*!
93    * Returns a pointer to the underground DataArrayTemplate<T> instance. So the
94    * caller should not decrRef() it. This method allows for a direct access to the field
95    * values. This method is quite unusable if there is more than a nodal field or a cell
96    * field on single geometric cell type. 
97    *  \return DataArrayTemplate<T> * - the pointer to the field values array.
98    */
99   template<class T>
100   typename Traits<T>::ArrayType *MEDFileField1TSTemplateWithoutSDA<T>::getUndergroundDataArrayTemplate() const
101   {
102     typename Traits<T>::ArrayType const *ret(_arr);
103     if(ret)
104       return const_cast<typename Traits<T>::ArrayType *>(ret);
105     else
106       return 0;
107   }
108   
109   /*!
110    * Returns a pointer to the underground DataArrayDouble instance and a
111    * sequence describing parameters of a support of each part of \a this field. The
112    * caller should not decrRef() the returned DataArrayDouble. This method allows for a
113    * direct access to the field values. This method is intended for the field lying on one
114    * mesh only.
115    *  \param [in,out] entries - the sequence describing parameters of a support of each
116    *         part of \a this field. Each item of this sequence consists of two parts. The
117    *         first part describes a type of mesh entity and an id of discretization of a
118    *         current field part. The second part describes a range of values [begin,end)
119    *         within the returned array relating to the current field part.
120    *  \return DataArrayDouble * - the pointer to the field values array.
121    *  \throw If the number of underlying meshes is not equal to 1.
122    *  \throw If no field values are available.
123    *  \sa getUndergroundDataArrayTemplate()
124    */
125   template<class T>
126   typename Traits<T>::ArrayType *MEDFileField1TSTemplateWithoutSDA<T>::getUndergroundDataArrayTemplateExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const
127   {
128     if(this->_field_per_mesh.size()!=1)
129       throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !");
130     if(this->_field_per_mesh[0]==0)
131       throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !");
132     this->_field_per_mesh[0]->getUndergroundDataArrayExt(entries);
133     return getUndergroundDataArrayTemplate();
134   }
135   
136   /*!
137    * Returns a pointer to the underground DataArrayDouble instance. So the
138    * caller should not decrRef() it. This method allows for a direct access to the field
139    * values. This method is quite unusable if there is more than a nodal field or a cell
140    * field on single geometric cell type. 
141    *  \return DataArrayDouble * - the pointer to the field values array.
142    */
143   template<class T>
144   DataArray *MEDFileField1TSTemplateWithoutSDA<T>::getUndergroundDataArray() const
145   {
146     return getUndergroundDataArrayTemplate();
147   }
148   
149   template<class T>
150   void MEDFileField1TSTemplateWithoutSDA<T>::aggregate(const std::vector<typename MLFieldTraits<T>::F1TSWSDAType const *>& f1tss, const std::vector< std::vector< std::pair<int,int> > >& dts)
151   {
152     if(f1tss.empty())
153       throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : empty vector !");
154     std::size_t sz(f1tss.size()),ii(0);
155     std::vector<const MEDFileFieldPerMesh *> pms;
156     std::vector<const DataArray *> das(sz);
157     for(typename std::vector<typename MLFieldTraits<T>::F1TSWSDAType const *>::const_iterator it=f1tss.begin();it!=f1tss.end();it++,ii++)
158       {
159         if(!*it)
160           throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : presence of null pointer in input vector !");
161         if((*it)->_field_per_mesh.empty())
162           throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : no info !");
163         const typename Traits<T>::ArrayType *arr((*it)->getUndergroundDataArrayTemplate());
164         if(!arr)
165           throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : presence of null array !");
166         das[ii]=arr;
167         pms.push_back((*it)->_field_per_mesh[0]);
168       }
169     typename MLFieldTraits<T>::F1TSWSDAType const *refPt(f1tss[0]);
170     setName(refPt->getName());
171     
172     const DataArray *arr(refPt->getUndergroundDataArray());
173     int nbCompo(arr->getNumberOfComponents());
174     for(typename std::vector<typename MLFieldTraits<T>::F1TSWSDAType const *>::const_iterator it=f1tss.begin();it!=f1tss.end();it++)
175       {
176         const typename Traits<T>::ArrayType *myArr((*it)->getUndergroundDataArrayTemplate());
177         if(myArr->getNumberOfComponents()!=nbCompo)
178           throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : arrays must have same number of components !");
179       }
180     std::vector<std::pair< int, std::pair<int,int> > > extractInfo;
181     int start(0);
182     MCAuto<MEDFileFieldPerMesh> fpm(MEDFileFieldPerMesh::Aggregate(start,pms,dts,this,extractInfo));
183     _field_per_mesh.push_back(fpm);
184     int iteration,order;
185     double tv(f1tss[0]->getTime(iteration,order));
186     _iteration=iteration; _order=order; _dt=tv;
187     _arr=Traits<T>::ArrayType::New();
188     _arr->alloc(start,nbCompo); _arr->copyStringInfoFrom(*arr);
189     start=0;
190     for(std::vector<std::pair< int, std::pair<int,int> > >::const_iterator it=extractInfo.begin();it!=extractInfo.end();it++)
191       {
192         const DataArray *zeArr(das[(*it).first]);
193         _arr->setContigPartOfSelectedValuesSlice(start,zeArr,(*it).second.first,(*it).second.second,1);
194         start+=(*it).second.second-(*it).second.first;
195       }
196   }
197
198   template<class T>
199   MEDFileTemplateField1TS<T>::MEDFileTemplateField1TS()
200   {
201     _content=new typename MLFieldTraits<T>::F1TSWSDAType;
202   }
203
204   /*!
205    * Returns a new empty instance of MEDFileField1TS.
206    *  \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller
207    *          is to delete this field using decrRef() as it is no more needed.
208    */
209   template<class T>
210   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New()
211   {
212     MCAuto<typename MLFieldTraits<T>::F1TSType> ret(new typename MLFieldTraits<T>::F1TSType);
213     ret->contentNotNull();
214     return ret.retn();
215   }
216
217   /*!
218    * Returns a new instance of MEDFileField1TS holding data of the first time step of 
219    * the first field that has been read from a specified MED file.
220    *  \param [in] fileName - the name of the MED file to read.
221    *  \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller
222    *          is to delete this field using decrRef() as it is no more needed.
223    *  \throw If reading the file fails.
224    */
225   template<class T>
226   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(const std::string& fileName, bool loadAll)
227   {
228     MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
229     return New(fid,loadAll);
230   }
231   
232   template<class T>
233   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(med_idt fid, bool loadAll)
234   {
235     MCAuto<typename MLFieldTraits<T>::F1TSType> ret(new typename MLFieldTraits<T>::F1TSType(fid,loadAll,0));
236     ret->contentNotNull();
237     return ret.retn();
238   }
239
240   /*!
241    * Returns a new instance of MEDFileField1TS holding data of the first time step of 
242    * a given field that has been read from a specified MED file.
243    *  \param [in] fileName - the name of the MED file to read.
244    *  \param [in] fieldName - the name of the field to read.
245    *  \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller
246    *          is to delete this field using decrRef() as it is no more needed.
247    *  \throw If reading the file fails.
248    *  \throw If there is no field named \a fieldName in the file.
249    */
250   template<class T>
251   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(const std::string& fileName, const std::string& fieldName, bool loadAll)
252   {
253     MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
254     return New(fid,fieldName,loadAll);
255   }
256
257   template<class T>
258   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(med_idt fid, const std::string& fieldName, bool loadAll)
259   {
260     MCAuto<typename MLFieldTraits<T>::F1TSType> ret(new typename MLFieldTraits<T>::F1TSType(fid,fieldName,loadAll,0));
261     ret->contentNotNull();
262     return ret.retn();
263   }
264
265   /*!
266    * Returns a new instance of MEDFileField1TS holding data of a given time step of 
267    * a given field that has been read from a specified MED file.
268    *  \param [in] fileName - the name of the MED file to read.
269    *  \param [in] fieldName - the name of the field to read.
270    *  \param [in] iteration - the iteration number of a required time step.
271    *  \param [in] order - the iteration order number of required time step.
272    *  \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller
273    *          is to delete this field using decrRef() as it is no more needed.
274    *  \throw If reading the file fails.
275    *  \throw If there is no field named \a fieldName in the file.
276    *  \throw If the required time step is missing from the file.
277    */
278   template<class T>
279   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll)
280   {
281     MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
282     return New(fid,fieldName,iteration,order,loadAll);
283   }
284   
285   template<class T>
286   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(med_idt fid, const std::string& fieldName, int iteration, int order, bool loadAll)
287   {
288     MCAuto<typename MLFieldTraits<T>::F1TSType> ret(new typename MLFieldTraits<T>::F1TSType(fid,fieldName,iteration,order,loadAll,0));
289     ret->contentNotNull();
290     return ret.retn();
291   }
292
293   /*!
294    * Returns a new instance of MEDFileField1TS. If \a shallowCopyOfContent is true the content of \a other is shallow copied.
295    * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this.
296    *
297    * Returns a new instance of MEDFileField1TS holding either a shallow copy
298    * of a given MEDFileField1TSWithoutSDA ( \a other ) or \a other itself.
299    * \warning this is a shallow copy constructor
300    *  \param [in] other - a MEDFileField1TSWithoutSDA to copy.
301    *  \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created.
302    *  \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller
303    *          is to delete this field using decrRef() as it is no more needed.
304    */
305   template<class T>
306   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(const typename MLFieldTraits<T>::F1TSWSDAType& other, bool shallowCopyOfContent)
307   {
308     MCAuto<typename MLFieldTraits<T>::F1TSType> ret(new typename MLFieldTraits<T>::F1TSType(other,shallowCopyOfContent));
309     ret->contentNotNull();
310     return ret.retn();
311   }
312   
313   template<class T>
314   const typename MLFieldTraits<T>::F1TSWSDAType *MEDFileTemplateField1TS<T>::contentNotNull() const
315   {
316     const MEDFileAnyTypeField1TSWithoutSDA *pt(_content);
317     if(!pt)
318       throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS<T>::contentNotNull : the content pointer is null !");
319     const typename MLFieldTraits<T>::F1TSWSDAType *ret(dynamic_cast<const typename MLFieldTraits<T>::F1TSWSDAType *>(pt));
320     if(!ret)
321       {
322         std::ostringstream oss; oss << "MEDFileTemplateField1TS<T>::contentNotNull : the content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type " << MLFieldTraits<T>::F1TSWSDAType::TYPE_STR;
323         throw INTERP_KERNEL::Exception(oss.str());
324       }
325     return ret;
326   }
327   
328   template<class T>
329   typename MLFieldTraits<T>::F1TSWSDAType *MEDFileTemplateField1TS<T>::contentNotNull()
330   {
331     MEDFileAnyTypeField1TSWithoutSDA *pt(_content);
332     if(!pt)
333       throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS<T>::contentNotNull : the non const content pointer is null !");
334     typename MLFieldTraits<T>::F1TSWSDAType *ret(dynamic_cast<typename MLFieldTraits<T>::F1TSWSDAType *>(pt));
335     if(!ret)
336       {
337         std::ostringstream oss; oss << "MEDFileTemplateField1TS<T>::contentNotNull : the non const content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type " << MLFieldTraits<T>::F1TSWSDAType::TYPE_STR;
338         throw INTERP_KERNEL::Exception(oss.str());
339       }
340     return ret;
341   }
342   
343   template<class T>
344   typename Traits<T>::ArrayType *MEDFileTemplateField1TS<T>::ReturnSafelyTypedDataArray(MCAuto<DataArray>& arr)
345   {
346     if(arr.isNull())
347       throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyTypedDataArray : no array !");
348     typename Traits<T>::ArrayType *arrOutC(dynamic_cast<typename Traits<T>::ArrayType *>((DataArray*)arr));
349     if(!arrOutC)
350       throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyTypedDataArray : mismatch between dataArrays type and MEDFileField1TS ! Expected double !");
351     arrOutC->incrRef();
352     return arrOutC;
353   }
354
355   /*!
356    * Returns values and a profile of the field of a given type lying on a given support.
357    * For more info, see \ref AdvMEDLoaderAPIFieldRW
358    *  \param [in] type - a spatial discretization of the field.
359    *  \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities.
360    *  \param [in] mesh - the supporting mesh.
361    *  \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the
362    *          field of interest lies on. If the field lies on all entities of the given
363    *          dimension, all ids in \a pfl are zero. The caller is to delete this array
364    *          using decrRef() as it is no more needed.  
365    *  \return DataArrayInt * - a new instance of DataArrayInt holding values of the
366    *          field. The caller is to delete this array using decrRef() as it is no more needed.
367    *  \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh.
368    *  \throw If no field of \a this is lying on \a mesh.
369    *  \throw If no field values of the given \a type or given \a meshDimRelToMax are available.
370    */
371   template<class T>
372   typename Traits<T>::ArrayType *MEDFileTemplateField1TS<T>::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const
373   {
374     MCAuto<DataArray> arr(contentNotNull()->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNull()));
375     return ReturnSafelyTypedDataArray(arr);
376   }
377
378   template<class T>
379   typename Traits<T>::ArrayType *MEDFileTemplateField1TS<T>::getUndergroundDataArray() const
380   {
381     return contentNotNull()->getUndergroundDataArrayTemplate();
382   }
383   
384   template<class T>
385   typename Traits<T>::ArrayType *MEDFileTemplateField1TS<T>::getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const
386   {
387     return contentNotNull()->getUndergroundDataArrayTemplateExt(entries);
388   }
389 }
390
391 #endif