Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.git] / src / MEDCalculator / MEDCalculatorDBField.cxx
1 // Copyright (C) 2007-2012  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.
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
20 #include "MEDCalculatorDBField.hxx"
21 #include "MEDCalculatorBrowserField.hxx"
22
23 #include "MEDLoaderBase.hxx"
24 #include "MEDLoader.hxx"
25
26 #include "MEDCouplingUMesh.hxx"
27 #include "MEDCouplingMemArray.hxx"
28 #include "MEDCouplingFieldDouble.hxx"
29 #include "MEDCouplingFieldOverTime.hxx"
30
31 #include "MEDCouplingFieldOverTimeServant.hxx"
32 #include "SALOME_NamingService.hxx"
33
34 #include <cmath>
35
36 using namespace ParaMEDMEM;
37
38 MEDCalculatorDBFieldReal *MEDCalculatorDBField::New(const MEDCalculatorBrowserField& ls)
39 {
40   return new MEDCalculatorDBFieldReal(ls);
41 }
42
43 MEDCalculatorDBFieldCst *MEDCalculatorDBField::New(double val)
44 {
45   return new MEDCalculatorDBFieldCst(val);
46 }
47
48 MEDCalculatorDBField *MEDCalculatorDBField::operator+(double val) const throw(INTERP_KERNEL::Exception)
49 {
50   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldCst> par2=new MEDCalculatorDBFieldCst(val);
51   return (*this)+(*par2);
52 }
53
54 MEDCalculatorDBField *MEDCalculatorDBField::operator-(double val) const throw(INTERP_KERNEL::Exception)
55 {
56   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldCst> par2=new MEDCalculatorDBFieldCst(val);
57   return (*this)-(*par2);
58 }
59
60 MEDCalculatorDBField *MEDCalculatorDBField::operator*(double val) const throw(INTERP_KERNEL::Exception)
61 {
62   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldCst> par2=new MEDCalculatorDBFieldCst(val);
63   return (*this)*(*par2);
64 }
65
66 MEDCalculatorDBField *MEDCalculatorDBField::operator/(double val) const throw(INTERP_KERNEL::Exception)
67 {
68   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldCst> par2=new MEDCalculatorDBFieldCst(val);
69   return (*this)/(*par2);
70 }
71
72 MEDCalculatorDBFieldReal *MEDCalculatorDBFieldReal::operator()(const MEDCalculatorDBRangeSelection& t, const MEDCalculatorDBRangeSelection& p, const MEDCalculatorDBRangeSelection& c) throw(INTERP_KERNEL::Exception)
73 {
74   MEDCalculatorDBFieldReal *ret=new MEDCalculatorDBFieldReal(*this);
75   ret->_t=t;
76   ret->_p=p;
77   ret->_c=c;
78   return ret;
79 }
80
81 MEDCalculatorDBFieldReal::~MEDCalculatorDBFieldReal()
82 {
83 }
84
85 MEDCalculatorDBFieldReal::MEDCalculatorDBFieldReal(TypeOfField type):_type(type)
86 {
87 }
88
89 void MEDCalculatorDBFieldReal::setName(const char *name)
90 {
91   _name=name;
92   /*fetchData();
93   std::vector<int> ids=_t.getIds(_time_steps.size());
94   for(std::vector<int>::const_iterator iter=ids.begin();iter!=ids.end();iter++)
95   _time_steps[*iter]->setName(name);*/
96 }
97
98 void MEDCalculatorDBFieldReal::setDescription(const char *descr)
99 {
100   _description=descr;
101   /*fetchData();
102   std::vector<int> ids=_t.getIds(_time_steps.size());
103   for(std::vector<int>::const_iterator iter=ids.begin();iter!=ids.end();iter++)
104   _time_steps[*iter]->setDescription(descr);*/
105 }
106
107 void MEDCalculatorDBFieldReal::write(const char *fName, bool writeFromScratch) const throw(INTERP_KERNEL::Exception)
108 {
109   fetchData();
110   std::vector<int> ids=_t.getIds(_time_steps.size());
111   int step=ids[0];
112   const MEDCouplingFieldDouble *field=_time_steps[step]->getField(_type,_file_name,_mesh_name,_field_name);
113   const MEDCouplingUMesh *mesh=static_cast<const MEDCouplingUMesh *>(field->getMesh());
114   int status=MEDLoaderBase::getStatusOfFile(fName);
115   if(!writeFromScratch && status==MEDLoaderBase::EXIST_RW)
116     {
117       std::vector<std::string> ms=MEDLoader::GetMeshNames(fName);
118       if(std::find(ms.begin(),ms.end(),mesh->getName())!=ms.end())
119         {
120           std::ostringstream oss; oss << "In file \"" << fName << "\" the mesh with name \"" << mesh->getName() << "\" already exists !"; 
121           throw INTERP_KERNEL::Exception(oss.str().c_str());
122         }
123       std::vector<std::string> fs=MEDLoader::GetAllFieldNames(fName);
124       if(std::find(fs.begin(),fs.end(),field->getName())!=fs.end())
125         {
126           std::ostringstream oss; oss << "In file \"" << fName << "\" the field with name \"" << field->getName() << "\" already exists !"; 
127           throw INTERP_KERNEL::Exception(oss.str().c_str());
128         }
129     }
130   MEDLoader::WriteUMesh(fName,mesh,writeFromScratch);
131   for(std::vector<int>::const_iterator iter=ids.begin();iter!=ids.end();iter++)
132     _time_steps[*iter]->write(fName,_name,_description);
133 }
134
135 void MEDCalculatorDBFieldReal::display() const throw(INTERP_KERNEL::Exception)
136 {
137   fetchData();
138   std::vector<int> ids=_t.getIds(_time_steps.size());
139   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > fs2(ids.size());
140   int ii=0;
141   for(std::vector<int>::const_iterator iter=ids.begin();iter!=ids.end();iter++)
142     fs2[ii++]=_time_steps[*iter]->getFieldWithoutQuestion(_c_labels.size(),_c);
143   std::vector<MEDCouplingFieldDouble *> fs(fs2.size());
144   std::copy(fs2.begin(),fs2.end(),fs.begin());
145   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldOverTime> fot=MEDCouplingFieldOverTime::New(fs);
146   //
147   int argc=0;
148   CORBA::ORB_var orb=CORBA::ORB_init(argc,0);
149   CORBA::Object_var obj=orb->resolve_initial_references("RootPOA");
150   PortableServer::POA_var poa=PortableServer::POA::_narrow(obj);
151   PortableServer::POAManager_var mgr=poa->the_POAManager();
152   mgr->activate();
153   MEDCouplingFieldOverTimeServant *fots=new MEDCouplingFieldOverTimeServant(fot);
154   SALOME_MED::MEDCouplingFieldOverTimeCorbaInterface_var fotPtr=fots->_this();
155   //
156   SALOME_NamingService ns(orb);
157   ns.Change_Directory("/Containers");
158   std::vector<std::string> subdirs=ns.list_subdirs();
159   std::ostringstream path;
160   path << "/Containers/" << subdirs[0] << "/FactoryServer/PARAVIS_inst_1";
161   //
162   CORBA::Object_var paravis=ns.Resolve(path.str().c_str());
163   CORBA::Request_var req=paravis->_request("ExecuteScript");
164   CORBA::NVList_ptr args=req->arguments();
165   CORBA::Any ob;
166   std::ostringstream script;
167   char *ior=orb->object_to_string(fotPtr);
168   script << "src1 = ParaMEDCorbaPluginSource()\nsrc1.IORCorba = '" << ior << "'\nasc=GetAnimationScene()\nrw=GetRenderView()\ndr=Show()\ndr.Visibility = 1\n";
169   CORBA::string_free(ior);
170   ob <<= script.str().c_str();
171   args->add_value("script",ob,CORBA::ARG_IN);
172   req->set_return_type(CORBA::_tc_void);
173   req->invoke();
174   // clean-up
175 }
176
177 std::string MEDCalculatorDBFieldReal::simpleRepr() const
178 {
179   std::ostringstream oss;
180   oss << "Multitime field with name : \""<< _name << "\".\n";
181   oss << "Description of the field is : \"" << _description << "\".\n";
182   oss << "Number of time steps of multitime field : " << getNumberOfSteps() << ".\n";
183   oss << "Number of components of multitime field : " << getNumberOfComponents() << ".\n";
184   oss << "Components names attached are : ";
185   std::vector<int> ids=_c.getIds(_c_labels.size());
186   for(std::vector<int>::const_iterator iter=ids.begin();iter!=ids.end();iter++)
187     oss << "\"" << _c_labels[*iter] << "\" ";
188   oss << ".\nNumber of fetched field in multime field : " << getNumberOfFetchedSteps() << "/" << getNumberOfSteps() << ".\n";
189   return oss.str();
190 }
191
192 MEDCalculatorDBFieldReal::MEDCalculatorDBFieldReal(const MEDCalculatorBrowserField& ls):_file_name(ls.getFileName()),_mesh_name(ls.getCorrespondingMeshesFromField().front()),_field_name(ls.getName()),_type(ls.getType()),
193                                                                      _c_labels(ls.getComponents())
194 {
195   const std::vector<MEDCalculatorBrowserStep>& steps=ls.getSteps();
196   int sz=steps.size();
197   for(int i=0;i<sz;i++)
198     {
199       MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBSliceField> elt(new MEDCalculatorDBSliceField(steps[i].getTimeStep(),steps[i].getOrder()));
200       _time_steps.push_back(elt);
201     }
202 }
203
204 const MEDCalculatorDBFieldReal& MEDCalculatorDBFieldReal::operator=(const MEDCalculatorDBFieldReal& other) throw(INTERP_KERNEL::Exception)
205 {
206   checkCoherency(other);
207   std::vector<int> ids=_t.getIds(_time_steps.size());
208   std::vector<int> ids2=other._t.getIds(other._time_steps.size());
209   unsigned int sz=ids.size();
210   if(sz!=ids2.size())
211     throw INTERP_KERNEL::Exception("FieldReal::operator= : Timesteps lengthes mismatch !");
212   fetchData();
213   other.fetchData();
214   for(unsigned int i=0;i<sz;i++)
215     _time_steps[ids[i]]->assign(other._time_steps[ids2[i]],_c_labels.size(),_c,other._c_labels.size(),other._c);
216   return *this;
217 }
218
219 const MEDCalculatorDBFieldReal& MEDCalculatorDBFieldReal::operator=(double val) throw(INTERP_KERNEL::Exception)
220 {
221   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> other=buildCstFieldFromThis(val);
222   return (*this)=*other;
223 }
224
225 MEDCalculatorDBField *MEDCalculatorDBFieldReal::operator+(const MEDCalculatorDBField& other) const throw(INTERP_KERNEL::Exception)
226 {
227   const MEDCalculatorDBField *other2=&other;
228   const MEDCalculatorDBFieldReal *otherr=dynamic_cast<const MEDCalculatorDBFieldReal *>(other2);
229   if(otherr)
230     return add(*otherr);
231   else
232     {
233       const MEDCalculatorDBFieldCst *otherc=dynamic_cast<const MEDCalculatorDBFieldCst *>(other2);
234       if(otherc)
235         {
236           MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> othercr=buildCstFieldFromThis(otherc->getValue());
237           MEDCalculatorDBField *ret=add(*othercr);
238           return ret;
239         }
240       else
241         throw INTERP_KERNEL::Exception("FieldReal::operator+ : unrecognized type of parameter recieved !");
242     }
243 }
244
245 MEDCalculatorDBField *MEDCalculatorDBFieldReal::add(const MEDCalculatorDBFieldReal& other) const throw(INTERP_KERNEL::Exception)
246 {
247   checkCoherency(other);
248   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
249   fetchData();
250   other.fetchData();
251   DataArrayInt *cellCor,*nodeCor;
252   std::vector<int> ids=_t.getIds(_time_steps.size());
253   std::vector<int> ids2=other._t.getIds(other._time_steps.size());
254   if(ids.size()!=ids2.size())
255     throw INTERP_KERNEL::Exception("FieldReal::add : Timesteps lengthes mismatch !");
256   int step=ids[0];
257   int step2=ids2[0];
258   const MEDCouplingMesh *mesh=_time_steps[step]->getMesh(_type,_file_name,_mesh_name,_field_name);
259   const MEDCouplingMesh *otherm=other._time_steps[step2]->getMesh(_type,other._file_name,other._mesh_name,other._field_name);
260   mesh->checkGeoEquivalWith(otherm,1,1e-12,cellCor,nodeCor);//1 for fast check
261   int sz=ids.size();
262   ret->_time_steps.resize(sz);
263   for(int i=0;i<sz;i++)
264     ret->_time_steps[i]=_time_steps[ids[i]]->add(other._time_steps[ids2[i]],cellCor,nodeCor,_c_labels.size(),_c,other._c_labels.size(),other._c);
265   int newNbOfCompo=_c.getSize(_c_labels.size());
266   ret->_c_labels.resize(newNbOfCompo);
267   if(cellCor)
268     cellCor->decrRef();
269   if(nodeCor)
270     nodeCor->decrRef();
271   ret->incrRef();
272   return ret;
273 }
274
275 bool MEDCalculatorDBFieldReal::isEqual(const MEDCalculatorDBField& other, double precM, double precF) const
276 {
277   const MEDCalculatorDBField *other2=&other;
278   const MEDCalculatorDBFieldReal *otherr=dynamic_cast<const MEDCalculatorDBFieldReal *>(other2);
279   if(otherr)
280     return isEqualSameType(*otherr,precM,precF);
281   else
282     {
283       const MEDCalculatorDBFieldCst *otherc=dynamic_cast<const MEDCalculatorDBFieldCst *>(other2);
284       if(otherc)
285         {
286           MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> othercr=buildCstFieldFromThis(otherc->getValue());
287           bool ret=isEqualSameType(*othercr,precM,precF);
288           return ret;
289         }
290       else
291         throw INTERP_KERNEL::Exception("FieldReal::isEqual : unrecognized type of parameter recieved !");
292     }
293 }
294
295 bool MEDCalculatorDBFieldReal::isEqualSameType(const MEDCalculatorDBFieldReal& other, double precM, double precF) const
296 {
297   if(_description!=other._description)
298     return false;
299   fetchData();
300   other.fetchData();
301   DataArrayInt *cellCor,*nodeCor;
302   std::vector<int> ids=_t.getIds(_time_steps.size());
303   std::vector<int> ids2=other._t.getIds(other._time_steps.size());
304   if(ids.size()!=ids2.size())
305     return false;
306   int step=ids[0];
307   int step2=ids2[0];
308   const MEDCouplingMesh *mesh=_time_steps[step]->getMesh(_type,_file_name,_mesh_name,_field_name);
309   const MEDCouplingMesh *otherm=other._time_steps[step2]->getMesh(_type,other._file_name,other._mesh_name,other._field_name);
310   mesh->checkGeoEquivalWith(otherm,0,precM,cellCor,nodeCor);
311   int sz=ids.size();
312   for(int i=0;i<sz;i++)
313     if(!_time_steps[ids[i]]->isEqual(other._time_steps[ids2[i]],cellCor,nodeCor,_c_labels.size(),_c,other._c_labels.size(),other._c,precF))
314       return false;
315   if(cellCor)
316     cellCor->decrRef();
317   if(nodeCor)
318     nodeCor->decrRef();
319   return true;
320 }
321
322 MEDCalculatorDBField *MEDCalculatorDBFieldReal::operator-(const MEDCalculatorDBField& other) const throw(INTERP_KERNEL::Exception)
323 {
324   const MEDCalculatorDBField *other2=&other;
325   const MEDCalculatorDBFieldReal *otherr=dynamic_cast<const MEDCalculatorDBFieldReal *>(other2);
326   if(otherr)
327     return substract(*otherr);
328   else
329     {
330       const MEDCalculatorDBFieldCst *otherc=dynamic_cast<const MEDCalculatorDBFieldCst *>(other2);
331       if(otherc)
332         {
333           MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> othercr=buildCstFieldFromThis(otherc->getValue());
334           MEDCalculatorDBField *ret=substract(*othercr);
335           return ret;
336         }
337       else
338         throw INTERP_KERNEL::Exception("FieldReal::operator- : unrecognized type of parameter recieved !");
339     }
340 }
341
342 MEDCalculatorDBField *MEDCalculatorDBFieldReal::substract(const MEDCalculatorDBFieldReal& other) const throw(INTERP_KERNEL::Exception)
343 {
344   checkCoherency(other);
345   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
346   fetchData();
347   other.fetchData();
348   DataArrayInt *cellCor,*nodeCor;
349   std::vector<int> ids=_t.getIds(_time_steps.size());
350   std::vector<int> ids2=other._t.getIds(other._time_steps.size());
351   if(ids.size()!=ids2.size())
352     throw INTERP_KERNEL::Exception("FieldReal::substract : Timesteps lengthes mismatch !");
353   int step=ids[0];
354   int step2=ids2[0];
355   const MEDCouplingMesh *mesh=_time_steps[step]->getMesh(_type,_file_name,_mesh_name,_field_name);
356   const MEDCouplingMesh *otherm=other._time_steps[step2]->getMesh(_type,other._file_name,other._mesh_name,other._field_name);
357   mesh->checkGeoEquivalWith(otherm,1,1e-12,cellCor,nodeCor);//1 for fast check
358   int sz=ids.size();
359   ret->_time_steps.resize(sz);
360   for(int i=0;i<sz;i++)
361     ret->_time_steps[i]=_time_steps[ids[i]]->substract(other._time_steps[ids2[i]],cellCor,nodeCor,_c_labels.size(),_c,other._c_labels.size(),other._c);
362   int newNbOfCompo=_c.getSize(_c_labels.size());
363   ret->_c_labels.resize(newNbOfCompo);
364   if(cellCor)
365     cellCor->decrRef();
366   if(nodeCor)
367     nodeCor->decrRef();
368   ret->incrRef();
369   return ret;
370 }
371
372 MEDCalculatorDBField *MEDCalculatorDBFieldReal::operator*(const MEDCalculatorDBField& other) const throw(INTERP_KERNEL::Exception)
373 {
374   const MEDCalculatorDBField *other2=&other;
375   const MEDCalculatorDBFieldReal *otherr=dynamic_cast<const MEDCalculatorDBFieldReal *>(other2);
376   if(otherr)
377     return multiply(*otherr);
378   else
379     {
380       const MEDCalculatorDBFieldCst *otherc=dynamic_cast<const MEDCalculatorDBFieldCst *>(other2);
381       if(otherc)
382         {
383           MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> othercr=buildCstFieldFromThis(otherc->getValue());
384           MEDCalculatorDBField *ret=multiply(*othercr);
385           return ret;
386         }
387       else
388         throw INTERP_KERNEL::Exception("FieldReal::operator* : unrecognized type of parameter recieved !");
389     }
390 }
391
392 MEDCalculatorDBField *MEDCalculatorDBFieldReal::multiply(const MEDCalculatorDBFieldReal& other) const throw(INTERP_KERNEL::Exception)
393 {
394   checkCoherency(other);
395   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
396   fetchData();
397   other.fetchData();
398   DataArrayInt *cellCor,*nodeCor;
399   std::vector<int> ids=_t.getIds(_time_steps.size());
400   std::vector<int> ids2=other._t.getIds(other._time_steps.size());
401   if(ids.size()!=ids2.size())
402     throw INTERP_KERNEL::Exception("FieldReal::multiply : Timesteps lengthes mismatch !");
403   int step=ids[0];
404   int step2=ids2[0];
405   const MEDCouplingMesh *mesh=_time_steps[step]->getMesh(_type,_file_name,_mesh_name,_field_name);
406   const MEDCouplingMesh *otherm=other._time_steps[step2]->getMesh(_type,other._file_name,other._mesh_name,other._field_name);
407   mesh->checkGeoEquivalWith(otherm,1,1e-12,cellCor,nodeCor);//1 for fast check
408   int sz=ids.size();
409   ret->_time_steps.resize(sz);
410   for(int i=0;i<sz;i++)
411     ret->_time_steps[i]=_time_steps[ids[i]]->multiply(other._time_steps[ids2[i]],cellCor,nodeCor,_c_labels.size(),_c,other._c_labels.size(),other._c);
412   int newNbOfCompo=_c.getSize(_c_labels.size());
413   ret->_c_labels.resize(newNbOfCompo);
414   if(cellCor)
415     cellCor->decrRef();
416   if(nodeCor)
417     nodeCor->decrRef();
418   ret->incrRef();
419   return ret;
420 }
421
422 MEDCalculatorDBField *MEDCalculatorDBFieldReal::operator/(const MEDCalculatorDBField& other) const throw(INTERP_KERNEL::Exception)
423 {
424   const MEDCalculatorDBField *other2=&other;
425   const MEDCalculatorDBFieldReal *otherr=dynamic_cast<const MEDCalculatorDBFieldReal *>(other2);
426   if(otherr)
427     return divide(*otherr);
428   else
429     {
430       const MEDCalculatorDBFieldCst *otherc=dynamic_cast<const MEDCalculatorDBFieldCst *>(other2);
431       if(otherc)
432         {
433           MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> othercr=buildCstFieldFromThis(otherc->getValue());
434           MEDCalculatorDBField *ret=divide(*othercr);
435           return ret;
436         }
437       else
438         throw INTERP_KERNEL::Exception("FieldReal::operator/ : unrecognized type of parameter recieved !");
439     }
440 }
441
442 MEDCalculatorDBField *MEDCalculatorDBFieldReal::divide(const MEDCalculatorDBFieldReal& other) const throw(INTERP_KERNEL::Exception)
443 {
444   checkCoherency(other);
445   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
446   fetchData();
447   other.fetchData();
448   DataArrayInt *cellCor,*nodeCor;
449   std::vector<int> ids=_t.getIds(_time_steps.size());
450   std::vector<int> ids2=other._t.getIds(other._time_steps.size());
451   if(ids.size()!=ids2.size())
452     throw INTERP_KERNEL::Exception("FieldReal::divide : Timesteps lengthes mismatch !");
453   int step=ids[0];
454   int step2=ids2[0];
455   const MEDCouplingMesh *mesh=_time_steps[step]->getMesh(_type,_file_name,_mesh_name,_field_name);
456   const MEDCouplingMesh *otherm=other._time_steps[step2]->getMesh(_type,other._file_name,other._mesh_name,other._field_name);
457   mesh->checkGeoEquivalWith(otherm,1,1e-12,cellCor,nodeCor);//1 for fast check
458   int sz=ids.size();
459   ret->_time_steps.resize(sz);
460   for(int i=0;i<sz;i++)
461     ret->_time_steps[i]=_time_steps[ids[i]]->divide(other._time_steps[ids2[i]],cellCor,nodeCor,_c_labels.size(),_c,other._c_labels.size(),other._c);
462   int newNbOfCompo=_c.getSize(_c_labels.size());
463   ret->_c_labels.resize(newNbOfCompo);
464   if(cellCor)
465     cellCor->decrRef();
466   if(nodeCor)
467     nodeCor->decrRef();
468   ret->incrRef();
469   return ret;
470 }
471
472 MEDCalculatorDBField *MEDCalculatorDBFieldReal::operator^(const MEDCalculatorDBFieldReal& other) const throw(INTERP_KERNEL::Exception)
473 {
474   return crossProduct(other);
475 }
476
477 MEDCalculatorDBField *MEDCalculatorDBFieldReal::dot(const MEDCalculatorDBFieldReal& other) const throw(INTERP_KERNEL::Exception)
478 {
479   checkCoherency(other);
480   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
481   fetchData();
482   other.fetchData();
483   std::vector<int> ids=_t.getIds(_time_steps.size());
484   std::vector<int> ids2=other._t.getIds(other._time_steps.size());
485   unsigned int sz=ids.size();
486   if(sz!=ids2.size())
487     throw INTERP_KERNEL::Exception("FieldReal::dot : Timesteps lengthes mismatch !");
488   ret->_time_steps.resize(sz);
489   for(unsigned int i=0;i<sz;i++)
490     ret->_time_steps[i]=_time_steps[ids[i]]->dot(other._time_steps[ids2[i]],_c_labels.size(),_c,other._c_labels.size(),other._c);
491   ret->_time_steps.resize(sz);
492   ret->_c_labels.resize(1);
493   ret->incrRef();
494   return ret;
495 }
496
497 MEDCalculatorDBField *MEDCalculatorDBFieldReal::crossProduct(const MEDCalculatorDBFieldReal& other) const throw(INTERP_KERNEL::Exception)
498 {
499   checkCoherency(other);
500   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
501   fetchData();
502   other.fetchData();
503   std::vector<int> ids=_t.getIds(_time_steps.size());
504   std::vector<int> ids2=other._t.getIds(other._time_steps.size());
505   unsigned int sz=ids.size();
506   if(sz!=ids2.size())
507     throw INTERP_KERNEL::Exception("FieldReal::crossProduct : Timesteps lengthes mismatch !");
508   ret->_time_steps.resize(sz);
509   for(unsigned int i=0;i<sz;i++)
510     ret->_time_steps[i]=_time_steps[ids[i]]->crossProduct(other._time_steps[ids2[i]],_c_labels.size(),_c,other._c_labels.size(),other._c);
511   ret->_time_steps.resize(sz);
512   ret->_c_labels.resize(3);
513   ret->incrRef();
514   return ret;
515 }
516
517 MEDCalculatorDBField *MEDCalculatorDBFieldReal::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
518 {
519   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
520   fetchData();
521   std::vector<int> ids=_t.getIds(_time_steps.size());
522   unsigned int sz=ids.size();
523   ret->_time_steps.resize(sz);
524   for(unsigned int i=0;i<sz;i++)
525     ret->_time_steps[i]=_time_steps[ids[i]]->doublyContractedProduct(_c_labels.size(),_c);
526   ret->_time_steps.resize(sz);
527   ret->_c_labels.resize(1);
528   ret->incrRef();
529   return ret;
530 }
531
532 MEDCalculatorDBField *MEDCalculatorDBFieldReal::determinant() const throw(INTERP_KERNEL::Exception)
533 {
534   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
535   fetchData();
536   std::vector<int> ids=_t.getIds(_time_steps.size());
537   unsigned int sz=ids.size();
538   ret->_time_steps.resize(sz);
539   for(unsigned int i=0;i<sz;i++)
540     ret->_time_steps[i]=_time_steps[ids[i]]->determinant(_c_labels.size(),_c);
541   ret->_time_steps.resize(sz);
542   ret->_c_labels.resize(1);
543   ret->incrRef();
544   return ret;
545 }
546
547 MEDCalculatorDBField *MEDCalculatorDBFieldReal::eigenValues() const throw(INTERP_KERNEL::Exception)
548 {
549   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
550   fetchData();
551   std::vector<int> ids=_t.getIds(_time_steps.size());
552   unsigned int sz=ids.size();
553   ret->_time_steps.resize(sz);
554   for(unsigned int i=0;i<sz;i++)
555     ret->_time_steps[i]=_time_steps[ids[i]]->eigenValues(_c_labels.size(),_c);
556   ret->_time_steps.resize(sz);
557   if(sz!=0)
558     {
559       int ncomp=ret->_time_steps[0]->getFieldAttribute()->getNumberOfComponents();
560       ret->_c_labels.resize(ncomp);
561     }
562   else
563     ret->_c_labels.resize(0);
564   ret->incrRef();
565   return ret;
566 }
567
568 MEDCalculatorDBField *MEDCalculatorDBFieldReal::eigenVectors() const throw(INTERP_KERNEL::Exception)
569 {
570   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
571   fetchData();
572   std::vector<int> ids=_t.getIds(_time_steps.size());
573   unsigned int sz=ids.size();
574   ret->_time_steps.resize(sz);
575   for(unsigned int i=0;i<sz;i++)
576     ret->_time_steps[i]=_time_steps[ids[i]]->eigenVectors(_c_labels.size(),_c);
577   ret->_time_steps.resize(sz);
578   if(sz!=0)
579     {
580       int ncomp=ret->_time_steps[0]->getFieldAttribute()->getNumberOfComponents();
581       ret->_c_labels.resize(ncomp);
582     }
583   else
584     ret->_c_labels.resize(0);
585   ret->incrRef();
586   return ret;
587 }
588
589 MEDCalculatorDBField *MEDCalculatorDBFieldReal::inverse() const throw(INTERP_KERNEL::Exception)
590 {
591   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
592   fetchData();
593   std::vector<int> ids=_t.getIds(_time_steps.size());
594   unsigned int sz=ids.size();
595   ret->_time_steps.resize(sz);
596   for(unsigned int i=0;i<sz;i++)
597     ret->_time_steps[i]=_time_steps[ids[i]]->inverse(_c_labels.size(),_c);
598   ret->_time_steps.resize(sz);
599   if(sz!=0)
600     {
601       int ncomp=ret->_time_steps[0]->getFieldAttribute()->getNumberOfComponents();
602       ret->_c_labels.resize(ncomp);
603     }
604   else
605     ret->_c_labels.resize(0);
606   ret->incrRef();
607   return ret;
608 }
609
610 MEDCalculatorDBField *MEDCalculatorDBFieldReal::trace() const throw(INTERP_KERNEL::Exception)
611 {
612   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
613   fetchData();
614   std::vector<int> ids=_t.getIds(_time_steps.size());
615   unsigned int sz=ids.size();
616   ret->_time_steps.resize(sz);
617   for(unsigned int i=0;i<sz;i++)
618     ret->_time_steps[i]=_time_steps[ids[i]]->trace(_c_labels.size(),_c);
619   ret->_time_steps.resize(sz);
620   ret->_c_labels.resize(1);
621   ret->incrRef();
622   return ret;
623 }
624
625 MEDCalculatorDBField *MEDCalculatorDBFieldReal::deviator() const throw(INTERP_KERNEL::Exception)
626 {
627   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
628   fetchData();
629   std::vector<int> ids=_t.getIds(_time_steps.size());
630   unsigned int sz=ids.size();
631   ret->_time_steps.resize(sz);
632   for(unsigned int i=0;i<sz;i++)
633     ret->_time_steps[i]=_time_steps[ids[i]]->deviator(_c_labels.size(),_c);
634   ret->_time_steps.resize(sz);
635   if(sz!=0)
636     {
637       int ncomp=ret->_time_steps[0]->getFieldAttribute()->getNumberOfComponents();
638       ret->_c_labels.resize(ncomp);
639     }
640   else
641     ret->_c_labels.resize(0);
642   ret->incrRef();
643   return ret;
644 }
645
646 MEDCalculatorDBField *MEDCalculatorDBFieldReal::magnitude() const throw(INTERP_KERNEL::Exception)
647 {
648   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
649   fetchData();
650   std::vector<int> ids=_t.getIds(_time_steps.size());
651   unsigned int sz=ids.size();
652   ret->_time_steps.resize(sz);
653   for(unsigned int i=0;i<sz;i++)
654     ret->_time_steps[i]=_time_steps[ids[i]]->magnitude(_c_labels.size(),_c);
655   ret->_time_steps.resize(sz);
656   ret->_c_labels.resize(1);
657   ret->incrRef();
658   return ret;
659 }
660
661 void MEDCalculatorDBFieldReal::applyFunc(const char *func) throw(INTERP_KERNEL::Exception)
662 {
663   fetchData();
664   std::vector<int> ids=_t.getIds(_time_steps.size());
665   for(std::vector<int>::const_iterator it=ids.begin();it!=ids.end();it++)
666     _time_steps[*it]->applyFunc(func,_c_labels.size(),_c);
667 }
668
669 MEDCalculatorDBFieldReal *MEDCalculatorDBFieldReal::buildCstFieldFromThis(double val) const
670 {
671   MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> ret=new MEDCalculatorDBFieldReal(_type);
672   ret->_p=_p;
673   ret->_c_labels.resize(_c.getSize(_c_labels.size()));
674   std::vector<int> stps=_t.getIds(_time_steps.size());
675   int stepSize=stps.size();
676   ret->_time_steps.resize(stepSize);
677   if(stepSize==0)
678     throw INTERP_KERNEL::Exception("MEDCalculatorDBFieldReal::buildCstFieldFromThis : no time steps defined !");
679   for(int i=0;i<stepSize;i++)
680     {
681       const MEDCouplingFieldDouble *f=_time_steps[stps[i]]->getField(_type,_file_name,_mesh_name,_field_name);
682       ret->_time_steps[i]=new MEDCalculatorDBSliceField(_time_steps[stps[i]]->buildCstFromThis(val,ret->_c_labels.size(),f));
683     }
684   ret->incrRef();
685   return ret;
686 }
687
688 void MEDCalculatorDBFieldReal::checkCoherency(const MEDCalculatorDBFieldReal& other) const throw(INTERP_KERNEL::Exception)
689 {
690   if(_type!=other._type)
691     throw INTERP_KERNEL::Exception("Types of field mismatch !");
692   if(getNumberOfSteps()!=other.getNumberOfSteps())
693     throw INTERP_KERNEL::Exception("Time steps mismatch !");
694   if(getNumberOfComponents()!=other.getNumberOfComponents())
695     throw INTERP_KERNEL::Exception("Components mismatch !");
696 }
697
698 void MEDCalculatorDBFieldReal::fetchData() const throw(INTERP_KERNEL::Exception)
699 {
700   std::vector<std::pair<int,int> > idstoFetch;
701   std::vector<int> ids=_t.getIds(_time_steps.size());
702   int sz=ids.size();
703   std::vector<int> idsInGlobalToFetch;
704   for(int i=0;i<sz;i++)
705     {
706       MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBSliceField> elt=_time_steps[ids[i]];
707       if(!elt->isFetched())
708         {
709           int dt,it;
710           elt->getDtIt(dt,it);
711           std::pair<int,int> p(dt,it);
712           idstoFetch.push_back(p);
713           idsInGlobalToFetch.push_back(ids[i]);
714         }
715     }
716   std::vector<MEDCouplingFieldDouble *> fs=MEDLoader::ReadFieldsOnSameMesh(_type,_file_name.c_str(),_mesh_name.c_str(),0,_field_name.c_str(),idstoFetch);
717   sz=fs.size();
718   for(int i=0;i<sz;i++)
719     {
720       MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBSliceField> elt=_time_steps[idsInGlobalToFetch[i]];
721       elt->setField(fs[i]);
722     }
723 }
724
725 int MEDCalculatorDBFieldReal::getNumberOfSteps() const
726 {
727   return _t.getSize(_time_steps.size());
728 }
729
730 int MEDCalculatorDBFieldReal::getNumberOfFetchedSteps() const
731 {
732   int ret=0;
733   std::vector<int> ids=_t.getIds(_time_steps.size());
734   for(std::vector<int>::const_iterator it=ids.begin();it!=ids.end();it++)
735     if(_time_steps[*it]->isFetched())
736       ret++;
737   return ret;
738 }
739
740 int MEDCalculatorDBFieldReal::getNumberOfComponents() const
741 {
742   return _c.getSize(_c_labels.size());
743 }
744
745 /*!
746  * WARNING the caller has the ownership of all of instances in returned vector.
747  */
748 std::vector<MEDCouplingFieldDouble *> MEDCalculatorDBFieldReal::getFields() const throw(INTERP_KERNEL::Exception)
749 {
750   fetchData();
751   std::vector<int> ids=_t.getIds(_time_steps.size());
752   std::vector<MEDCouplingFieldDouble *> ret(ids.size());
753   int i=0;
754   for(std::vector<int>::const_iterator it=ids.begin();it!=ids.end();it++,i++)
755     ret[i]=_time_steps[*it]->getFieldWithoutQuestion(_c_labels.size(),_c);
756   return ret;
757 }
758
759 std::string MEDCalculatorDBFieldReal::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
760 {
761   if(i>=(int)_c_labels.size())
762     throw INTERP_KERNEL::Exception("MEDCalculatorDBFieldReal::getInfoOnComponent : sepcified id >= number of component !");
763   return _c_labels[i];
764 }
765
766 void MEDCalculatorDBFieldReal::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
767 {
768   if(i>=(int)_c_labels.size())
769     throw INTERP_KERNEL::Exception("MEDCalculatorDBFieldReal::setInfoOnComponent : sepcified id >= number of component !");
770   _c_labels[i]=info;
771 }
772
773 MEDCalculatorDBFieldCst::MEDCalculatorDBFieldCst(double val):_val(val)
774 {
775 }
776
777 MEDCalculatorDBField *MEDCalculatorDBFieldCst::operator+(const MEDCalculatorDBField& other) const throw(INTERP_KERNEL::Exception)
778 {
779   const MEDCalculatorDBField *other2=&other;
780   const MEDCalculatorDBFieldCst *otherc=dynamic_cast<const MEDCalculatorDBFieldCst *>(other2);
781   if(otherc)
782     {
783       MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldCst> ret=new MEDCalculatorDBFieldCst(*this);
784       ret->_val=_val+otherc->_val;
785       ret->incrRef();
786       return ret;
787     }
788   else
789     {
790       const MEDCalculatorDBFieldReal *otherr=dynamic_cast<const MEDCalculatorDBFieldReal *>(other2);
791       if(otherr)
792         {
793           MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> thisr=otherr->buildCstFieldFromThis(_val);
794           MEDCalculatorDBField *ret=(*thisr)+other;
795           return ret;
796         }
797       else
798         throw INTERP_KERNEL::Exception("FieldCst::operator+ : unrecognized type of parameter recieved !");
799     }
800 }
801
802 MEDCalculatorDBField *MEDCalculatorDBFieldCst::operator-(const MEDCalculatorDBField& other) const throw(INTERP_KERNEL::Exception)
803 {
804   const MEDCalculatorDBField *other2=&other;
805   const MEDCalculatorDBFieldCst *otherc=dynamic_cast<const MEDCalculatorDBFieldCst *>(other2);
806   if(otherc)
807     {
808       MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldCst> ret=new MEDCalculatorDBFieldCst(*this);
809       ret->_val=_val-otherc->_val;
810       ret->incrRef();
811       return ret;
812     }
813   else
814     {
815       const MEDCalculatorDBFieldReal *otherr=dynamic_cast<const MEDCalculatorDBFieldReal *>(other2);
816       if(otherr)
817         {
818           MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> thisr=otherr->buildCstFieldFromThis(_val);
819           MEDCalculatorDBField *ret=(*thisr)-other;
820           return ret;
821         }
822       else
823         throw INTERP_KERNEL::Exception("FieldCst::operator- : unrecognized type of parameter recieved !");
824     }
825 }
826
827 MEDCalculatorDBField *MEDCalculatorDBFieldCst::operator*(const MEDCalculatorDBField& other) const throw(INTERP_KERNEL::Exception)
828 {
829   const MEDCalculatorDBField *other2=&other;
830   const MEDCalculatorDBFieldCst *otherc=dynamic_cast<const MEDCalculatorDBFieldCst *>(other2);
831   if(otherc)
832     {
833       MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldCst> ret=new MEDCalculatorDBFieldCst(*this);
834       ret->_val=_val*otherc->_val;
835       ret->incrRef();
836       return ret;
837     }
838   else
839     {
840       const MEDCalculatorDBFieldReal *otherr=dynamic_cast<const MEDCalculatorDBFieldReal *>(other2);
841       if(otherr)
842         {
843           MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> thisr=otherr->buildCstFieldFromThis(_val);
844           MEDCalculatorDBField *ret=(*thisr)*other;
845           return ret;
846         }
847       else
848         throw INTERP_KERNEL::Exception("FieldCst::operator* : unrecognized type of parameter recieved !");
849     }
850 }
851
852 MEDCalculatorDBField *MEDCalculatorDBFieldCst::operator/(const MEDCalculatorDBField& other) const throw(INTERP_KERNEL::Exception)
853 {
854   const MEDCalculatorDBField *other2=&other;
855   const MEDCalculatorDBFieldCst *otherc=dynamic_cast<const MEDCalculatorDBFieldCst *>(other2);
856   if(otherc)
857     {
858       MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldCst> ret=new MEDCalculatorDBFieldCst(*this);
859       ret->_val=_val/otherc->_val;
860       ret->incrRef();
861       return ret;
862     }
863   else
864     {
865       const MEDCalculatorDBFieldReal *otherr=dynamic_cast<const MEDCalculatorDBFieldReal *>(other2);
866       if(otherr)
867         {
868           MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> thisr=otherr->buildCstFieldFromThis(_val);
869           MEDCalculatorDBField *ret=(*thisr)/other;
870           return ret;
871         }
872       else
873         throw INTERP_KERNEL::Exception("FieldCst::operator/ : unrecognized type of parameter recieved !");
874     }
875 }
876
877 bool MEDCalculatorDBFieldCst::isEqual(const MEDCalculatorDBField& other, double precM, double precF) const
878 {
879   const MEDCalculatorDBField *other2=&other;
880   const MEDCalculatorDBFieldCst *otherc=dynamic_cast<const MEDCalculatorDBFieldCst *>(other2);
881   if(otherc)
882     return fabs(otherc->_val-_val)<precF;
883   else
884     {
885       const MEDCalculatorDBFieldReal *otherr=dynamic_cast<const MEDCalculatorDBFieldReal *>(other2);
886       if(otherr)
887         {
888           MEDCouplingAutoRefCountObjectPtr<MEDCalculatorDBFieldReal> thisr=otherr->buildCstFieldFromThis(_val);
889           bool ret=thisr->isEqual(other,precM,precF);
890           return ret;
891         }
892       else
893         throw INTERP_KERNEL::Exception("FieldCst::isEqual : unrecognized type of parameter recieved !");
894     }
895 }