1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCouplingMultiFields.hxx"
22 #include "MEDCouplingFieldTemplate.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24 #include "MEDCouplingMesh.hxx"
25 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
30 using namespace ParaMEDMEM;
32 MEDCouplingMultiFields *MEDCouplingMultiFields::New(const std::vector<MEDCouplingFieldDouble *>& fs)
34 return new MEDCouplingMultiFields(fs);
37 MEDCouplingMultiFields *MEDCouplingMultiFields::New()
39 return new MEDCouplingMultiFields;
42 MEDCouplingMultiFields *MEDCouplingMultiFields::deepCpy() const
44 return new MEDCouplingMultiFields(*this);
47 bool MEDCouplingMultiFields::isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const
49 std::size_t sz=_fs.size();
50 if(sz!=other->_fs.size())
52 for(std::size_t i=0;i<sz;i++)
54 const MEDCouplingFieldDouble *f1=_fs[i];
55 const MEDCouplingFieldDouble *f2=other->_fs[i];
60 if(!_fs[i]->isEqual(other->_fs[i],meshPrec,valsPrec))
64 std::vector<int> refs1,refs2;
65 std::vector<MEDCouplingMesh *> ms1=getDifferentMeshes(refs1);
66 std::vector<MEDCouplingMesh *> ms2=other->getDifferentMeshes(refs2);
67 if(ms1.size()!=ms2.size())
71 std::vector< std::vector<int> > refs3,refs4;
72 std::vector<DataArrayDouble *> das1=getDifferentArrays(refs3);
73 std::vector<DataArrayDouble *> das2=getDifferentArrays(refs4);
74 if(das1.size()!=das2.size())
81 std::string MEDCouplingMultiFields::getName() const
83 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();
84 for(;it!=_fs.end();it++)
85 if((const MEDCouplingFieldDouble *)(*it))
86 return (*it)->getName();
90 std::string MEDCouplingMultiFields::getDescription() const
92 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();
93 for(;it!=_fs.end();it++)
94 if((const MEDCouplingFieldDouble *)(*it))
95 return (*it)->getDescription();
99 std::string MEDCouplingMultiFields::getTimeUnit() const
101 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();
102 for(;it!=_fs.end();it++)
103 if((const MEDCouplingFieldDouble *)(*it))
104 return (*it)->getTimeUnit();
105 return std::string();
108 double MEDCouplingMultiFields::getTimeResolution() const
110 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();
111 for(;it!=_fs.end();it++)
112 if((const MEDCouplingFieldDouble *)(*it))
113 return (*it)->getTimeTolerance();
114 throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::getTimeResolution : no not null field !");
117 std::string MEDCouplingMultiFields::simpleRepr() const
119 std::ostringstream ret;
120 ret << "MEDCouplingMultiFields with name : \"" << getName() << "\"\n";
121 ret << "Description of MEDCouplingMultiFields is : \"" << getDescription() << "\"\n";
122 ret << "Number of discretization : " << _fs.size() << "\n";
123 ret << "Number of different meshes : ";
124 std::vector<MEDCouplingMesh *> ms;
125 std::vector<int> refms;
128 ms=getDifferentMeshes(refms);
129 ret << ms.size() << "\n";
131 catch(INTERP_KERNEL::Exception& /*e*/)
132 { ret << "Current instance is INVALID !\n"; }
136 std::string MEDCouplingMultiFields::advancedRepr() const
141 bool MEDCouplingMultiFields::isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const
143 std::size_t sz=_fs.size();
144 if(sz!=other->_fs.size())
146 for(std::size_t i=0;i<sz;i++)
147 if(!_fs[i]->isEqualWithoutConsideringStr(other->_fs[i],meshPrec,valsPrec))
152 const MEDCouplingFieldDouble *MEDCouplingMultiFields::getFieldWithId(int id) const
154 if(id>=(int)_fs.size() || id < 0)
155 throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::getFieldWithId : invalid id outside boundaries !");
159 std::vector<const MEDCouplingFieldDouble *> MEDCouplingMultiFields::getFields() const
161 std::vector<const MEDCouplingFieldDouble *> ret(_fs.size());
162 std::copy(_fs.begin(),_fs.end(),ret.begin());
166 int MEDCouplingMultiFields::getNumberOfFields() const
168 return (int)_fs.size();
171 const MEDCouplingFieldDouble *MEDCouplingMultiFields::getFieldAtPos(int id) const
173 if(id<0 || id>=(int)_fs.size())
175 std::ostringstream oss; oss << "MEDCouplingMultiFields::getFieldAtPos : Invalid given pos : should be >=0 and < " << _fs.size() << " !";
176 throw INTERP_KERNEL::Exception(oss.str().c_str());
181 void MEDCouplingMultiFields::updateTime() const
183 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();
184 for(;it!=_fs.end();it++)
185 if((const MEDCouplingFieldDouble *)(*it))
188 for(;it!=_fs.end();it++)
189 if((const MEDCouplingFieldDouble *)(*it))
190 updateTimeWith(*(*it));
193 std::size_t MEDCouplingMultiFields::getHeapMemorySizeWithoutChildren() const
198 std::vector<const BigMemoryObject *> MEDCouplingMultiFields::getDirectChildrenWithNull() const
200 std::vector<const BigMemoryObject *> ret;
201 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();it!=_fs.end();it++)
202 ret.push_back((const MEDCouplingFieldDouble *)*it);
206 std::vector<MEDCouplingMesh *> MEDCouplingMultiFields::getMeshes() const
208 std::vector<MEDCouplingMesh *> ms;
209 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();it!=_fs.end();it++)
211 const MEDCouplingMesh *m=0;
212 if((const MEDCouplingFieldDouble *)(*it))
214 ms.push_back(const_cast<MEDCouplingMesh *>(m));
219 std::vector<MEDCouplingMesh *> MEDCouplingMultiFields::getDifferentMeshes(std::vector<int>& refs) const
221 refs.resize(_fs.size());
222 std::vector<MEDCouplingMesh *> ms;
224 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();it!=_fs.end();it++,id++)
226 const MEDCouplingMesh *m=0;
227 if((const MEDCouplingFieldDouble *)(*it))
231 std::vector<MEDCouplingMesh *>::iterator it2=std::find(ms.begin(),ms.end(),m);
234 ms.push_back(const_cast<MEDCouplingMesh *>(m));
235 refs[id]=(int)ms.size()-1;
238 refs[id]=(int)std::distance(ms.begin(),it2);
246 std::vector<DataArrayDouble *> MEDCouplingMultiFields::getArrays() const
248 std::vector<DataArrayDouble *> tmp;
249 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();it!=_fs.end();it++)
251 std::vector<DataArrayDouble *> tmp2=(*it)->getArrays();
252 tmp.insert(tmp.end(),tmp2.begin(),tmp2.end());
257 std::vector<DataArrayDouble *> MEDCouplingMultiFields::getDifferentArrays(std::vector< std::vector<int> >& refs) const
259 refs.resize(_fs.size());
261 std::vector<DataArrayDouble *> ret;
262 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();it!=_fs.end();it++,id++)
264 std::vector<DataArrayDouble *> tmp2;
265 if((const MEDCouplingFieldDouble *)(*it))
267 tmp2=(*it)->getArrays();
268 refs[id].resize(tmp2.size());
273 for(std::vector<DataArrayDouble *>::const_iterator it2=tmp2.begin();it2!=tmp2.end();it2++,id2++)
277 std::vector<DataArrayDouble *>::iterator it3=std::find(ret.begin(),ret.end(),*it2);
281 refs[id][id2]=(int)ret.size()-1;
284 refs[id][id2]=(int)std::distance(ret.begin(),it3);
293 void MEDCouplingMultiFields::checkCoherency() const
295 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();
296 for(;it!=_fs.end();it++)
298 if((const MEDCouplingFieldDouble *)(*it)==0)
299 throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::checkCoherency : There is an empty Field in array...");
300 (*it)->checkCoherency();
304 MEDCouplingMultiFields::MEDCouplingMultiFields(const std::vector<MEDCouplingFieldDouble *>& fs):_fs(fs.size())
307 for(std::vector< MEDCouplingFieldDouble * >::const_iterator it=fs.begin();it!=fs.end();it++,id++)
312 throw INTERP_KERNEL::Exception("MEDCouplingMultiFields constructor : empty field found in vector !");
313 (*it)->checkCoherency();
322 MEDCouplingMultiFields::MEDCouplingMultiFields(const MEDCouplingMultiFields& other):RefCountObject(other)
324 std::size_t sz=other._fs.size();
326 std::vector<int> refs;
327 std::vector< std::vector<int> > refs2;
328 std::vector<MEDCouplingMesh *> ms=other.getDifferentMeshes(refs);
329 std::size_t msLgh=ms.size();
330 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> > ms2(msLgh);
331 for(std::size_t i=0;i<msLgh;i++)
332 ms2[i]=ms[i]->deepCpy();
333 std::vector<DataArrayDouble *> das=other.getDifferentArrays(refs2);
334 std::size_t dasLgth=das.size();
335 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > das2(dasLgth);
336 for(std::size_t i=0;i<dasLgth;i++)
337 das2[i]=das[i]->deepCpy();
338 for(std::size_t i=0;i<sz;i++)
340 if((const MEDCouplingFieldDouble *)other._fs[i])
342 MEDCouplingFieldTemplate *tmp=MEDCouplingFieldTemplate::New(*other._fs[i]);
343 _fs[i]=MEDCouplingFieldDouble::New(*tmp,other._fs[i]->getTimeDiscretization());
346 _fs[i]->setMesh(ms2[refs[i]]);
347 std::size_t nbOfArr=refs2[i].size();
348 std::vector<DataArrayDouble *> tmp2(nbOfArr);
349 for(std::size_t j=0;j<nbOfArr;j++)
352 tmp2[j]=das2[refs2[i][j]];
356 _fs[i]->setArrays(tmp2);
357 std::vector<int> tinyInfo;
358 std::vector<double> tinyInfo2;
359 other._fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationIntInformation2(tinyInfo);
360 other._fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationDbleInformation2(tinyInfo2);
361 _fs[i]->getTimeDiscretizationUnderGround()->finishUnserialization2(tinyInfo,tinyInfo2);
366 MEDCouplingMultiFields::MEDCouplingMultiFields()
370 void MEDCouplingMultiFields::getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<double>& tinyInfo2, int& nbOfDiffMeshes, int& nbOfDiffArr) const
372 std::vector<int> refs;
373 std::vector<MEDCouplingMesh *> ms=getDifferentMeshes(refs);
374 nbOfDiffMeshes=(int)ms.size();
375 std::vector< std::vector<int> > refs2;
376 std::vector<DataArrayDouble *> fs=getDifferentArrays(refs2);
377 nbOfDiffArr=(int)fs.size();
379 std::size_t sz=refs.size();//==_fs.size()
381 for(std::size_t i=0;i<sz;i++)
382 sz2+=(int)refs2[i].size();
385 std::vector<int> doubleDaInd(sz);
386 std::vector<int> timeDiscrInt;
387 tinyInfo.resize(sz2+5*sz+3);
390 for(std::size_t i=0;i<sz;i++)
392 std::vector<double> tmp;
393 std::vector<int> tmp2;
394 _fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationDbleInformation2(tmp);
395 _fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationIntInformation2(tmp2);
396 tinyInfo[3*sz+3+i]=(int)tmp.size();
397 tinyInfo[4*sz+3+i]=(int)tmp2.size();
398 tinyInfo2.insert(tinyInfo2.end(),tmp.begin(),tmp.end());
399 timeDiscrInt.insert(timeDiscrInt.end(),tmp2.begin(),tmp2.end());
401 int sz3=(int)timeDiscrInt.size();
404 for(std::size_t i=0;i<sz;i++)
405 tinyInfo[i+3]=refs[i];
406 for(std::size_t i=0;i<sz;i++)
407 tinyInfo[i+sz+3]=(int)refs2[i].size();
408 for(std::size_t i=0;i<sz;i++)
409 tinyInfo[i+2*sz+3]=(int)_fs[i]->getTimeDiscretization();
411 for(std::size_t i=0;i<sz;i++)
412 for(std::vector<int>::const_iterator it=refs2[i].begin();it!=refs2[i].end();it++,k++)
413 tinyInfo[5*sz+k+3]=*it;
414 tinyInfo.insert(tinyInfo.end(),timeDiscrInt.begin(),timeDiscrInt.end());//tinyInfo has lgth==sz3+sz2+5*sz+3
417 void MEDCouplingMultiFields::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD,
418 const std::vector<MEDCouplingFieldTemplate *>& ft, const std::vector<MEDCouplingMesh *>& ms,
419 const std::vector<DataArrayDouble *>& das)
423 int sz2=tinyInfoI[1];
424 // dealing with ft with no mesh set.
425 for(int i=0;i<sz;i++)
427 int meshId=tinyInfoI[3+i];
429 ft[i]->setMesh(ms[meshId]);
431 // dealing with fieldtemplate->fielddouble
435 for(int i=0;i<sz;i++)
437 _fs[i]=MEDCouplingFieldDouble::New(*ft[i],(TypeOfTimeDiscretization)tinyInfoI[2*sz+3+i]);
438 int sz3=tinyInfoI[sz+i+3];
439 std::vector<DataArrayDouble *> tmp(sz3);
440 for(int j=0;j<sz3;j++,k++)
442 int daId=tinyInfoI[5*sz+k+3];
448 _fs[i]->setArrays(tmp);
449 // time discr tiny info
450 int lgthI=tinyInfoI[4*sz+3+i];
451 int lgthD=tinyInfoI[3*sz+3+i];
453 std::vector<int> tdInfoI(tinyInfoI.begin()+sz2+5*sz+3+offI,tinyInfoI.begin()+sz2+5*sz+3+offI+lgthI);
454 std::vector<double> tdInfoD(tinyInfoD.begin()+offD,tinyInfoD.begin()+offD+lgthD);
455 _fs[i]->getTimeDiscretizationUnderGround()->finishUnserialization2(tdInfoI,tdInfoD);