Salome HOME
Merge branch 'master' of https://git.salome-platform.org/git/modules/med
[modules/med.git] / src / MEDCalculator / MEDCalculatorBrowserField.cxx
1 // Copyright (C) 2007-2015  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 (CEA/DEN)
20
21 #include "MEDCalculatorBrowserStep.hxx"
22 #include "MEDCalculatorBrowserField.hxx"
23
24 #include "MEDLoader.hxx"
25 #include "MEDCouplingFieldDouble.hxx"
26
27 #include <set>
28 #include <sstream>
29 #include <algorithm>
30 #include <functional>
31
32 using namespace ParaMEDMEM;
33
34 //  Default constructor
35 //  Set field name to nm and selection to flase
36 //  Init empty vector for all other parameters
37 MEDCalculatorBrowserField::MEDCalculatorBrowserField(const char* nm) : _name(nm),_selection(false)
38 {
39 }
40
41 //  Destructor
42 MEDCalculatorBrowserField::~MEDCalculatorBrowserField()
43 {
44 }
45
46 //  Constructor with two parameters :
47 //   - fname, the fileName
48 //   - fieldname, the fieldname
49 //  First set name to fieldname
50 //  Then, read the Med structur to fill time steps, components and meshes
51 MEDCalculatorBrowserField::MEDCalculatorBrowserField(const char *fname, const char *fieldName) : _name(fieldName), _file_name(fname), _selection(false)
52 {
53   std::vector< std::string > meshNames=MEDLoader::GetMeshNamesOnField(fname,fieldName);
54   std::vector< std::pair< std::pair<int,int>, double > > dtits=MEDLoader::GetAllFieldIterations(fname, fieldName);
55   for(std::vector<std::pair< std::pair<int,int>, double > >::const_iterator iter=dtits.begin();iter!=dtits.end();iter++)
56     {
57       _steps.push_back(MEDCalculatorBrowserStep((*iter).first.first,(*iter).first.second,(*iter).second,meshNames[0]));
58     }
59   std::vector<TypeOfField> types=MEDLoader::GetTypesOfField(fname,meshNames[0].c_str(),fieldName);
60   if(types.empty())
61     throw INTERP_KERNEL::Exception("MEDCalculatorBrowserField::MEDCalculatorBrowserField : the file is not loadable using MED File 3 API ! Problably presence of field on edges faces...");
62   _type=types[0];//To improve
63   MEDCouplingFieldDouble *tmpf=0;
64   try
65     {
66       tmpf=MEDLoader::ReadField(_type,fname,meshNames[0].c_str(),0,fieldName,dtits[0].first.first,dtits[0].first.second);
67     }
68   catch(INTERP_KERNEL::Exception& e)
69     {
70       if(_type==ON_CELLS)
71         tmpf=MEDLoader::ReadField(_type,fname,meshNames[0].c_str(),-1,fieldName,dtits[0].first.first,dtits[0].first.second);
72       else
73         throw e;
74     }
75   int NumberOfComponents=tmpf->getNumberOfComponents();
76   for(int i=0;i<NumberOfComponents;i++)
77     {
78       std::string c=tmpf->getArray()->getInfoOnComponent(i);
79       if(c=="")
80         c="-noname-";
81       _components.push_back(c);
82     }
83   tmpf->decrRef();
84   _corresponding_meshes=MEDLoader::GetMeshNamesOnField(fname,fieldName);
85 }
86
87 //  Equal to string operator,
88 //  Test if fieldname of this field is the same as nm
89 bool MEDCalculatorBrowserField::operator==(const std::string& nm)
90 {
91   return nm==_name;
92 }
93
94 //  Equal to bool operator,
95 //  Test selection flag is set just as sel
96 bool MEDCalculatorBrowserField::operator==(bool sel)
97 {
98   return _selection==sel;
99 }
100
101 //  str method
102 //  Construct a std::string to print Field, using std::cout for example
103 //  Put x or o for selected or not
104 //  Add Field fieldname
105 //  Add x/o components
106 //  Add MEDCalculatorBrowserStep::str() for each step
107 //  Return a std::string
108 std::string MEDCalculatorBrowserField::str()
109 {
110   std::ostringstream res;
111   _selection?res<<"x ":res<<"o ";
112   res<<"Field "<<_name;
113
114   res<<"\n\t\tComponents :"<<std::endl;
115   for (unsigned int i = 0; i < _components.size(); i += 1)
116     {
117       res<<"\n\t\t\t"<<i<<" : "<<_components[i]<<""<<std::endl;
118     }
119
120   res<<"\n\t\tTimessteps :"<<std::endl;
121   for (unsigned int i = 0; i < _steps.size(); i += 1)
122     {
123       res<<"\n\t\t\t"<<_steps[i].str();
124     }
125
126   return res.str();
127 }
128
129 //  Select a specific step according to its id
130 //  Use std::find to get the corresponding step
131 //  Also select all components if none is selected (avoid having time steps selected, so field selected, without components)
132 void MEDCalculatorBrowserField::selectStep(int ts)
133 {
134   std::vector<MEDCalculatorBrowserStep>::iterator it = std::find(_steps.begin(),_steps.end(),ts);
135   if(it != _steps.end())
136     {
137       it->select();
138       _selection=true;
139       std::vector<bool>::iterator itb = std::find(_selected_components.begin(),_selected_components.end(),true);
140       if(itb == _selected_components.end())
141         {
142           for (unsigned int i = 0; i < _selected_components.size(); i += 1)
143             {
144             _selected_components[i] = true;
145             }
146         }
147     }
148 }
149
150
151 //  Select all time steps
152 //  Also select all components if none is selected (avoid having time steps selected, so field selected, without components)
153 void MEDCalculatorBrowserField::selectAllSteps()
154 {
155   for (std::vector<MEDCalculatorBrowserStep>::iterator it = _steps.begin(); it != _steps.end(); ++it)
156     {
157       it->select();
158     }
159   std::vector<bool>::iterator itb = std::find(_selected_components.begin(),_selected_components.end(),true);
160   if(itb == _selected_components.end())
161     {
162       for (unsigned int i = 0; i < _selected_components.size(); i += 1)
163         {
164           _selected_components[i] = true;
165         }
166     }
167   _selection=true;
168 }
169
170 //  Unselect a specific time step according to its id
171 //  Check if there is still time step selected :
172 //  - if yes, do nothing;
173 //  - if not, set selection flag to false
174 void MEDCalculatorBrowserField::unselectStep(int ts)
175 {
176   std::vector<MEDCalculatorBrowserStep>::iterator it = std::find(_steps.begin(),_steps.end(),ts);
177   if(it != _steps.end())
178     {
179       it->unselect();
180     }
181   it = std::find(_steps.begin(),_steps.end(),true);
182   if(it == _steps.end())
183     {
184       _selection=false;
185     }
186 }
187
188 //  Unselect all time steps
189 //  Set selection flag to false
190 void MEDCalculatorBrowserField::unselectAllSteps()
191 {
192   for (std::vector<MEDCalculatorBrowserStep>::iterator it = _steps.begin(); it != _steps.end(); ++it)
193     {
194       it->unselect();
195     }
196   _selection=false;
197 }
198
199 //  Return if this field is selected or not, i.e. if some time steps are selected or not
200 bool MEDCalculatorBrowserField::isSelected()
201 {
202   return _selection;
203 }
204
205 //  Return field name
206 const std::string& MEDCalculatorBrowserField::getName() const
207 {
208   return _name;
209 }
210
211 //  Return steps vector
212 const std::vector<MEDCalculatorBrowserStep>& MEDCalculatorBrowserField::getSteps() const
213 {
214   return _steps;
215 }
216
217 //  Return the time value corresponding to time step with id ts
218 const double& MEDCalculatorBrowserField::getTimeValue(int ts) const
219 {
220   std::vector<MEDCalculatorBrowserStep>::const_iterator it = std::find(_steps.begin(),_steps.end(),ts);
221   return it->getTimeValue();
222 }
223
224
225 //  Return the number of time steps
226 unsigned int MEDCalculatorBrowserField::getStepsSize() const
227 {
228   return _steps.size();
229 }
230
231 //  Add a time step to steps vector with (id, time value)
232 void MEDCalculatorBrowserField::addStep(int ts, double tv)
233 {
234   _steps.push_back(MEDCalculatorBrowserStep(ts,tv));
235 }
236
237 //  Select a specific component according to its id
238 void MEDCalculatorBrowserField::selectComponent(int id)
239 {
240   _selected_components[id]=true;
241 }
242
243 //  Select all components
244 void MEDCalculatorBrowserField::selectAllComponents()
245 {
246   for (unsigned int i = 0; i < _selected_components.size(); i += 1)
247     {
248       _selected_components[i] = true;
249     }
250 }
251
252 //  Unselect a specific component according to its id
253 void MEDCalculatorBrowserField::unselectComponent(int id)
254 {
255   _selected_components[id]=false;
256 }
257
258 // Unselect all components
259 void MEDCalculatorBrowserField::unselectAllComponents()
260 {
261   for (unsigned int i = 0; i < _selected_components.size(); i += 1)
262     {
263       _selected_components[i] = false;
264     }
265 }
266
267 //  Return a copy of the components vector
268 const std::vector<std::string>& MEDCalculatorBrowserField::getComponents() const
269 {
270   return _components;
271 }
272
273 //  Return a copy of the selected components vector
274 const std::vector<bool>& MEDCalculatorBrowserField::getSelectedComponents() const
275 {
276   return _selected_components;
277 }
278
279 //  Return the number of components
280 unsigned int MEDCalculatorBrowserField::getComponentsSize() const
281 {
282   return _components.size();
283 }
284
285 //  Return a std::vector of std::string which contains all the meshes name used by all the time steps as supporting meshes
286 const std::vector<std::string>& MEDCalculatorBrowserField::getCorrespondingMeshesFromField() const
287 {
288   return _corresponding_meshes;
289 }
290
291 //  Return a std::string which contains all the meshes name used by the time steps (id) as supporting meshes
292 const std::string& MEDCalculatorBrowserField::getCorrespondingMeshFromStep(int i) const
293 {
294   return _steps[i].getCorrespondingMeshFromStep();
295 }
296
297 //  Change the name of a component, if input is empty, the component name is -noname- (for print)
298 void MEDCalculatorBrowserField::setComponentName(int i,const std::string& name)
299 {
300   std::string name2(name);
301   if(name2 == std::string(""))
302     name2 = "-noname-";
303   _components[i] = name2;
304 }
305
306 /*!
307  * Contrary to isSelected see all time steps.
308  */
309 bool MEDCalculatorBrowserField::isAnySelection() const
310 {
311   return std::find(_steps.begin(),_steps.end(),true)!=_steps.end();
312 }
313
314 void MEDCalculatorBrowserField::setMeshName(const std::string& m)
315 {
316   _corresponding_meshes.resize(1);
317   _corresponding_meshes[0]=m;
318 }
319
320 /*!
321  * This method returns a restriction of this containing only selected TimeSteps.
322  * This methods throws an exception if multiple meshes exists in selected time steps.
323  */
324 MEDCalculatorBrowserField MEDCalculatorBrowserField::getSelectedTimeSteps() const throw(INTERP_KERNEL::Exception)
325 {
326   int nbOfTs=std::count(_steps.begin(),_steps.end(),true);
327   std::vector<MEDCalculatorBrowserStep> ts(nbOfTs);
328   std::vector<MEDCalculatorBrowserStep>::const_iterator it=_steps.begin();
329   std::set<std::string> meshes;
330   for(int i=0;i<nbOfTs;i++)
331     {
332       it=std::find(it,_steps.end(),true);
333       ts[i]=*it;
334       meshes.insert((*it).getCorrespondingMeshFromStep());
335       if(meshes.size()>1)
336         throw INTERP_KERNEL::Exception("Not managed fields with variable meshes during time !");
337     }
338   MEDCalculatorBrowserField ret(*this);
339   ret.setSteps(ts);
340   ret.setMeshName(*(meshes.begin()));
341   return ret;
342 }
343
344 void MEDCalculatorBrowserField::setSteps(const std::vector<MEDCalculatorBrowserStep>& steps)
345 {
346   _steps=steps;
347 }