Salome HOME
639bc1ab98f861919110126985714bee6e6562d2
[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. So the
111    * caller should not decrRef() it. This method allows for a direct access to the field
112    * values. This method is quite unusable if there is more than a nodal field or a cell
113    * field on single geometric cell type. 
114    *  \return DataArrayDouble * - the pointer to the field values array.
115    */
116   template<class T>
117   DataArray *MEDFileField1TSTemplateWithoutSDA<T>::getUndergroundDataArray() const
118   {
119     return getUndergroundDataArrayTemplate();
120   }
121   
122   template<class T>
123   void MEDFileField1TSTemplateWithoutSDA<T>::aggregate(const std::vector<typename MLFieldTraits<T>::F1TSWSDAType const *>& f1tss, const std::vector< std::vector< std::pair<int,int> > >& dts)
124   {
125     if(f1tss.empty())
126       throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : empty vector !");
127     std::size_t sz(f1tss.size()),ii(0);
128     std::vector<const MEDFileFieldPerMesh *> pms;
129     std::vector<const DataArray *> das(sz);
130     for(typename std::vector<typename MLFieldTraits<T>::F1TSWSDAType const *>::const_iterator it=f1tss.begin();it!=f1tss.end();it++,ii++)
131       {
132         if(!*it)
133           throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : presence of null pointer in input vector !");
134         if((*it)->_field_per_mesh.empty())
135           throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : no info !");
136         const typename Traits<T>::ArrayType *arr((*it)->getUndergroundDataArrayTemplate());
137         if(!arr)
138           throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : presence of null array !");
139         das[ii]=arr;
140         pms.push_back((*it)->_field_per_mesh[0]);
141       }
142     typename MLFieldTraits<T>::F1TSWSDAType const *refPt(f1tss[0]);
143     setName(refPt->getName());
144     
145     const DataArray *arr(refPt->getUndergroundDataArray());
146     int nbCompo(arr->getNumberOfComponents());
147     for(typename std::vector<typename MLFieldTraits<T>::F1TSWSDAType const *>::const_iterator it=f1tss.begin();it!=f1tss.end();it++)
148       {
149         const typename Traits<T>::ArrayType *myArr((*it)->getUndergroundDataArrayTemplate());
150         if(myArr->getNumberOfComponents()!=nbCompo)
151           throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : arrays must have same number of components !");
152       }
153     std::vector<std::pair< int, std::pair<int,int> > > extractInfo;
154     int start(0);
155     MCAuto<MEDFileFieldPerMesh> fpm(MEDFileFieldPerMesh::Aggregate(start,pms,dts,this,extractInfo));
156     _field_per_mesh.push_back(fpm);
157     int iteration,order;
158     double tv(f1tss[0]->getTime(iteration,order));
159     _iteration=iteration; _order=order; _dt=tv;
160     _arr=Traits<T>::ArrayType::New();
161     _arr->alloc(start,nbCompo); _arr->copyStringInfoFrom(*arr);
162     start=0;
163     for(std::vector<std::pair< int, std::pair<int,int> > >::const_iterator it=extractInfo.begin();it!=extractInfo.end();it++)
164       {
165         const DataArray *zeArr(das[(*it).first]);
166         _arr->setContigPartOfSelectedValuesSlice(start,zeArr,(*it).second.first,(*it).second.second,1);
167         start+=(*it).second.second-(*it).second.first;
168       }
169   }
170
171   template<class T>
172   MEDFileTemplateField1TS<T>::MEDFileTemplateField1TS()
173   {
174     _content=new typename MLFieldTraits<T>::F1TSWSDAType;
175   }
176
177   /*!
178    * Returns a new empty instance of MEDFileField1TS.
179    *  \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller
180    *          is to delete this field using decrRef() as it is no more needed.
181    */
182   template<class T>
183   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New()
184   {
185     MCAuto<typename MLFieldTraits<T>::F1TSType> ret(new typename MLFieldTraits<T>::F1TSType);
186     ret->contentNotNull();
187     return ret.retn();
188   }
189
190   /*!
191    * Returns a new instance of MEDFileField1TS holding data of the first time step of 
192    * the first field that has been read from a specified MED file.
193    *  \param [in] fileName - the name of the MED file to read.
194    *  \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller
195    *          is to delete this field using decrRef() as it is no more needed.
196    *  \throw If reading the file fails.
197    */
198   template<class T>
199   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(const std::string& fileName, bool loadAll)
200   {
201     MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
202     return New(fid,loadAll);
203   }
204   
205   template<class T>
206   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(med_idt fid, bool loadAll)
207   {
208     MCAuto<typename MLFieldTraits<T>::F1TSType> ret(new typename MLFieldTraits<T>::F1TSType(fid,loadAll,0));
209     ret->contentNotNull();
210     return ret.retn();
211   }
212
213   /*!
214    * Returns a new instance of MEDFileField1TS holding data of the first time step of 
215    * a given field that has been read from a specified MED file.
216    *  \param [in] fileName - the name of the MED file to read.
217    *  \param [in] fieldName - the name of the field to read.
218    *  \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller
219    *          is to delete this field using decrRef() as it is no more needed.
220    *  \throw If reading the file fails.
221    *  \throw If there is no field named \a fieldName in the file.
222    */
223   template<class T>
224   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(const std::string& fileName, const std::string& fieldName, bool loadAll)
225   {
226     MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
227     return New(fid,fieldName,loadAll);
228   }
229
230   template<class T>
231   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(med_idt fid, const std::string& fieldName, bool loadAll)
232   {
233     MCAuto<typename MLFieldTraits<T>::F1TSType> ret(new typename MLFieldTraits<T>::F1TSType(fid,fieldName,loadAll,0));
234     ret->contentNotNull();
235     return ret.retn();
236   }
237
238   /*!
239    * Returns a new instance of MEDFileField1TS holding data of a given time step of 
240    * a given field that has been read from a specified MED file.
241    *  \param [in] fileName - the name of the MED file to read.
242    *  \param [in] fieldName - the name of the field to read.
243    *  \param [in] iteration - the iteration number of a required time step.
244    *  \param [in] order - the iteration order number of required time step.
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    *  \throw If the required time step is missing from the file.
250    */
251   template<class T>
252   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll)
253   {
254     MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
255     return New(fid,fieldName,iteration,order,loadAll);
256   }
257   
258   template<class T>
259   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(med_idt fid, const std::string& fieldName, int iteration, int order, bool loadAll)
260   {
261     MCAuto<typename MLFieldTraits<T>::F1TSType> ret(new typename MLFieldTraits<T>::F1TSType(fid,fieldName,iteration,order,loadAll,0));
262     ret->contentNotNull();
263     return ret.retn();
264   }
265
266   /*!
267    * Returns a new instance of MEDFileField1TS. If \a shallowCopyOfContent is true the content of \a other is shallow copied.
268    * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this.
269    *
270    * Returns a new instance of MEDFileField1TS holding either a shallow copy
271    * of a given MEDFileField1TSWithoutSDA ( \a other ) or \a other itself.
272    * \warning this is a shallow copy constructor
273    *  \param [in] other - a MEDFileField1TSWithoutSDA to copy.
274    *  \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created.
275    *  \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller
276    *          is to delete this field using decrRef() as it is no more needed.
277    */
278   template<class T>
279   typename MLFieldTraits<T>::F1TSType *MEDFileTemplateField1TS<T>::New(const typename MLFieldTraits<T>::F1TSWSDAType& other, bool shallowCopyOfContent)
280   {
281     MCAuto<typename MLFieldTraits<T>::F1TSType> ret(new typename MLFieldTraits<T>::F1TSType(other,shallowCopyOfContent));
282     ret->contentNotNull();
283     return ret.retn();
284   }
285   
286   template<class T>
287   const typename MLFieldTraits<T>::F1TSWSDAType *MEDFileTemplateField1TS<T>::contentNotNull() const
288   {
289     const MEDFileAnyTypeField1TSWithoutSDA *pt(_content);
290     if(!pt)
291       throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS<T>::contentNotNull : the content pointer is null !");
292     const typename MLFieldTraits<T>::F1TSWSDAType *ret(dynamic_cast<const typename MLFieldTraits<T>::F1TSWSDAType *>(pt));
293     if(!ret)
294       throw INTERP_KERNEL::Exception("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 FLOAT64 !");
295     return ret;
296   }
297   
298   template<class T>
299   typename MLFieldTraits<T>::F1TSWSDAType *MEDFileTemplateField1TS<T>::contentNotNull()
300   {
301     MEDFileAnyTypeField1TSWithoutSDA *pt(_content);
302     if(!pt)
303       throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS<T>::contentNotNull : the non const content pointer is null !");
304     typename MLFieldTraits<T>::F1TSWSDAType *ret(dynamic_cast<typename MLFieldTraits<T>::F1TSWSDAType *>(pt));
305     if(!ret)
306       throw INTERP_KERNEL::Exception("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 FLOAT64 !");
307     return ret;
308   }
309 }
310
311 #endif