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