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