Salome HOME
stash
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingAMRAttribute.cxx
1 // Copyright (C) 2007-2014  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
20
21 #include "MEDCouplingAMRAttribute.hxx"
22 #include "MEDCouplingMemArray.hxx"
23
24 using namespace ParaMEDMEM;
25
26 DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames)
27 {
28   return new DataArrayDoubleCollection(fieldNames);
29 }
30
31 void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
32 {
33   std::size_t sz(_arrs.size());
34   for(std::size_t i=0;i<sz;i++)
35     _arrs[i]->reAlloc(nbOfTuples);
36 }
37
38 void DataArrayDoubleCollection::dellocTuples()
39 {
40   std::size_t sz(_arrs.size());
41   for(std::size_t i=0;i<sz;i++)
42     _arrs[i]->reAlloc(0);
43 }
44
45 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
46 {
47   std::size_t sz(_arrs.size());
48   if(sz!=compNames.size())
49     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !");
50   for(std::size_t i=0;i<sz;i++)
51     {
52       const std::vector<std::string>& names(compNames[i]);
53       _arrs[i]->setInfoOnComponents(names);
54     }
55 }
56
57 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
58 {
59   std::size_t sz(fieldNames.size());
60   std::vector<std::string> names(sz);
61   for(std::size_t i=0;i<sz;i++)
62     {
63       const std::pair<std::string,int>& info(fieldNames[i]);
64       _arrs[i]=DataArrayDouble::New();
65       _arrs[i]->alloc(0,info.second);
66       _arrs[i]->setName(info.first);
67       names[i]=info.second;
68     }
69   CheckDiscriminantNames(names);
70 }
71
72 std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
73 {
74   std::size_t ret(sizeof(DataArrayDoubleCollection));
75   ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>);
76   return ret;
77 }
78
79 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
80 {
81   std::vector<const BigMemoryObject *> ret;
82   for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
83     {
84       const DataArrayDouble *pt(*it);
85       if(pt)
86         ret.push_back(pt);
87     }
88   return ret;
89 }
90
91 void DataArrayDoubleCollection::updateTime() const
92 {
93   for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
94     {
95       const DataArrayDouble *pt(*it);
96       if(pt)
97         updateTimeWith(*pt);
98     }
99 }
100
101 void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names)
102 {
103   std::set<std::string> s(names.begin(),names.end());
104   if(s.size()!=names.size())
105     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
106 }
107
108 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
109 {
110   return new MEDCouplingGridCollection(ms,fieldNames);
111 }
112
113 void MEDCouplingGridCollection::alloc(int ghostLev)
114 {
115   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
116     {
117       int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev));
118       DataArrayDoubleCollection *dadc((*it).second);
119       if(dadc)
120         dadc->allocTuples(nbTuples);
121       else
122         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !");
123     }
124 }
125
126 void MEDCouplingGridCollection::dealloc()
127 {
128   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
129     {
130       DataArrayDoubleCollection *dadc((*it).second);
131       if(dadc)
132         dadc->dellocTuples();
133       else
134         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !");
135     }
136 }
137
138 void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
139 {
140   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
141     (*it).second->spillInfoOnComponents(compNames);
142 }
143
144 MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size())
145 {
146   std::size_t sz(ms.size());
147   for(std::size_t i=0;i<sz;i++)
148     {
149       if(!ms[i])
150         throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !");
151       _map_of_dadc[i].first=ms[i];
152       _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames);
153     }
154 }
155
156 std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const
157 {
158   std::size_t ret(sizeof(MEDCouplingGridCollection));
159   ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >);
160   return ret;
161 }
162
163 std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildren() const
164 {
165   std::vector<const BigMemoryObject *> ret;
166   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
167     {
168       const DataArrayDoubleCollection *col((*it).second);
169       if(col)
170         ret.push_back(col);
171     }
172   return ret;
173 }
174
175 void MEDCouplingGridCollection::updateTime() const
176 {
177   for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
178     {
179       const MEDCouplingCartesianAMRMeshGen *a((*it).first);
180       if(a)
181         updateTimeWith(*a);
182       const DataArrayDoubleCollection *b((*it).second);
183       if(b)
184         updateTimeWith(*b);
185     }
186 }
187
188 /*!
189  * This method creates, attach to a main AMR mesh \a gf ( called god father :-) ) and returns a data linked to \a gf ready for the computation.
190  */
191 MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames)
192 {
193   return new MEDCouplingAMRAttribute(gf,fieldNames);
194 }
195
196 /*!
197  * Assign the info on components for all DataArrayDouble instance recursively stored in \a this.
198  * The first dim of input \a compNames is the field id in the same order than those implicitely specified in \a fieldNames parameter of MEDCouplingAMRAttribute::New.
199  * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has
200  * to perfectly fit with those specified in MEDCouplingAMRAttribute::New.
201  */
202 void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
203 {
204   _tlc.checkConst();
205   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
206     (*it)->spillInfoOnComponents(compNames);
207 }
208
209 /*!
210  * This method allocates all DataArrayDouble instances stored recursively in \a this.
211  *
212  * \param [in] ghostLev - The size of ghost zone.
213  *
214  * \sa dealloc
215  */
216 void MEDCouplingAMRAttribute::alloc(int ghostLev)
217 {
218   _tlc.resetState();
219   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
220     {
221       MEDCouplingGridCollection *elt(*it);
222       if(elt)
223         elt->alloc(ghostLev);
224       else
225         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !");
226     }
227 }
228
229 /*!
230  * This method deallocates all DataArrayDouble instances stored recursively in \a this.
231  * \sa alloc
232  */
233 void MEDCouplingAMRAttribute::dealloc()
234 {
235   _tlc.checkConst();
236   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
237     {
238       MEDCouplingGridCollection *elt(*it);
239       if(elt)
240         elt->dealloc();
241       else
242         throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !");
243     }
244 }
245
246 bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf)
247 {
248   bool ret(MEDCouplingDataForGodFather::changeGodFather(gf));
249   return ret;
250 }
251
252 std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const
253 {
254   std::size_t ret(sizeof(MEDCouplingAMRAttribute));
255   ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>);
256   return ret;
257 }
258
259 std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildren() const
260 {
261   std::vector<const BigMemoryObject *> ret;
262   for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++)
263     {
264       const MEDCouplingGridCollection *elt(*it);
265       if(elt)
266         ret.push_back(elt);
267     }
268   return ret;
269 }
270
271 void MEDCouplingAMRAttribute::updateTime() const
272 {//tony
273 }
274
275 MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames):MEDCouplingDataForGodFather(gf)
276 {
277   //gf non empty, checked by constructor
278   int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()+1);
279   _levs.resize(maxLev+1);
280   for(int i=0;i<maxLev;i++)
281     {
282       std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i));
283       std::size_t sz(patches.size());
284       std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size());
285       for(std::size_t j=0;j<sz;j++)
286         patchesSafe[j]=patches[j];
287       std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz);
288       for(std::size_t j=0;j<sz;j++)
289         {
290           ms[j]=patches[j]->getMesh();
291         }
292       _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames);
293     }
294 }