1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Partitioning/decimation module for the SALOME v3.2 platform
22 * \file MULTIPR_Utils.cxx
24 * \brief see MULTIPR_Utils.hxx
26 * \author Olivier LE ROUX - CS, Virtual Reality Dpt
31 //*****************************************************************************
33 //*****************************************************************************
35 #include "MULTIPR_Utils.hxx"
36 #include "MULTIPR_Exceptions.hxx"
37 #include "MULTIPR_Mesh.hxx"
43 //*****************************************************************************
45 //*****************************************************************************
47 void multipr::trim(char* pStr, char pChar)
49 int len = strlen(pStr) - 1;
51 while (pStr[p] == pChar)
62 bool multipr::startsWith(const char* pStr, const char* pStrPrefix)
65 while ((pStr[i] != '\0') && (pStrPrefix[i] != '\0') && (pStr[i] == pStrPrefix[i]))
69 return (pStrPrefix[i] == '\0');
73 string multipr::removeExtension(const char* pFilename, const char* pExtension)
75 string strPrefix(pFilename);
76 strPrefix.erase(strPrefix.rfind(pExtension), strlen(pExtension));
82 string multipr::getFilenameWithoutPath(const char* pFilename)
84 char* res = strrchr(pFilename, '/');
97 string multipr::getPath(const char* pFilename)
99 // find (reverse) the first occurrence of '/' in the given string
100 std::string aFilename(pFilename);
101 std::string::size_type aPos = aFilename.rfind('/');
103 if ( aPos == std::string::npos )
106 aFilename = aFilename.substr( 0, aPos + 1 );
108 aPos = aFilename.find( "//" );
110 if ( aPos == std::string::npos )
113 aFilename.replace( aPos, 2, "/" );
120 void multipr::copyFile(const char* pFilename, const char* pDestDir)
122 std::string srcDir = multipr::getPath(pFilename);
123 if (strcmp(srcDir.c_str(), pDestDir) == 0) return;
125 std::string filenameWithoutPath = multipr::getFilenameWithoutPath(pFilename);
126 std::string pDstFilename (pDestDir);
127 pDstFilename += filenameWithoutPath;
129 // open binary source file
130 FILE* src = fopen(pFilename, "rb");
131 if (src == NULL) return;
133 // open (create) binary destination file
134 FILE* dst = fopen(pDstFilename.c_str(), "wb");
135 if (dst == NULL) return;
137 const int size = 65536; // size of buffer is 64Kb
138 char* buf = new char[size];
140 ret = fread(buf, 1, size, src);
143 fwrite(buf, 1, ret, dst); // write to destination
144 ret = fread(buf, 1, size, src); // read from source
153 void multipr::printArray2D(
154 const med_float* pData,
159 for (int itElt = 0 ; itElt < pNumElt ; itElt++)
161 cout << pPrefix << " " << (itElt + 1) << ": ";
162 for (int itDim = 0 ; itDim < pDimElt ; itDim++)
164 cout << pData[itElt * pDimElt + itDim] << " ";
171 string multipr::realToString(med_float mV)
174 sprintf(str, "%lf", mV);
176 int len = strlen(str);
177 if (str[len - 1] == '.')
186 vector<string> multipr::getListMeshes(const char* pMEDfilename)
188 if (pMEDfilename == NULL) throw multipr::NullArgumentException("", __FILE__, __LINE__);
193 //---------------------------------------------------------------------
194 // Open MED file (READ_ONLY)
195 //---------------------------------------------------------------------
196 med_idt file = MEDouvrir(const_cast<char*>(pMEDfilename), MED_LECTURE); // open MED file for reading
197 if (file <= 0) throw multipr::IOException("MED file not found or not a sequential MED file", __FILE__, __LINE__);
199 //---------------------------------------------------------------------
200 // Read name of meshes
201 //---------------------------------------------------------------------
202 med_int nbMeshes = MEDnMaa(file);
203 if (nbMeshes <= 0) throw multipr::IOException("i/o error while reading number of meshes in MED file", __FILE__, __LINE__);
205 // for each mesh in the file (warning: first mesh is number 1)
206 for (int itMesh = 1 ; itMesh <= nbMeshes ; itMesh++)
208 char meshName[MED_TAILLE_NOM + 1];
211 med_maillage meshType;
212 char meshDesc[MED_TAILLE_DESC + 1];
222 if (ret != 0) throw multipr::IOException("i/o error while reading mesh information in MED file", __FILE__, __LINE__);
224 res.push_back(meshName);
227 //---------------------------------------------------------------------
228 // Close the MED file
229 //---------------------------------------------------------------------
230 ret = MEDfermer(file);
231 if (ret != 0) throw multipr::IOException("i/o error while closing MED file", __FILE__, __LINE__);
237 void multipr::getListScalarFields(const char* pMEDfilename, vector<pair<string, int> >& pFields, bool pAddNbGaussPoint, const char *pMeshName)
239 if (pMEDfilename == NULL) throw multipr::NullArgumentException("", __FILE__, __LINE__);
242 bool isOnNodes = true;
243 //---------------------------------------------------------------------
244 // Open MED file (READ_ONLY)
245 //---------------------------------------------------------------------
246 med_idt file = MEDouvrir(const_cast<char*>(pMEDfilename), MED_LECTURE); // open MED file for reading
247 if (file <= 0) throw multipr::IOException("MED file not found or not a sequential MED file", __FILE__, __LINE__);
249 //---------------------------------------------------------------------
250 // Read number of fields
251 //---------------------------------------------------------------------
252 med_int numFields = MEDnChamp(file, 0);
253 if (numFields < 0) throw IOException("Can't read number of fields.", __FILE__, __LINE__);
259 //---------------------------------------------------------------------
260 // For each field, read its name
261 //---------------------------------------------------------------------
262 for (int itField = 1 ; itField <= numFields ; itField++)
264 char* name = new char[MED_TAILLE_NOM + 1024];
266 med_int numComponents = MEDnChamp(file, itField);
268 if (numComponents < 0) throw IOException("Number of component less than zero.", __FILE__, __LINE__);
270 // collect scalar field only (not vectorial fields)
271 if (numComponents != 1)
276 char* strComponent = new char[numComponents * MED_TAILLE_PNOM + 1];
277 char* strUnit = new char[numComponents * MED_TAILLE_PNOM + 1];
278 strComponent[0] = '\0';
282 med_err ret = MEDchampInfo(
291 delete[] strComponent;
292 if (ret != 0) throw IOException("Can't get information on a field.", __FILE__, __LINE__);
294 // Get number of time step on nodes.
295 med_int numTimeStamps = MEDnPasdetemps(
299 (med_geometrie_element) 0);
300 if (numTimeStamps < 0) throw IOException("Can't get number of time steps on nodes", __FILE__, __LINE__);
302 // Get the number of time step on elements.
303 if (numTimeStamps == 0)
305 for (int i = 0; i < eMaxMedMesh; ++i)
307 numTimeStamps = MEDnPasdetemps(
312 if (numTimeStamps > 0)
320 if (numTimeStamps < 0) throw IOException("Can't get number of time steps on elements", __FILE__, __LINE__);
321 // For GUI only : add the nomber of gauss points to the string.
322 if (pAddNbGaussPoint == true && pMeshName != NULL)
324 char* tmp = new char[1024];
325 char* tmp2 = new char[1024];
327 med_int numdt, numo, nmaa;
329 med_int nb_values = -1;
333 // Get number of gauss points on nodes.
334 ret = MEDpasdetempsInfo(file, name, MED_NOEUD, (med_geometrie_element) 0, 1, &ngauss, &numdt, &numo, tmp2, &dt, tmp, &local, &nmaa);
335 nb_values = MEDnVal(file, name, MED_NOEUD,(med_geometrie_element) 0, numdt, numo, const_cast<char*>(pMeshName), MED_COMPACT);
339 // Get number of gauss points on elements.
340 // For each geometry type.
341 for (int itCell = 0 ; itCell < eMaxMedMesh ; ++itCell)
344 // For each time step.
345 for (int j = 1; j <= numTimeStamps; ++j)
347 ret = MEDpasdetempsInfo(file, name, MED_MAILLE, const_cast<med_geometrie_element*>(CELL_TYPES)[itCell], j, &ngauss, &numdt, &numo, tmp2, &dt, tmp, &local, &nmaa);
348 // If we can get info on this field, it must exist.
351 nb_values = MEDnVal(file, name, MED_MAILLE,const_cast<med_geometrie_element*>(CELL_TYPES)[itCell], numdt, numo, const_cast<char*>(pMeshName), MED_COMPACT);
358 // We got what we need : don't need to go further.
367 sprintf(tmp, "%s : %d gauss points", name, nb_values);
368 sprintf(name, "%s", tmp);
371 // add the pair(name, #time stamps) to the result
372 pFields.push_back(make_pair(name, numTimeStamps));
375 //---------------------------------------------------------------------
376 // Close the MED file
377 //---------------------------------------------------------------------
378 ret = MEDfermer(file);
379 if (ret != 0) throw multipr::IOException("i/o error while closing MED file", __FILE__, __LINE__);