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_Mesh.cxx
24 * \brief see MULTIPR_Mesh.hxx
26 * \author Olivier LE ROUX - CS, Virtual Reality Dpt
31 //*****************************************************************************
33 //*****************************************************************************
35 #include "MULTIPR_Mesh.hxx"
36 #include "MULTIPR_Nodes.hxx"
37 #include "MULTIPR_Elements.hxx"
38 #include "MULTIPR_Family.hxx"
39 #include "MULTIPR_Profil.hxx"
40 #include "MULTIPR_GaussLoc.hxx"
41 #include "MULTIPR_Field.hxx"
42 #include "MULTIPR_MeshDis.hxx"
43 #include "MULTIPR_PointOfField.hxx"
44 #include "MULTIPR_DecimationFilter.hxx"
45 #include "MULTIPR_Utils.hxx"
46 #include "MULTIPR_Exceptions.hxx"
47 #include "MULTIPR_Globals.hxx"
48 #include "MULTIPR_API.hxx"
57 const med_geometrie_element CELL_TYPES[MED_NBR_GEOMETRIE_MAILLE] =
77 char CELL_NAMES[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1] =
96 // Number of points to consider when looking for significant nodes in a mesh.
97 // ie the n first nodes.
98 const int CELL_NB_NODE[MED_NBR_GEOMETRIE_MAILLE] =
119 //*****************************************************************************
120 // Class Mesh implementation
121 //*****************************************************************************
126 for (int i = 0; i < eMaxMedMesh; i++)
143 mMEDfilename[0] = '\0';
147 mMeshUName[0] = '\0';
150 mMeshType = MED_NON_STRUCTURE;
152 for (int itDim = 0 ; itDim < 3 ; itDim++)
154 mMeshBBoxMin[itDim] = numeric_limits<med_float>::quiet_NaN();
155 mMeshBBoxMax[itDim] = numeric_limits<med_float>::quiet_NaN();
158 if (mNodes != NULL) { delete mNodes; mNodes = NULL; }
160 for (int i = 0; i < eMaxMedMesh; i++)
162 if (mElements[i] != NULL)
168 for (unsigned itFam = 0 ; itFam < mFamilies.size() ; itFam++)
170 delete mFamilies[itFam];
175 for (unsigned itGroup = 0 ; itGroup < mGroups.size() ; itGroup++)
177 delete mGroups[itGroup];
180 mGroupNameToGroup.clear();
182 for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
184 delete mGaussLoc[itGaussLoc];
187 mGaussLocNameToGaussLoc.clear();
189 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
191 //delete mFields[itField];
195 for (unsigned itProfil = 0 ; itProfil < mProfils.size() ; itProfil++)
197 delete mProfils[itProfil];
201 mFlagPrintAll = false;
207 vector<string> Mesh::getNameScalarFields() const
211 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
213 Field* currentField = mFields[itField];
215 // only get scalar fields, not vectorial fields
216 // (because, currently, decimation can only be performed on scalar fields)
217 if (currentField->getNumberOfComponents() == 1)
219 res.push_back(currentField->getName());
227 int Mesh::getTimeStamps(const char* pFieldName) const
229 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
231 Field* currentField = mFields[itField];
232 if (strcmp(currentField->getName(), pFieldName) == 0)
234 return currentField->getNumberOfTimeSteps();
241 Field* Mesh::getFieldByName(const char* pFieldName, eMeshType pGeomType) const
243 if (pFieldName == NULL) throw NullArgumentException("pFieldName should not be NULL", __FILE__, __LINE__);
245 Field* retField = NULL;
248 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
250 Field* currentField = mFields[itField];
251 // Check if this is the field we want.
252 if (strncmp(pFieldName, currentField->getName(), MED_TAILLE_NOM) == 0 &&
253 (currentField->getGeomIdx() == pGeomType || currentField->isFieldOnNodes()))
256 retField = currentField;
264 void Mesh::getFieldMinMax(const char* pFieldName, float& pMin, float& pMax) const
266 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
268 Field* currentField = mFields[itField];
269 // Check if this is the field we want.
270 if (strncmp(pFieldName, currentField->getName(), MED_TAILLE_NOM) == 0)
272 currentField->getMinMax(pMin, pMax);
278 GaussLoc* Mesh::getGaussLocByName(const char* pGaussLocName) const
280 if (pGaussLocName == NULL) throw NullArgumentException("pGaussLocName should not be NULL", __FILE__, __LINE__);
282 map<string, GaussLoc*>::const_iterator itGaussLoc = mGaussLocNameToGaussLoc.find(pGaussLocName);
283 GaussLoc* retGaussLoc = NULL;
285 if (itGaussLoc != mGaussLocNameToGaussLoc.end())
287 retGaussLoc = (*itGaussLoc).second;
294 int Mesh::getNumberOfElements(eMeshType pGeomType) const
296 if (mElements[pGeomType])
298 return mElements[pGeomType]->getNumberOfElements();
306 int Mesh::getNumberOfElements() const
310 for (int i = 0; i < eMaxMedMesh; ++i)
314 accum += mElements[i]->getNumberOfElements();
320 Profil* Mesh::getProfil(const std::string pProfilName)
322 Profil* profile = NULL;
323 std::vector<Profil*>::iterator it;
324 if (pProfilName.size() > 0)
326 for (it = mProfils.begin(); it != mProfils.end(); ++it)
328 if ((*it)->getName() == pProfilName)
338 Mesh* Mesh::createFromSetOfElements(const std::set<med_int>* pSetOfElements, const char* pNewMeshName)
340 if (pNewMeshName == NULL) throw NullArgumentException("pNewMeshName should not be NULL", __FILE__, __LINE__);
342 //---------------------------------------------------------------------
344 //---------------------------------------------------------------------
345 Mesh* mesh = new Mesh();
347 //---------------------------------------------------------------------
348 // Build name of the new mesh
349 //---------------------------------------------------------------------
350 strcpy(mesh->mMeshName, pNewMeshName);
352 MULTIPR_LOG("Mesh name=|" << mesh->mMeshName << "|" << endl);
354 //---------------------------------------------------------------------
355 // Fill general infos
356 //---------------------------------------------------------------------
357 strcpy(mesh->mMeshUName, mMeshUName);
358 strcpy(mesh->mMeshDesc, mMeshDesc);
360 mesh->mMeshDim = mMeshDim;
361 mesh->mMeshType = mMeshType;
363 MULTIPR_LOG("Mesh u. name=|" << mesh->mMeshUName << "|" << endl);
364 MULTIPR_LOG("Mesh desc=|" << mesh->mMeshDesc << "|" << endl);
365 MULTIPR_LOG("Mesh dim=" << mesh->mMeshDim << endl);
366 MULTIPR_LOG("Mesh Type=" << mesh->mMeshType << endl);
368 //---------------------------------------------------------------------
369 // Build nodes and elements
370 //---------------------------------------------------------------------
371 // get all elements involved
372 for (int i = 0; i < eMaxMedMesh; ++i)
374 if (pSetOfElements[i].size() != 0)
376 mesh->mElements[i] = mElements[i]->extractSubSet(pSetOfElements[i]);
377 MULTIPR_LOG((*(mesh->mElements[i])) << endl);
381 // get all nodes involved
382 set<med_int> setOfNodes;
383 for (int i = 0; i < eMaxMedMesh; ++i)
385 if (mElements[i] != NULL && mesh->mElements[i] != NULL)
387 const set<med_int>& curSetOfNodes = mesh->mElements[i]->getSetOfNodes();
388 setOfNodes.insert(curSetOfNodes.begin(), curSetOfNodes.end());
391 mesh->mNodes = mNodes->extractSubSet(setOfNodes);
392 MULTIPR_LOG((*(mesh->mNodes)) << endl);
394 //---------------------------------------------------------------------
396 //---------------------------------------------------------------------
397 for (int i = 0; i < eMaxMedMesh; ++i)
399 if (mElements[i] != NULL && mesh->mElements[i] != NULL)
401 mesh->mElements[i]->remap(setOfNodes);
402 MULTIPR_LOG((*(mesh->mElements[i])) << endl);
407 //---------------------------------------------------------------------
409 //---------------------------------------------------------------------
410 MULTIPR_LOG("Build fam.:" << endl);
411 // get families of nodes
413 set<med_int> famOfNodes = mesh->mNodes->getSetOfFamilies();
414 for (set<med_int>::iterator itFam = famOfNodes.begin() ; itFam != famOfNodes.end() ; itFam++)
416 Family* famSrc = mFamIdToFam[*itFam];
417 if (mesh->mFamIdToFam.find(famSrc->getId()) == mesh->mFamIdToFam.end())
419 Family* famDest = famSrc->extractGroup(NULL);
420 mesh->mFamilies.push_back(famDest);
421 mesh->mFamIdToFam[famDest->getId()] = famDest;
426 // get families of elements
428 set<med_int> famOfElt;
429 for (int i = 0; i < eMaxMedMesh; ++i)
431 if (mElements[i] != NULL && mesh->mElements[i] != NULL)
433 set<med_int> curSetOfFamilies = mesh->mElements[i]->getSetOfFamilies();
434 famOfElt.insert(curSetOfFamilies.begin(), curSetOfFamilies.end());
437 for (set<med_int>::iterator itFam = famOfElt.begin() ; itFam != famOfElt.end() ; itFam++)
439 Family* famSrc = mFamIdToFam[*itFam];
440 if (mesh->mFamIdToFam.find(famSrc->getId()) == mesh->mFamIdToFam.end())
442 Family* famDest = famSrc->extractGroup(NULL);
443 mesh->mFamilies.push_back(famDest);
444 mesh->mFamIdToFam[famDest->getId()] = famDest;
449 MULTIPR_LOG("Finalize:");
451 // fill families with elements and build groups
452 //mesh->finalizeFamiliesAndGroups();
456 //---------------------------------------------------------------------
458 //---------------------------------------------------------------------
459 for (std::vector<Profil*>::iterator it = mProfils.begin(); it != mProfils.end(); ++it)
461 Profil* lProfil = new Profil();
462 lProfil->create((*it)->getName());
463 std::set<med_int> lSet;
464 if ((*it)->getBinding() == OnNodes)
466 (*it)->extractSetOfElement(setOfNodes, lSet);
470 (*it)->extractSetOfElement(pSetOfElements[lProfil->getGeomIdx()], lSet);
472 if (lSet.size() == 0)
478 mesh->mProfils.push_back(lProfil);
481 //---------------------------------------------------------------------
482 // Create new fields and collect Gauss
483 //---------------------------------------------------------------------
485 set<string> newSetOfGauss;
486 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
488 Field* currentField = mFields[itField];
490 Field* newField = NULL;
491 if (currentField->isFieldOnNodes())
493 newField = currentField->extractSubSet(setOfNodes);
497 if (pSetOfElements[currentField->getGeomIdx()].size() != 0)
499 newField = currentField->extractSubSet(pSetOfElements[currentField->getGeomIdx()]);
503 if (newField != NULL && !newField->isEmpty())
505 mesh->mFields.push_back(newField);
506 newField->getSetOfGaussLoc(newSetOfGauss);
509 MULTIPR_LOG("Collect fields: ok: #gauss=" << newSetOfGauss.size() << endl);
511 //---------------------------------------------------------------------
513 //---------------------------------------------------------------------
514 for (set<string>::iterator itSet = newSetOfGauss.begin() ; itSet != newSetOfGauss.end(); itSet++)
516 const string& keyName = (*itSet);
518 GaussLoc* gaussLoc = getGaussLocByName(keyName.c_str());
519 if (gaussLoc != NULL)
521 GaussLoc* copyGaussLoc = new GaussLoc(*gaussLoc);
522 mesh->mGaussLoc.push_back(copyGaussLoc);
523 mesh->mGaussLocNameToGaussLoc.insert(make_pair(copyGaussLoc->getName(), copyGaussLoc));
527 //---------------------------------------------------------------------
529 //---------------------------------------------------------------------
530 mesh->mNodes->getBBox(mesh->mMeshBBoxMin, mesh->mMeshBBoxMax);
536 Mesh* Mesh::createFromGroup(const Group* pGroup, const char* pNewMeshName)
538 if (pGroup == NULL) throw NullArgumentException("pGroup should not be NULL", __FILE__, __LINE__);
539 if (pNewMeshName == NULL) throw NullArgumentException("pNewMeshName should not be NULL", __FILE__, __LINE__);
540 if (strlen(pNewMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("pNewMeshName length too long", __FILE__, __LINE__);
541 //---------------------------------------------------------------------
543 //---------------------------------------------------------------------
544 Mesh* mesh = new Mesh();
546 //---------------------------------------------------------------------
547 // Build name of the new mesh
548 //---------------------------------------------------------------------
549 strcpy(mesh->mMeshName, pNewMeshName);
551 MULTIPR_LOG("Mesh name=|" << mesh->mMeshName << "|" << endl);
553 //---------------------------------------------------------------------
554 // Fill general infos
555 //---------------------------------------------------------------------
556 strcpy(mesh->mMeshUName, mMeshUName);
557 strcpy(mesh->mMeshDesc, mMeshDesc);
559 mesh->mMeshDim = mMeshDim;
560 mesh->mMeshType = mMeshType;
562 MULTIPR_LOG("Mesh u. name=|" << mesh->mMeshUName << "|" << endl);
563 MULTIPR_LOG("Mesh desc=|" << mesh->mMeshDesc << "|" << endl);
564 MULTIPR_LOG("Mesh dim=" << mesh->mMeshDim << endl);
565 MULTIPR_LOG("Mesh Type=" << mesh->mMeshType << endl);
567 //---------------------------------------------------------------------
568 // Build nodes and elements
569 //---------------------------------------------------------------------
570 // Get all elements involved
571 std::set< med_int>* setOfEltList = new std::set< med_int>[eMaxMedMesh];
572 for (int i = 0; i < eMaxMedMesh; ++i)
574 if (mElements[i] != NULL)
576 const set<med_int> setOfElt = pGroup->getSetOfElt((eMeshType)i);
577 mesh->mElements[i] = mElements[i]->extractSubSet(setOfElt);
578 setOfEltList[i] = setOfElt;
582 // Get all nodes involved
583 // The nodes a common for all elements so we don't need to store them separately.
584 set<med_int> setOfNodes;
585 for (int i = 0; i < eMaxMedMesh; ++i)
587 if (mesh->mElements[i] != NULL)
589 const set<med_int>& curSetOfNodes = mesh->mElements[i]->getSetOfNodes();
590 setOfNodes.insert(curSetOfNodes.begin(), curSetOfNodes.end());
593 mesh->mNodes = mNodes->extractSubSet(setOfNodes);
595 // We need this for the optimized memory management.
596 this->mGaussIndex.push_back(IndexPair(setOfEltList, setOfNodes));
597 //---------------------------------------------------------------------
599 //---------------------------------------------------------------------
600 for (int i = 0; i < eMaxMedMesh; ++i)
602 if (mesh->mElements[i] != NULL)
604 mesh->mElements[i]->remap(setOfNodes);
608 //---------------------------------------------------------------------
610 //---------------------------------------------------------------------
611 MULTIPR_LOG("Build fam.:" << endl);
612 // get families of nodes
614 set<med_int> famOfNodes = mesh->mNodes->getSetOfFamilies();
615 for (set<med_int>::iterator itFam = famOfNodes.begin() ; itFam != famOfNodes.end() ; itFam++)
617 Family* famSrc = mFamIdToFam[*itFam];
618 Family* famDest = famSrc->extractGroup(pGroup->getName().c_str());
619 mesh->mFamilies.push_back(famDest);
623 // get families of elements
625 set<med_int> famOfElt;
626 for (int i = 0; i < eMaxMedMesh; ++i)
628 if (mesh->mElements[i] != NULL)
630 set<med_int> curSetOfFamilies = mesh->mElements[i]->getSetOfFamilies();
631 famOfElt.insert(curSetOfFamilies.begin(), curSetOfFamilies.end());
634 for (set<med_int>::iterator itFam = famOfElt.begin() ; itFam != famOfElt.end() ; itFam++)
636 Family* famSrc = mFamIdToFam[*itFam];
637 Family* famDest = famSrc->extractGroup(pGroup->getName().c_str());
638 mesh->mFamilies.push_back(famDest);
642 MULTIPR_LOG("Finalize:");
644 // fill families with elements and build groups
645 mesh->finalizeFamiliesAndGroups();
649 //---------------------------------------------------------------------
651 //---------------------------------------------------------------------
652 for (std::vector<Profil*>::iterator it = mProfils.begin(); it != mProfils.end(); ++it)
654 Profil* lProfil = new Profil();
655 lProfil->create((*it)->getName());
656 std::set<med_int> lSet;
657 if ((*it)->getBinding() == OnNodes)
659 (*it)->extractSetOfElement(setOfNodes, lSet);
663 (*it)->extractSetOfElement(setOfEltList[lProfil->getGeomIdx()], lSet);
665 if (lSet.size() == 0)
671 mesh->mProfils.push_back(lProfil);
674 //---------------------------------------------------------------------
675 // Create new fields and collect Gauss
676 //---------------------------------------------------------------------
678 set<string> newSetOfGauss;
679 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
681 Field* currentField = mFields[itField];
684 if (currentField->isFieldOnNodes())
686 newField = currentField->extractSubSet(setOfNodes);
690 if (setOfEltList[currentField->getGeomIdx()].size() != 0)
692 newField = currentField->extractSubSet(setOfEltList[currentField->getGeomIdx()]);
696 if (!newField->isEmpty())
698 mesh->mFields.push_back(newField);
699 newField->getSetOfGaussLoc(newSetOfGauss);
702 // Get gauss locs for optimized fields reading.
703 if (mFields.size() == 0)
705 for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
707 const string& gaussLocName = mGaussLoc[itGaussLoc]->getName();
709 if (gaussLocName.length() != 0)
711 newSetOfGauss.insert(gaussLocName);
715 MULTIPR_LOG("Collect fields: ok: #gauss=" << newSetOfGauss.size() << endl);
717 //---------------------------------------------------------------------
719 //---------------------------------------------------------------------
720 for (set<string>::iterator itSet = newSetOfGauss.begin() ; itSet != newSetOfGauss.end(); itSet++)
722 const string& keyName = (*itSet);
724 GaussLoc* gaussLoc = getGaussLocByName(keyName.c_str());
725 if (gaussLoc != NULL)
727 GaussLoc* copyGaussLoc = new GaussLoc(*gaussLoc);
728 mesh->mGaussLoc.push_back(copyGaussLoc);
729 mesh->mGaussLocNameToGaussLoc.insert(make_pair(copyGaussLoc->getName(), copyGaussLoc));
733 //---------------------------------------------------------------------
735 //---------------------------------------------------------------------
736 mesh->mNodes->getBBox(mesh->mMeshBBoxMin, mesh->mMeshBBoxMax);
742 Mesh* Mesh::createFromFamily(const Family* pFamily, const char* pNewMeshName)
744 if (pFamily == NULL) throw NullArgumentException("pFamily should not be NULL", __FILE__, __LINE__);
745 if (pNewMeshName == NULL) throw NullArgumentException("pNewMeshName should not be NULL", __FILE__, __LINE__);
746 if (strlen(pNewMeshName) > MED_TAILLE_NOM)
749 sprintf(msg, "pNewMeshName length (=%d) too long: max size allowed is %d", strlen(pNewMeshName), MED_TAILLE_NOM);
750 throw IllegalArgumentException(msg, __FILE__, __LINE__);
752 //---------------------------------------------------------------------
754 //---------------------------------------------------------------------
755 Mesh* mesh = new Mesh();
757 //---------------------------------------------------------------------
758 // Build name of the new mesh
759 //---------------------------------------------------------------------
760 strcpy(mesh->mMeshName, pNewMeshName);
762 MULTIPR_LOG("Mesh name=|" << mesh->mMeshName << "|" << endl);
764 //---------------------------------------------------------------------
765 // Fill general infos
766 //---------------------------------------------------------------------
767 strcpy(mesh->mMeshUName, mMeshUName);
768 strcpy(mesh->mMeshDesc, mMeshDesc);
770 mesh->mMeshDim = mMeshDim;
771 mesh->mMeshType = mMeshType;
773 MULTIPR_LOG("Mesh u. name=|" << mesh->mMeshUName << "|" << endl);
774 MULTIPR_LOG("Mesh desc=|" << mesh->mMeshDesc << "|" << endl);
775 MULTIPR_LOG("Mesh dim=" << mesh->mMeshDim << endl);
776 MULTIPR_LOG("Mesh Type=" << mesh->mMeshType << endl);
778 //---------------------------------------------------------------------
779 // Build nodes and elements
780 //---------------------------------------------------------------------
781 // Get all elements involved
782 std::set< med_int>* setOfEltList = new std::set< med_int>[eMaxMedMesh];
783 for (int i = 0; i < eMaxMedMesh; ++i)
785 if (mElements[i] != NULL)
787 const set<med_int> setOfElt = pFamily->getSetOfElt((eMeshType)i);
788 mesh->mElements[i] = mElements[i]->extractSubSet(setOfElt);
789 setOfEltList[i] = setOfElt;
793 // Get all nodes involved
794 // The nodes a common for all elements so we don't need to store them separately.
795 set<med_int> setOfNodes;
796 for (int i = 0; i < eMaxMedMesh; ++i)
798 if (mesh->mElements[i] != NULL)
800 const set<med_int>& curSetOfNodes = mesh->mElements[i]->getSetOfNodes();
801 setOfNodes.insert(curSetOfNodes.begin(), curSetOfNodes.end());
804 mesh->mNodes = mNodes->extractSubSet(setOfNodes);
806 // We need this for the optimized memory management.
807 this->mGaussIndex.push_back(IndexPair(setOfEltList, setOfNodes));
808 //---------------------------------------------------------------------
810 //---------------------------------------------------------------------
811 for (int i = 0; i < eMaxMedMesh; ++i)
813 if (mesh->mElements[i] != NULL)
815 mesh->mElements[i]->remap(setOfNodes);
819 //---------------------------------------------------------------------
821 //---------------------------------------------------------------------
822 MULTIPR_LOG("Build fam.:" << endl);
823 // get families of nodes
824 Family* lFam = new Family(*pFamily);
825 mesh->mFamilies.push_back(lFam);
827 MULTIPR_LOG("Finalize:");
829 // fill families with elements and build groups
830 mesh->finalizeFamiliesAndGroups();
834 //---------------------------------------------------------------------
836 //---------------------------------------------------------------------
837 for (std::vector<Profil*>::iterator it = mProfils.begin(); it != mProfils.end(); ++it)
839 Profil* lProfil = new Profil();
840 lProfil->create((*it)->getName());
841 std::set<med_int> lSet;
842 if ((*it)->getBinding() == OnNodes)
844 (*it)->extractSetOfElement(setOfNodes, lSet);
848 (*it)->extractSetOfElement(setOfEltList[lProfil->getGeomIdx()], lSet);
850 if (lSet.size() == 0)
856 mesh->mProfils.push_back(lProfil);
859 //---------------------------------------------------------------------
860 // Create new fields and collect Gauss
861 //---------------------------------------------------------------------
863 set<string> newSetOfGauss;
864 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
866 Field* currentField = mFields[itField];
869 if (currentField->isFieldOnNodes())
871 newField = currentField->extractSubSet(setOfNodes);
875 if (setOfEltList[currentField->getGeomIdx()].size() != 0)
877 newField = currentField->extractSubSet(setOfEltList[currentField->getGeomIdx()]);
881 if (!newField->isEmpty())
883 mesh->mFields.push_back(newField);
884 newField->getSetOfGaussLoc(newSetOfGauss);
887 // Get gauss locs for optimized fields reading.
888 if (mFields.size() == 0)
890 for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
892 const string& gaussLocName = mGaussLoc[itGaussLoc]->getName();
894 if (gaussLocName.length() != 0)
896 newSetOfGauss.insert(gaussLocName);
900 MULTIPR_LOG("Collect fields: ok: #gauss=" << newSetOfGauss.size() << endl);
902 //---------------------------------------------------------------------
904 //---------------------------------------------------------------------
905 for (set<string>::iterator itSet = newSetOfGauss.begin() ; itSet != newSetOfGauss.end(); itSet++)
907 const string& keyName = (*itSet);
909 GaussLoc* gaussLoc = getGaussLocByName(keyName.c_str());
910 if (gaussLoc != NULL)
912 GaussLoc* copyGaussLoc = new GaussLoc(*gaussLoc);
913 mesh->mGaussLoc.push_back(copyGaussLoc);
914 mesh->mGaussLocNameToGaussLoc.insert(make_pair(copyGaussLoc->getName(), copyGaussLoc));
918 //---------------------------------------------------------------------
920 //---------------------------------------------------------------------
921 mesh->mNodes->getBBox(mesh->mMeshBBoxMin, mesh->mMeshBBoxMax);
926 Mesh* Mesh::mergePartial(vector<Mesh*> pMeshes, const char* pFieldName, int pFieldIt)
928 if (pMeshes.size() == 0) throw IllegalArgumentException("list must contain one mesh at least", __FILE__, __LINE__);
930 //---------------------------------------------------------------------
932 //---------------------------------------------------------------------
933 Mesh* mesh = new Mesh();
935 //---------------------------------------------------------------------
936 // Build name of the new mesh
937 //---------------------------------------------------------------------
938 strcpy(mesh->mMeshName, mMeshName);
940 //---------------------------------------------------------------------
941 // Merge general infos
942 //---------------------------------------------------------------------
943 strcpy(mesh->mMeshUName, mMeshUName);
944 strcpy(mesh->mMeshDesc, mMeshDesc);
946 mesh->mMeshDim = mMeshDim;
947 mesh->mMeshType = mMeshType;
949 //---------------------------------------------------------------------
950 // Merge nodes and elements
951 //---------------------------------------------------------------------
952 vector<Nodes*> nodes;
953 vector<Elements*> elements[eMaxMedMesh];
954 vector<int> offsets[eMaxMedMesh];
956 int offset[eMaxMedMesh];
957 for (unsigned j = 0; j < eMaxMedMesh; ++j)
959 offset[j] = mNodes->getNumberOfNodes();
962 for (unsigned i = 0 ; i < pMeshes.size() ; i++)
964 if (mMeshDim != pMeshes[i]->mMeshDim) throw IllegalStateException("all meshes should have same dimension", __FILE__, __LINE__);
965 if (mMeshType != pMeshes[i]->mMeshType) throw IllegalStateException("all meshes should have same type", __FILE__, __LINE__);
968 nodes.push_back(pMeshes[i]->mNodes);
969 for (unsigned j = 0; j < eMaxMedMesh; ++j)
972 if (pMeshes[i]->mElements[j] != NULL)
974 elements[j].push_back(pMeshes[i]->mElements[j]);
975 offsets[j].push_back(offset[j]);
977 offset[j] += pMeshes[i]->mNodes->getNumberOfNodes();
981 mesh->mNodes = mNodes->mergePartial(nodes);
982 for (unsigned i = 0; i < eMaxMedMesh; ++i)
984 if (elements[i].size() != 0)
986 if (mElements[i] == NULL)
988 mElements[i] = new Elements(CELL_TYPES[i]);
989 mElements[i]->mergePartial(elements[i].front(), offsets[i].front());
990 elements[i].erase(elements[i].begin());
992 mesh->mElements[i] = mElements[i]->mergePartial(elements[i], offsets[i]);
994 else if (mElements[i] != NULL)
996 mesh->mElements[i] = mElements[i];
1001 //---------------------------------------------------------------------
1003 //---------------------------------------------------------------------
1004 for (unsigned i = 0 ; i < mFamilies.size() ; i++)
1006 Family* family = new Family(*(mFamilies[i]));
1007 mesh->mFamilies.push_back(family);
1008 mesh->mFamIdToFam.insert(make_pair(family->getId(), family));
1011 for (unsigned j = 0 ; j < pMeshes.size() ; j++)
1013 for (unsigned i = 0 ; i < pMeshes[j]->mFamilies.size() ; i++)
1015 // test if there is a fimaly with the same id
1016 map<med_int, Family*>::iterator itFam = mesh->mFamIdToFam.find(pMeshes[j]->mFamilies[i]->getId());
1018 if (itFam == mesh->mFamIdToFam.end())
1020 // id not found: create a new family
1021 Family* family = new Family(*(pMeshes[j]->mFamilies[i]));
1022 mesh->mFamilies.push_back(family);
1023 mesh->mFamIdToFam.insert(make_pair(family->getId(), family));
1028 //---------------------------------------------------------------------
1030 //---------------------------------------------------------------------
1033 vector<Field*> fields;
1034 for (unsigned i = 0 ; i < pMeshes.size() ; i++)
1036 for (std::vector<Field*>::iterator it = pMeshes[i]->mFields.begin();
1037 it != pMeshes[i]->mFields.end(); ++it)
1039 if (strcmp((*it)->getName(), pFieldName) == 0)
1041 fields.push_back(*it);
1046 bool hasField = false;
1047 for (std::vector<Field*>::iterator it = mFields.begin();
1048 it != mFields.end(); ++it)
1050 if (strcmp((*it)->getName(), pFieldName) == 0)
1052 Field* field = (*it)->merge(fields, pFieldIt);
1053 mesh->mFields.push_back(field);
1058 if (hasField == false)
1060 Field* lField = fields.back();
1062 Field* field = lField->merge(fields, pFieldIt);
1063 mesh->mFields.push_back(field);
1066 //---------------------------------------------------------------------
1067 // Merge Gauss infos
1068 //---------------------------------------------------------------------
1069 // WARNING: assume Gauss infos are the same for the two meshes.
1070 for (unsigned i = 0 ; i < mGaussLoc.size() ; i++)
1072 GaussLoc* copyGaussLoc = new GaussLoc(*(mGaussLoc[i]));
1073 mesh->mGaussLoc.push_back(copyGaussLoc);
1074 mesh->mGaussLocNameToGaussLoc.insert(make_pair(copyGaussLoc->getName(), copyGaussLoc));
1081 MeshDis* Mesh::splitGroupsOfElements()
1083 MeshDis* meshDis = new MeshDis();
1084 meshDis->setSequentialMEDFilename(mMEDfilename);
1086 // get prefix from the original MED filename
1087 string strPrefix = removeExtension(mMEDfilename, ".med");
1092 for (unsigned itGroup = 0 ; itGroup < mGroups.size() ; itGroup++)
1094 Group* currentGroup = mGroups[itGroup];
1096 // skip this group if it is a group of nodes
1097 if (currentGroup->isGroupOfNodes())
1099 this->mGaussIndex.push_back(IndexPair());
1103 char strPartName[256];
1104 sprintf(strPartName, "%s_%d", mMeshName, numGroup);
1106 char strMEDfilename[256];
1107 char strMedGroup[256];
1109 for (i = 0; currentGroup->getName()[i] && currentGroup->getName()[i] != ' '; ++i)
1111 strMedGroup[i] = currentGroup->getName()[i];
1113 strMedGroup[i] = '\0';
1114 sprintf(strMEDfilename, "%s_%s.med", strPrefix.c_str(), strMedGroup);
1116 Mesh* mesh = createFromGroup(currentGroup, mMeshName);
1118 // skip the group which contain all the others groups, even if it contains only 1 group
1119 if (mesh->getNumberOfElements() == this->getNumberOfElements())
1121 for (int i = 0; i < eMaxMedMesh; ++i)
1123 this->mGaussIndex.back().first[i].clear();
1125 this->mGaussIndex.back().second.clear();
1131 MeshDisPart::MULTIPR_WRITE_MESH,
1141 if (mGroups.size() == 0)
1143 for (unsigned itFam = 0; itFam < mFamilies.size(); ++itFam)
1146 Family* currentFam = mFamilies[itFam];
1148 // skip this family if it is a family of nodes
1149 if (currentFam->isFamilyOfNodes())
1151 this->mGaussIndex.push_back(IndexPair());
1155 char strPartName[256];
1156 sprintf(strPartName, "%s_%d", mMeshName, numGroup);
1158 char strMEDfilename[256];
1159 char strMedFam[256];
1161 for (i = 0; currentFam->getName()[i] && currentFam->getName()[i] != ' '; ++i)
1163 strMedFam[i] = currentFam->getName()[i];
1165 strMedFam[i] = '\0';
1166 sprintf(strMEDfilename, "%s_%s.med", strPrefix.c_str(), strMedFam);
1168 Mesh* mesh = createFromFamily(currentFam, mMeshName);
1171 MeshDisPart::MULTIPR_WRITE_MESH,
1187 Mesh* Mesh::decimate(
1188 const char* pFilterName,
1190 const char* pNameNewMesh)
1192 //---------------------------------------------------------------------
1194 //---------------------------------------------------------------------
1195 if (pFilterName == NULL) throw NullArgumentException("pFilterName should not be NULL", __FILE__, __LINE__);
1196 if (pArgv == NULL) throw NullArgumentException("pArgv should not be NULL", __FILE__, __LINE__);
1197 if (pNameNewMesh == NULL) throw NullArgumentException("pNameNewMesh should not be NULL", __FILE__, __LINE__);
1199 //---------------------------------------------------------------------
1200 // Instanciate filter used for decimation
1201 //---------------------------------------------------------------------
1202 DecimationFilter* filter = DecimationFilter::create(pFilterName);
1204 //---------------------------------------------------------------------
1205 // Create new mesh by decimating current one
1206 //---------------------------------------------------------------------
1207 Mesh* decimatedMesh = filter->apply(this, pArgv, pNameNewMesh);
1209 //---------------------------------------------------------------------
1211 //---------------------------------------------------------------------
1214 return decimatedMesh;
1219 void Mesh::getAllPointsOfField(Field* pField, int pTimeStepIt, std::vector<PointOfField>& pPoints, eMeshType pGeomType)
1221 //---------------------------------------------------------------------
1223 //---------------------------------------------------------------------
1224 if (pField == NULL) throw NullArgumentException("field should not be NULL", __FILE__, __LINE__);
1225 if (pTimeStepIt < 1) throw IllegalArgumentException("invalid field iteration; should be >= 1", __FILE__, __LINE__);
1227 if (mMeshDim != 3) throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
1228 if (pField->getType() != MED_FLOAT64) throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
1229 if (pField->getNumberOfComponents() != 1) throw UnsupportedOperationException("field have more than 1 component (vectorial field, expected scalar field)", __FILE__, __LINE__);
1231 //---------------------------------------------------------------------
1233 //---------------------------------------------------------------------
1235 const std::string& profilName = pField->getProfil(pTimeStepIt);
1236 std::vector<Profil*>::iterator it;
1237 Profil* profile = NULL;
1239 if (profilName.size() > 0)
1241 for (it = mProfils.begin(); it != mProfils.end(); ++it)
1243 if ((*it)->getName() == profilName)
1249 if (it == mProfils.end()) throw IllegalStateException("Can't find the profile in the mesh.", __FILE__, __LINE__);
1253 //---------------------------------------------------------------------
1255 //---------------------------------------------------------------------
1257 if (pField->isFieldOnNodes())
1259 //-------------------------------------------------------------
1260 // Case 1: field of nodes
1261 //-------------------------------------------------------------
1262 if (mNodes == NULL) throw IllegalStateException("no nodes in the current mesh", __FILE__, __LINE__);
1265 for (int itNode = 0, size = mNodes->getNumberOfNodes() ; itNode < size ; itNode++)
1267 if (profile && profile->find(itNode) == false)
1271 // collect coordinates and value of the point
1272 const med_float* coo = mNodes->getCoordinates(itNode);
1274 const med_float* val =
1275 reinterpret_cast<const med_float*>(pField->getValue(pTimeStepIt, count + 1));
1277 pPoints.push_back(PointOfField(coo[0], coo[1], coo[2], val[0]));
1283 //-------------------------------------------------------------
1284 // Case 2: field of elements
1285 //-------------------------------------------------------------
1287 if (mElements[pGeomType] == NULL) throw IllegalStateException("no elements in the current mesh", __FILE__, __LINE__);
1289 const string& nameGaussLoc = pField->getNameGaussLoc(pTimeStepIt);
1290 GaussLoc* gaussLoc = getGaussLocByName(nameGaussLoc.c_str());
1291 if (gaussLoc == NULL) throw IllegalStateException("no Gauss localization for these elements", __FILE__, __LINE__);
1293 int numGauss = pField->getNumberOfGaussPointsByElement(pTimeStepIt);
1294 int size = gaussLoc->getDim() * gaussLoc->getNumGaussPoints();
1295 med_float* cooGaussPts = new med_float[size];
1297 int dim = mElements[pGeomType]->getTypeOfPrimitives() / 100;
1298 //int numNodes = mElements[pGeomType]->getTypeOfPrimitives() % 100;
1299 size = dim * numGauss;
1300 med_float* cooNodes = new med_float[size];
1302 // for each elements
1303 for (int itElt = 0, size = mElements[pGeomType]->getNumberOfElements() ; itElt < size ; itElt++)
1305 if (profile && profile->find(itElt) == false)
1309 // get coordinates of nodes of the current elements
1310 mElements[pGeomType]->getCoordinates(itElt, mNodes, cooNodes, numGauss);
1312 // compute coordinates of gauss points
1313 gaussLoc->getCoordGaussPoints(cooNodes, cooGaussPts, numGauss);
1315 const med_float* val =
1316 reinterpret_cast<const med_float*>(pField->getValue(pTimeStepIt, count + 1));
1318 // for each point of Gauss of the element
1319 med_float* srcCoo = cooGaussPts;
1320 for (int itPtGauss = 0 ; itPtGauss < numGauss ; itPtGauss++)
1322 pPoints.push_back(PointOfField(srcCoo[0], srcCoo[1], srcCoo[2], val[itPtGauss]));
1329 delete[] cooGaussPts;
1334 float Mesh::evalDefaultRadius(int pN) const
1336 if (mFields.size() == 0) return 1.0f;
1338 //---------------------------------------------------------------------
1339 // Compute default radius
1340 //---------------------------------------------------------------------
1342 med_float volumeBBox =
1343 (mMeshBBoxMax[0] - mMeshBBoxMin[0]) *
1344 (mMeshBBoxMax[1] - mMeshBBoxMin[1]) *
1345 (mMeshBBoxMax[2] - mMeshBBoxMin[2]);
1347 if (isnan(volumeBBox))
1352 const med_float k = 0.8; // considered 80% of the volume
1354 // get number of gauss points in the field
1357 Field* anyField = mFields[mFields.size()-1];
1358 int numTimeSteps = anyField->getNumberOfTimeSteps();
1360 int numGaussPoints = getNumberOfElements() * anyField->getNumberOfGaussPointsByElement(numTimeSteps-1);
1362 med_float radius = med_float(pow( (3.0/4.0) * pN * k * volumeBBox / (3.1415 * numGaussPoints), 1.0/3.0));
1364 return float(radius);
1372 void Mesh::_openMEDFile(const char* pMEDfilename, med_mode_acces pMEDModeAccess)
1376 //---------------------------------------------------------------------
1378 //---------------------------------------------------------------------
1379 MULTIPR_LOG("Check arguments: ");
1380 if (pMEDfilename == NULL) throw NullArgumentException("pMEDfilename should not be NULL", __FILE__, __LINE__);
1381 MULTIPR_LOG("OK\n");
1383 strncpy(mMEDfilename, pMEDfilename, 256);
1385 //---------------------------------------------------------------------
1386 // Open MED file (READ_ONLY)
1387 //---------------------------------------------------------------------
1388 MULTIPR_LOG("Open MED file: ");
1389 mMEDfile = MEDouvrir(mMEDfilename, pMEDModeAccess);
1390 if (mMEDfile <= 0) throw FileNotFoundException("MED file not found", __FILE__, __LINE__);
1391 MULTIPR_LOG("OK\n");
1393 //---------------------------------------------------------------------
1394 // Check valid HDF format
1395 //---------------------------------------------------------------------
1396 MULTIPR_LOG("Format HDF: ");
1397 if (MEDformatConforme(mMEDfilename) != 0) throw IOException("invalid file", __FILE__, __LINE__);
1398 MULTIPR_LOG("OK\n");
1400 //---------------------------------------------------------------------
1402 //---------------------------------------------------------------------
1403 MULTIPR_LOG("MED version: ");
1404 med_int verMajor, verMinor, verRelease;
1405 med_err ret = MEDversionLire(mMEDfile, &verMajor, &verMinor, &verRelease);
1406 if (ret != 0) throw IOException("error while reading MED version", __FILE__, __LINE__);
1407 MULTIPR_LOG(verMajor << "." << verMinor << "." << verRelease << ": OK\n");
1411 void Mesh::_readSequentialMED(const char* pMeshName, bool pReadFields)
1415 //---------------------------------------------------------------------
1417 //---------------------------------------------------------------------
1418 MULTIPR_LOG("Check arguments: ");
1419 if (pMeshName == NULL) throw NullArgumentException("pMeshName should not be NULL", __FILE__, __LINE__);
1420 MULTIPR_LOG("OK\n");
1422 strncpy(mMeshName, pMeshName, MED_TAILLE_NOM);
1424 //---------------------------------------------------------------------
1426 //---------------------------------------------------------------------
1427 MULTIPR_LOG("Profils: ");
1428 med_int nbProfils = MEDnProfil(mMEDfile);
1429 for (med_int i = 1; i <= nbProfils; ++i)
1431 Profil* profil = new Profil();
1432 profil->readMED(mMEDfile, i);
1433 profil->readProfilBinding(mMEDfile, const_cast<char*>(pMeshName));
1434 this->mProfils.push_back(profil);
1436 MULTIPR_LOG("OK\n");
1438 //---------------------------------------------------------------------
1439 // Read all Gauss localizations
1440 //---------------------------------------------------------------------
1441 MULTIPR_LOG("Gauss localizations: ");
1444 //---------------------------------------------------------------------
1445 // Read scalars (should be 0)
1446 //---------------------------------------------------------------------
1447 MULTIPR_LOG("Scalars: ");
1448 med_int nbScalars = MEDnScalaire(mMEDfile);
1449 if (nbScalars != 0) throw UnsupportedOperationException("scalars information not yet implemented", __FILE__, __LINE__);
1450 MULTIPR_LOG(nbScalars << ": OK\n");
1452 //---------------------------------------------------------------------
1454 //---------------------------------------------------------------------
1455 // read number of meshes
1456 MULTIPR_LOG("Num meshes: ");
1457 med_int nbMeshes = MEDnMaa(mMEDfile);
1458 if (nbMeshes <= 0) throw IOException("i/o error while reading number of meshes in MED file", __FILE__, __LINE__);
1459 MULTIPR_LOG(nbMeshes << ": OK\n");
1461 med_int meshIndex = -1;
1462 // iteration over mesh to find the mesh we want
1463 // for each mesh in the file (warning: first mesh is number 1)
1464 for (int itMesh = 1 ; itMesh <= nbMeshes ; itMesh++)
1466 char meshName[MED_TAILLE_NOM + 1];
1476 if (ret != 0) throw IOException("i/o error while reading mesh information in MED file", __FILE__, __LINE__);
1477 MULTIPR_LOG("Mesh: |" << meshName << "|");
1479 // test if the current mesh is the mesh we want
1480 if (strcmp(pMeshName, meshName) == 0)
1482 // *** mesh found ***
1483 MULTIPR_LOG(" OK (found)\n");
1489 // not the mesh we want: skip this mesh
1490 MULTIPR_LOG(" skipped\n");
1494 if (meshIndex == -1)
1496 throw IllegalStateException("mesh not found in the given MED file", __FILE__, __LINE__);
1499 //---------------------------------------------------------------------
1500 // Check mesh validity
1501 //---------------------------------------------------------------------
1502 // dimension of the mesh must be 3 (= 3D mesh)
1503 MULTIPR_LOG("Mesh is 3D: ");
1504 if (mMeshDim != 3) throw UnsupportedOperationException("dimension of the mesh should be 3; other dimension not yet implemented", __FILE__, __LINE__);
1505 MULTIPR_LOG("OK\n");
1507 // mesh must not be a grid
1508 MULTIPR_LOG("Mesh is not a grid: ");
1509 if (mMeshType != MED_NON_STRUCTURE)
1510 throw UnsupportedOperationException("grid not supported", __FILE__, __LINE__);
1511 MULTIPR_LOG("OK\n");
1513 med_connectivite connectivite = MED_NOD; // NODAL CONNECTIVITY ONLY
1514 // Read all the supported geometry type.
1515 for (int itCell = 0; itCell < eMaxMedMesh ; ++itCell)
1517 med_int meshNumCells = MEDnEntMaa(
1526 //---------------------------------------------------------------------
1528 //---------------------------------------------------------------------
1529 if (meshNumCells > 0)
1531 mElements[itCell] = new Elements();
1532 mElements[itCell]->readMED(mMEDfile, mMeshName, mMeshDim, MED_MAILLE, CELL_TYPES[itCell]);
1535 // everything is OK...
1537 //---------------------------------------------------------------------
1538 // Check num joint = 0
1539 //---------------------------------------------------------------------
1540 MULTIPR_LOG("Num joints: ");
1541 med_int numJoints = MEDnJoint(mMEDfile, mMeshName);
1542 MULTIPR_LOG(numJoints << ": OK\n");
1544 //---------------------------------------------------------------------
1545 // Check num equivalence = 0
1546 //---------------------------------------------------------------------
1547 MULTIPR_LOG("Num equivalences: ");
1548 med_int numEquiv = MEDnEquiv(mMEDfile, mMeshName);
1549 MULTIPR_LOG(numEquiv << ": OK\n");
1551 //---------------------------------------------------------------------
1553 //---------------------------------------------------------------------
1554 mNodes = new Nodes();
1555 mNodes->readMED(mMEDfile, mMeshName, mMeshDim);
1556 mNodes->getBBox(mMeshBBoxMin, mMeshBBoxMax);
1558 if (mNodes->getNumberOfNodes() != 0)
1561 //---------------------------------------------------------------------
1563 //---------------------------------------------------------------------
1565 finalizeFamiliesAndGroups();
1567 //---------------------------------------------------------------------
1569 //---------------------------------------------------------------------
1576 //---------------------------------------------------------------------
1577 // Close the MED file
1578 //---------------------------------------------------------------------
1579 MULTIPR_LOG("Close MED file: ");
1580 ret = MEDfermer(mMEDfile);
1581 if (ret != 0) throw IOException("i/o error while closing MED file", __FILE__, __LINE__);
1582 MULTIPR_LOG("OK\n");
1586 void Mesh::readSequentialMED(const char* pMEDfilename, const char* pMeshName, bool pReadFields)
1588 _openMEDFile(pMEDfilename);
1589 _readSequentialMED(pMeshName, pReadFields);
1593 void Mesh::readSequentialMED(const char* pMEDfilename, med_int pMeshNumber, bool pReadFields)
1595 _openMEDFile(pMEDfilename);
1597 //---------------------------------------------------------------------
1599 //---------------------------------------------------------------------
1600 // read number of meshes
1601 MULTIPR_LOG("Num meshes: ");
1602 med_int nbMeshes = MEDnMaa(mMEDfile);
1603 if (nbMeshes <= 0) throw IOException("i/o error while reading number of meshes in MED file", __FILE__, __LINE__);
1604 MULTIPR_LOG(nbMeshes << ": OK\n");
1607 med_maillage meshType;
1608 char meshDesc[MED_TAILLE_DESC + 1];
1609 char meshName[MED_TAILLE_NOM + 1];
1611 med_err ret = MEDmaaInfo(mMEDfile, pMeshNumber, meshName, &meshDim, &meshType, meshDesc);
1612 if (ret != 0) throw IOException("i/o error while reading mesh information in MED file", __FILE__, __LINE__);
1614 _readSequentialMED(meshName, pReadFields);
1618 void Mesh::writeMED(const char* pMEDfilename)
1620 writeMED(pMEDfilename, getName());
1624 void Mesh::writeMED(const char* pMEDfilename, const char* pMeshName)
1627 MULTIPR_LOG("Write MED: " << pMEDfilename << endl);
1628 if (pMEDfilename == NULL) throw NullArgumentException("pMEDfilename should not be NULL", __FILE__, __LINE__);
1629 if (strlen(pMEDfilename) == 0) throw IllegalArgumentException("pMEDfilename size is 0", __FILE__, __LINE__);
1631 if (pMeshName == NULL) throw NullArgumentException("pMeshName should not be NULL", __FILE__, __LINE__);
1632 if (strlen(pMeshName) == 0) throw IllegalArgumentException("pMeshName size is 0", __FILE__, __LINE__);
1634 remove(pMEDfilename);
1636 char aMeshName[MED_TAILLE_NOM + 1];
1637 strncpy(aMeshName, pMeshName, MED_TAILLE_NOM);
1639 //---------------------------------------------------------------------
1640 // Create the new MED file (WRITE_ONLY)
1641 //---------------------------------------------------------------------
1642 med_idt newMEDfile = MEDouvrir(const_cast<char*>(pMEDfilename), MED_CREATION);
1643 if (newMEDfile == -1) throw IOException("", __FILE__, __LINE__);
1645 //---------------------------------------------------------------------
1647 //---------------------------------------------------------------------
1648 // no scalars to write
1650 //---------------------------------------------------------------------
1651 // Create mesh: must be created first
1652 //---------------------------------------------------------------------
1653 med_err ret = MEDmaaCr(
1660 if (ret != 0) throw IOException("", __FILE__, __LINE__);
1661 MULTIPR_LOG(" Create mesh: |" << aMeshName << "|: OK" << endl);
1663 //---------------------------------------------------------------------
1664 // Write nodes and elements (mesh must exist)
1665 //---------------------------------------------------------------------
1666 if (mNodes == NULL) throw IllegalStateException("mNodes should not be NULL", __FILE__, __LINE__);
1667 mNodes->writeMED(newMEDfile, aMeshName);
1668 MULTIPR_LOG(" Write nodes: ok" << endl);
1670 for (int i = 0; i < eMaxMedMesh; ++i)
1672 if (mElements[i] != NULL)
1675 mElements[i]->writeMED(newMEDfile, aMeshName, mMeshDim);
1680 //throw IllegalStateException("No mesh writen.", __FILE__, __LINE__);
1684 MULTIPR_LOG(" write elt: ok" << endl);
1686 //---------------------------------------------------------------------
1687 // Write families (mesh must exist)
1688 //---------------------------------------------------------------------
1689 // MED assume there is a family 0 in the file.
1690 bool createFamZero = true;
1691 for(std::vector<Family*>::iterator it = mFamilies.begin();
1692 it != mFamilies.end(); ++it)
1694 if ((*it)->getId() == 0)
1696 createFamZero = false;
1704 strcpy(const_cast<char*>(famZero.getName()), "FAMILLE_ZERO");
1705 famZero.writeMED(newMEDfile, aMeshName);
1708 for (unsigned itFam = 0 ; itFam < mFamilies.size() ; ++itFam)
1710 Family* fam = mFamilies[itFam];
1711 fam->writeMED(newMEDfile, aMeshName);
1713 MULTIPR_LOG(" Write families: ok" << endl);
1715 //---------------------------------------------------------------------
1717 //---------------------------------------------------------------------
1718 for (unsigned itProf = 0; itProf < mProfils.size(); ++itProf)
1720 Profil* prof = mProfils[itProf];
1721 prof->writeMED(newMEDfile);
1724 //---------------------------------------------------------------------
1725 // Write Gauss localization (must be written before fields)
1726 //---------------------------------------------------------------------
1727 for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ;
1730 GaussLoc* gaussLoc = mGaussLoc[itGaussLoc];
1731 gaussLoc->writeMED(newMEDfile);
1734 MULTIPR_LOG(" Write Gauss: ok" << endl);
1736 //---------------------------------------------------------------------
1738 //---------------------------------------------------------------------
1739 std::set<std::string> fieldNameList;
1740 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
1742 Field* field = mFields[itField];
1743 if (fieldNameList.find(std::string(field->getName())) != fieldNameList.end())
1745 field->writeMED(newMEDfile, aMeshName, false);
1749 fieldNameList.insert(std::string(field->getName()));
1750 field->writeMED(newMEDfile, aMeshName);
1754 MULTIPR_LOG(" Write fields: ok" << endl);
1756 //---------------------------------------------------------------------
1757 // Close the new MED file
1758 //---------------------------------------------------------------------
1759 ret = MEDfermer(newMEDfile);
1760 if (ret != 0) throw IOException("", __FILE__, __LINE__);
1763 void Mesh::readGaussLoc()
1765 MULTIPR_LOG("Gauss ref: ");
1766 med_int numGauss = MEDnGauss(mMEDfile);
1767 if (numGauss < 0) throw IOException("", __FILE__, __LINE__);
1768 MULTIPR_LOG(numGauss << ": OK\n");
1770 for (int itGauss = 1 ; itGauss <= numGauss ; itGauss++)
1772 GaussLoc* gaussLoc = new GaussLoc();
1773 gaussLoc->readMED(mMEDfile, itGauss);
1774 MULTIPR_LOG((*gaussLoc) << endl);
1775 mGaussLoc.push_back(gaussLoc);
1776 mGaussLocNameToGaussLoc.insert(make_pair(gaussLoc->getName(), gaussLoc));
1780 void Mesh::readFamilies()
1782 med_int numFamilies = MEDnFam(mMEDfile, mMeshName);
1783 if (numFamilies <= 0) throw IOException("", __FILE__, __LINE__);
1785 for (int itFam = 1 ; itFam <= numFamilies ; ++itFam)
1787 Family* fam = new Family();
1788 fam->readMED(mMEDfile, mMeshName, itFam);
1789 mFamilies.push_back(fam);
1794 void Mesh::finalizeFamiliesAndGroups()
1796 if (mFamilies.size() == 0)
1800 //---------------------------------------------------------------------
1801 // Build mapping between family id and pointers towards families
1802 //---------------------------------------------------------------------
1803 for (unsigned itFam = 0 ; itFam < mFamilies.size() ; ++itFam)
1805 Family* fam = mFamilies[itFam];
1806 mFamIdToFam.insert(make_pair(fam->getId(), fam));
1808 //---------------------------------------------------------------------
1809 // Fill families of nodes
1810 //---------------------------------------------------------------------
1811 for (int itNode = 1 ; itNode <= mNodes->getNumberOfNodes() ; ++itNode)
1813 // get family of the ith nodes
1814 int famIdent = mNodes->getFamIdent(itNode - 1); // MED nodes start at 1
1816 map<med_int, Family*>::iterator itFam = mFamIdToFam.find(famIdent);
1818 if (itFam == mFamIdToFam.end())
1821 sprintf(msg, "wrong family of nodes for node #%d: family %d not found", itNode, famIdent);
1822 throw IllegalStateException(msg, __FILE__, __LINE__);
1825 Family* fam = (*itFam).second;
1827 // add the current node to its family
1828 fam->insertElt(itNode);
1829 fam->setIsFamilyOfNodes(true);
1831 //---------------------------------------------------------------------
1832 // Fill families of elements
1833 //---------------------------------------------------------------------
1834 for (int itMesh = 0; itMesh < eMaxMedMesh; ++itMesh)
1836 if (mElements[itMesh] != NULL)
1838 for (int itElt = 1 ; itElt <= mElements[itMesh]->getNumberOfElements() ; itElt++)
1840 // get family of the ith element (MED index start at 1)
1841 int famIdent = mElements[itMesh]->getFamilyIdentifier(itElt - 1);
1843 map<med_int, Family*>::iterator itFam = mFamIdToFam.find(famIdent);
1845 if (itFam == mFamIdToFam.end())
1848 sprintf(msg, "wrong family of elements for element #%d: family %d not found", itElt, famIdent);
1849 throw IllegalStateException(msg, __FILE__, __LINE__);
1852 Family* fam = (*itFam).second;
1854 // add the current element to its family
1855 fam->insertElt( itElt, (eMeshType)itMesh);
1856 fam->setIsFamilyOfNodes(false);
1860 //---------------------------------------------------------------------
1862 //---------------------------------------------------------------------
1864 for (unsigned itFam = 0 ; itFam < mFamilies.size() ; itFam++)
1866 mFamilies[itFam]->buildGroups(mGroups, mGroupNameToGroup);
1871 void Mesh::readFields()
1873 //---------------------------------------------------------------------
1874 // Read number of fields
1875 //---------------------------------------------------------------------
1876 MULTIPR_LOG("Read fields: ");
1877 med_int numFields = MEDnChamp(mMEDfile, 0);
1878 if (numFields <= 0) throw IOException("", __FILE__, __LINE__);
1879 MULTIPR_LOG(numFields << ": OK\n");
1881 //---------------------------------------------------------------------
1882 // Iterate over fields
1883 //---------------------------------------------------------------------
1884 // for each field, read number of components and others infos
1885 for (int itField = 1 ; itField <= numFields ; itField++)
1887 for (int i = 0; i < eMaxMedMesh; ++i)
1889 Field* field = new Field();
1890 field->readMED(mMEDfile, itField, mMeshName, CELL_TYPES[i]);
1892 // if the nth field does not apply on our mesh => slip it
1893 if (field->isEmpty())
1899 mFields.push_back(field);
1900 // ReadMed will always work with fields on node so we need to stop the first time.
1901 // ie : CELL_TYPES[i] is not used in this case.
1902 if (field->isFieldOnNodes())
1912 ostream& operator<<(ostream& pOs, Mesh& pM)
1914 pOs << "Mesh: " << endl;
1915 pOs << " MED file =|" << pM.mMEDfilename << "|" << endl;
1916 pOs << " Name =|" << pM.mMeshName << "|" << endl;
1917 pOs << " Unv name =|" << pM.mMeshUName << "|" << endl;
1918 pOs << " Desc =|" << pM.mMeshDesc << "|" << endl;
1919 pOs << " Dim =" << pM.mMeshDim << endl;
1920 pOs << " Type =" << ((pM.mMeshType == MED_STRUCTURE)?"STRUCTURE":"NON_STRUCTURE") << endl;
1921 pOs << " BBox =[" << pM.mMeshBBoxMin[0] << " ; " << pM.mMeshBBoxMax[0] << "] x [" << pM.mMeshBBoxMin[1] << " ; " << pM.mMeshBBoxMax[1] << "] x [" << pM.mMeshBBoxMin[2] << " ; " << pM.mMeshBBoxMax[2] << "]" << endl;
1923 int numFamOfNodes = 0;
1924 for (unsigned i = 0 ; i < pM.mFamilies.size() ; i++)
1926 if (pM.mFamilies[i]->isFamilyOfNodes())
1932 int numGroupsOfNodes = 0;
1933 for (unsigned i = 0 ; i < pM.mGroups.size() ; i++)
1935 if (pM.mGroups[i]->isGroupOfNodes())
1941 if (pM.mFlagPrintAll)
1943 cout << (*(pM.mNodes)) << endl;
1944 for (int i = 0; i < eMaxMedMesh; ++i)
1946 if (pM.mElements[i] != NULL)
1948 cout << (*(pM.mElements[i])) << endl;
1952 pOs << " Families : #=" << pM.mFamilies.size() << " (nodes=" << numFamOfNodes << " ; elements=" << (pM.mFamilies.size() - numFamOfNodes) << ")" << endl;
1953 for (unsigned i = 0 ; i < pM.mFamilies.size() ; i++)
1955 cout << (*(pM.mFamilies[i])) << endl;
1958 pOs << " Groups : #=" << pM.mGroups.size() << " (nodes=" << numGroupsOfNodes << " ; elements=" << (pM.mGroups.size() - numGroupsOfNodes) << ")" << endl;
1959 for (unsigned i = 0 ; i < pM.mGroups.size() ; i++)
1961 cout << (*(pM.mGroups[i])) << endl;
1964 pOs << " Gauss loc: #=" << pM.mGaussLoc.size() << endl;
1965 for (unsigned i = 0 ; i < pM.mGaussLoc.size() ; i++)
1967 cout << (*(pM.mGaussLoc[i])) << endl;
1970 pOs << " Fields : #=" << pM.mFields.size() << endl;
1971 for (unsigned i = 0 ; i < pM.mFields.size() ; i++)
1973 cout << (*(pM.mFields[i])) << endl;
1978 if (pM.mNodes != NULL)
1980 pOs << " Nodes : #=" << pM.mNodes->getNumberOfNodes() << endl;
1982 for (int i = 0; i < eMaxMedMesh; ++i)
1984 if (pM.mElements[i] != NULL)
1986 const set<med_int>& setOfNodes = pM.mElements[i]->getSetOfNodes();
1987 if (setOfNodes.size() == 0)
1989 pOs << " Elt : #=" << pM.mElements[i]->getNumberOfElements() << endl;
1993 set<med_int>::iterator itNode = setOfNodes.end();
1995 pOs << " Elt : #=" << pM.mElements[i]->getNumberOfElements() << " node_id_min=" << (*(setOfNodes.begin())) << " node_id_max=" << (*itNode) << endl;
1999 pOs << " Families : #=" << pM.mFamilies.size() << " (nodes=" << numFamOfNodes << " ; elements=" << (pM.mFamilies.size() - numFamOfNodes) << ")" << endl;
2000 pOs << " Groups : #=" << pM.mGroups.size() << " (nodes=" << numGroupsOfNodes << " ; elements=" << (pM.mGroups.size() - numGroupsOfNodes) << ")" << endl;
2001 pOs << " Gauss loc: #=" << pM.mGaussLoc.size() << endl;
2002 pOs << " Fields : #=" << pM.mFields.size() << endl;
2009 } // namespace multipr