1 // Project MULTIPR, IOLS WP1.2.1 - EDF/CS
2 // Partitioning/decimation module for the SALOME v3.2 platform
5 * \file MULTIPR_Mesh.cxx
7 * \brief see MULTIPR_Mesh.hxx
9 * \author Olivier LE ROUX - CS, Virtual Reality Dpt
14 //*****************************************************************************
16 //*****************************************************************************
18 #include "MULTIPR_Mesh.hxx"
19 #include "MULTIPR_Nodes.hxx"
20 #include "MULTIPR_Elements.hxx"
21 #include "MULTIPR_Family.hxx"
22 #include "MULTIPR_Profil.hxx"
23 #include "MULTIPR_GaussLoc.hxx"
24 #include "MULTIPR_Field.hxx"
25 #include "MULTIPR_MeshDis.hxx"
26 #include "MULTIPR_PointOfField.hxx"
27 #include "MULTIPR_DecimationFilter.hxx"
28 #include "MULTIPR_Utils.hxx"
29 #include "MULTIPR_Exceptions.hxx"
30 #include "MULTIPR_Globals.hxx"
31 #include "MULTIPR_API.hxx"
40 const med_geometrie_element CELL_TYPES[MED_NBR_GEOMETRIE_MAILLE] =
60 char CELL_NAMES[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1] =
79 // Number of points to consider when looking for significant nodes in a mesh.
80 // ie the n first nodes.
81 const int CELL_NB_NODE[MED_NBR_GEOMETRIE_MAILLE] =
102 //*****************************************************************************
103 // Class Mesh implementation
104 //*****************************************************************************
109 for (int i = 0; i < eMaxMedMesh; i++)
126 mMEDfilename[0] = '\0';
130 mMeshUName[0] = '\0';
133 mMeshType = MED_NON_STRUCTURE;
135 for (int itDim = 0 ; itDim < 3 ; itDim++)
137 mMeshBBoxMin[itDim] = numeric_limits<med_float>::quiet_NaN();
138 mMeshBBoxMax[itDim] = numeric_limits<med_float>::quiet_NaN();
141 if (mNodes != NULL) { delete mNodes; mNodes = NULL; }
143 for (int i = 0; i < eMaxMedMesh; i++)
145 if (mElements[i] != NULL)
151 for (unsigned itFam = 0 ; itFam < mFamilies.size() ; itFam++)
153 delete mFamilies[itFam];
158 for (unsigned itGroup = 0 ; itGroup < mGroups.size() ; itGroup++)
160 delete mGroups[itGroup];
163 mGroupNameToGroup.clear();
165 for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
167 delete mGaussLoc[itGaussLoc];
170 mGaussLocNameToGaussLoc.clear();
172 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
174 //delete mFields[itField];
178 for (unsigned itProfil = 0 ; itProfil < mProfils.size() ; itProfil++)
180 delete mProfils[itProfil];
184 mFlagPrintAll = false;
190 vector<string> Mesh::getNameScalarFields() const
194 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
196 Field* currentField = mFields[itField];
198 // only get scalar fields, not vectorial fields
199 // (because, currently, decimation can only be performed on scalar fields)
200 if (currentField->getNumberOfComponents() == 1)
202 res.push_back(currentField->getName());
210 int Mesh::getTimeStamps(const char* pFieldName) const
212 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
214 Field* currentField = mFields[itField];
215 if (strcmp(currentField->getName(), pFieldName) == 0)
217 return currentField->getNumberOfTimeSteps();
224 Field* Mesh::getFieldByName(const char* pFieldName, eMeshType pGeomType) const
226 if (pFieldName == NULL) throw NullArgumentException("pFieldName should not be NULL", __FILE__, __LINE__);
228 Field* retField = NULL;
231 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
233 Field* currentField = mFields[itField];
234 // Check if this is the field we want.
235 if (strncmp(pFieldName, currentField->getName(), MED_TAILLE_NOM) == 0 &&
236 (currentField->getGeomIdx() == pGeomType || currentField->isFieldOnNodes()))
239 retField = currentField;
247 void Mesh::getFieldMinMax(const char* pFieldName, float& pMin, float& pMax) const
249 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
251 Field* currentField = mFields[itField];
252 // Check if this is the field we want.
253 if (strncmp(pFieldName, currentField->getName(), MED_TAILLE_NOM) == 0)
255 currentField->getMinMax(pMin, pMax);
261 GaussLoc* Mesh::getGaussLocByName(const char* pGaussLocName) const
263 if (pGaussLocName == NULL) throw NullArgumentException("pGaussLocName should not be NULL", __FILE__, __LINE__);
265 map<string, GaussLoc*>::const_iterator itGaussLoc = mGaussLocNameToGaussLoc.find(pGaussLocName);
266 GaussLoc* retGaussLoc = NULL;
268 if (itGaussLoc != mGaussLocNameToGaussLoc.end())
270 retGaussLoc = (*itGaussLoc).second;
277 int Mesh::getNumberOfElements(eMeshType pGeomType) const
279 if (mElements[pGeomType])
281 return mElements[pGeomType]->getNumberOfElements();
289 int Mesh::getNumberOfElements() const
293 for (int i = 0; i < eMaxMedMesh; ++i)
297 accum += mElements[i]->getNumberOfElements();
303 Profil* Mesh::getProfil(const std::string pProfilName)
305 Profil* profile = NULL;
306 std::vector<Profil*>::iterator it;
307 if (pProfilName.size() > 0)
309 for (it = mProfils.begin(); it != mProfils.end(); ++it)
311 if ((*it)->getName() == pProfilName)
321 Mesh* Mesh::createFromSetOfElements(const std::set<med_int>* pSetOfElements, const char* pNewMeshName)
323 if (pNewMeshName == NULL) throw NullArgumentException("pNewMeshName should not be NULL", __FILE__, __LINE__);
325 //---------------------------------------------------------------------
327 //---------------------------------------------------------------------
328 Mesh* mesh = new Mesh();
330 //---------------------------------------------------------------------
331 // Build name of the new mesh
332 //---------------------------------------------------------------------
333 strcpy(mesh->mMeshName, pNewMeshName);
335 MULTIPR_LOG("Mesh name=|" << mesh->mMeshName << "|" << endl);
337 //---------------------------------------------------------------------
338 // Fill general infos
339 //---------------------------------------------------------------------
340 strcpy(mesh->mMeshUName, mMeshUName);
341 strcpy(mesh->mMeshDesc, mMeshDesc);
343 mesh->mMeshDim = mMeshDim;
344 mesh->mMeshType = mMeshType;
346 MULTIPR_LOG("Mesh u. name=|" << mesh->mMeshUName << "|" << endl);
347 MULTIPR_LOG("Mesh desc=|" << mesh->mMeshDesc << "|" << endl);
348 MULTIPR_LOG("Mesh dim=" << mesh->mMeshDim << endl);
349 MULTIPR_LOG("Mesh Type=" << mesh->mMeshType << endl);
351 //---------------------------------------------------------------------
352 // Build nodes and elements
353 //---------------------------------------------------------------------
354 // get all elements involved
355 for (int i = 0; i < eMaxMedMesh; ++i)
357 if (pSetOfElements[i].size() != 0)
359 mesh->mElements[i] = mElements[i]->extractSubSet(pSetOfElements[i]);
360 MULTIPR_LOG((*(mesh->mElements[i])) << endl);
364 // get all nodes involved
365 set<med_int> setOfNodes;
366 for (int i = 0; i < eMaxMedMesh; ++i)
368 if (mElements[i] != NULL && mesh->mElements[i] != NULL)
370 const set<med_int>& curSetOfNodes = mesh->mElements[i]->getSetOfNodes();
371 setOfNodes.insert(curSetOfNodes.begin(), curSetOfNodes.end());
374 mesh->mNodes = mNodes->extractSubSet(setOfNodes);
375 MULTIPR_LOG((*(mesh->mNodes)) << endl);
377 //---------------------------------------------------------------------
379 //---------------------------------------------------------------------
380 for (int i = 0; i < eMaxMedMesh; ++i)
382 if (mElements[i] != NULL && mesh->mElements[i] != NULL)
384 mesh->mElements[i]->remap(setOfNodes);
385 MULTIPR_LOG((*(mesh->mElements[i])) << endl);
390 //---------------------------------------------------------------------
392 //---------------------------------------------------------------------
393 MULTIPR_LOG("Build fam.:" << endl);
394 // get families of nodes
396 set<med_int> famOfNodes = mesh->mNodes->getSetOfFamilies();
397 for (set<med_int>::iterator itFam = famOfNodes.begin() ; itFam != famOfNodes.end() ; itFam++)
399 Family* famSrc = mFamIdToFam[*itFam];
400 if (mesh->mFamIdToFam.find(famSrc->getId()) == mesh->mFamIdToFam.end())
402 Family* famDest = famSrc->extractGroup(NULL);
403 mesh->mFamilies.push_back(famDest);
404 mesh->mFamIdToFam[famDest->getId()] = famDest;
409 // get families of elements
411 set<med_int> famOfElt;
412 for (int i = 0; i < eMaxMedMesh; ++i)
414 if (mElements[i] != NULL && mesh->mElements[i] != NULL)
416 set<med_int> curSetOfFamilies = mesh->mElements[i]->getSetOfFamilies();
417 famOfElt.insert(curSetOfFamilies.begin(), curSetOfFamilies.end());
420 for (set<med_int>::iterator itFam = famOfElt.begin() ; itFam != famOfElt.end() ; itFam++)
422 Family* famSrc = mFamIdToFam[*itFam];
423 if (mesh->mFamIdToFam.find(famSrc->getId()) == mesh->mFamIdToFam.end())
425 Family* famDest = famSrc->extractGroup(NULL);
426 mesh->mFamilies.push_back(famDest);
427 mesh->mFamIdToFam[famDest->getId()] = famDest;
432 MULTIPR_LOG("Finalize:");
434 // fill families with elements and build groups
435 //mesh->finalizeFamiliesAndGroups();
439 //---------------------------------------------------------------------
441 //---------------------------------------------------------------------
442 for (std::vector<Profil*>::iterator it = mProfils.begin(); it != mProfils.end(); ++it)
444 Profil* lProfil = new Profil();
445 lProfil->create((*it)->getName());
446 std::set<med_int> lSet;
447 if ((*it)->getBinding() == OnNodes)
449 (*it)->extractSetOfElement(setOfNodes, lSet);
453 (*it)->extractSetOfElement(pSetOfElements[lProfil->getGeomIdx()], lSet);
455 if (lSet.size() == 0)
461 mesh->mProfils.push_back(lProfil);
464 //---------------------------------------------------------------------
465 // Create new fields and collect Gauss
466 //---------------------------------------------------------------------
468 set<string> newSetOfGauss;
469 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
471 Field* currentField = mFields[itField];
473 Field* newField = NULL;
474 if (currentField->isFieldOnNodes())
476 newField = currentField->extractSubSet(setOfNodes);
480 if (pSetOfElements[currentField->getGeomIdx()].size() != 0)
482 newField = currentField->extractSubSet(pSetOfElements[currentField->getGeomIdx()]);
486 if (newField != NULL && !newField->isEmpty())
488 mesh->mFields.push_back(newField);
489 newField->getSetOfGaussLoc(newSetOfGauss);
492 MULTIPR_LOG("Collect fields: ok: #gauss=" << newSetOfGauss.size() << endl);
494 //---------------------------------------------------------------------
496 //---------------------------------------------------------------------
497 for (set<string>::iterator itSet = newSetOfGauss.begin() ; itSet != newSetOfGauss.end(); itSet++)
499 const string& keyName = (*itSet);
501 GaussLoc* gaussLoc = getGaussLocByName(keyName.c_str());
502 if (gaussLoc != NULL)
504 GaussLoc* copyGaussLoc = new GaussLoc(*gaussLoc);
505 mesh->mGaussLoc.push_back(copyGaussLoc);
506 mesh->mGaussLocNameToGaussLoc.insert(make_pair(copyGaussLoc->getName(), copyGaussLoc));
510 //---------------------------------------------------------------------
512 //---------------------------------------------------------------------
513 mesh->mNodes->getBBox(mesh->mMeshBBoxMin, mesh->mMeshBBoxMax);
519 Mesh* Mesh::createFromGroup(const Group* pGroup, const char* pNewMeshName)
521 if (pGroup == NULL) throw NullArgumentException("pGroup should not be NULL", __FILE__, __LINE__);
522 if (pNewMeshName == NULL) throw NullArgumentException("pNewMeshName should not be NULL", __FILE__, __LINE__);
523 if (strlen(pNewMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("pNewMeshName length too long", __FILE__, __LINE__);
524 //---------------------------------------------------------------------
526 //---------------------------------------------------------------------
527 Mesh* mesh = new Mesh();
529 //---------------------------------------------------------------------
530 // Build name of the new mesh
531 //---------------------------------------------------------------------
532 strcpy(mesh->mMeshName, pNewMeshName);
534 MULTIPR_LOG("Mesh name=|" << mesh->mMeshName << "|" << endl);
536 //---------------------------------------------------------------------
537 // Fill general infos
538 //---------------------------------------------------------------------
539 strcpy(mesh->mMeshUName, mMeshUName);
540 strcpy(mesh->mMeshDesc, mMeshDesc);
542 mesh->mMeshDim = mMeshDim;
543 mesh->mMeshType = mMeshType;
545 MULTIPR_LOG("Mesh u. name=|" << mesh->mMeshUName << "|" << endl);
546 MULTIPR_LOG("Mesh desc=|" << mesh->mMeshDesc << "|" << endl);
547 MULTIPR_LOG("Mesh dim=" << mesh->mMeshDim << endl);
548 MULTIPR_LOG("Mesh Type=" << mesh->mMeshType << endl);
550 //---------------------------------------------------------------------
551 // Build nodes and elements
552 //---------------------------------------------------------------------
553 // Get all elements involved
554 std::set< med_int>* setOfEltList = new std::set< med_int>[eMaxMedMesh];
555 for (int i = 0; i < eMaxMedMesh; ++i)
557 if (mElements[i] != NULL)
559 const set<med_int> setOfElt = pGroup->getSetOfElt((eMeshType)i);
560 mesh->mElements[i] = mElements[i]->extractSubSet(setOfElt);
561 setOfEltList[i] = setOfElt;
565 // Get all nodes involved
566 // The nodes a common for all elements so we don't need to store them separately.
567 set<med_int> setOfNodes;
568 for (int i = 0; i < eMaxMedMesh; ++i)
570 if (mesh->mElements[i] != NULL)
572 const set<med_int>& curSetOfNodes = mesh->mElements[i]->getSetOfNodes();
573 setOfNodes.insert(curSetOfNodes.begin(), curSetOfNodes.end());
576 mesh->mNodes = mNodes->extractSubSet(setOfNodes);
578 // We need this for the optimized memory management.
579 this->mGaussIndex.push_back(IndexPair(setOfEltList, setOfNodes));
580 //---------------------------------------------------------------------
582 //---------------------------------------------------------------------
583 for (int i = 0; i < eMaxMedMesh; ++i)
585 if (mesh->mElements[i] != NULL)
587 mesh->mElements[i]->remap(setOfNodes);
591 //---------------------------------------------------------------------
593 //---------------------------------------------------------------------
594 MULTIPR_LOG("Build fam.:" << endl);
595 // get families of nodes
597 set<med_int> famOfNodes = mesh->mNodes->getSetOfFamilies();
598 for (set<med_int>::iterator itFam = famOfNodes.begin() ; itFam != famOfNodes.end() ; itFam++)
600 Family* famSrc = mFamIdToFam[*itFam];
601 Family* famDest = famSrc->extractGroup(pGroup->getName().c_str());
602 mesh->mFamilies.push_back(famDest);
606 // get families of elements
608 set<med_int> famOfElt;
609 for (int i = 0; i < eMaxMedMesh; ++i)
611 if (mesh->mElements[i] != NULL)
613 set<med_int> curSetOfFamilies = mesh->mElements[i]->getSetOfFamilies();
614 famOfElt.insert(curSetOfFamilies.begin(), curSetOfFamilies.end());
617 for (set<med_int>::iterator itFam = famOfElt.begin() ; itFam != famOfElt.end() ; itFam++)
619 Family* famSrc = mFamIdToFam[*itFam];
620 Family* famDest = famSrc->extractGroup(pGroup->getName().c_str());
621 mesh->mFamilies.push_back(famDest);
625 MULTIPR_LOG("Finalize:");
627 // fill families with elements and build groups
628 mesh->finalizeFamiliesAndGroups();
632 //---------------------------------------------------------------------
634 //---------------------------------------------------------------------
635 for (std::vector<Profil*>::iterator it = mProfils.begin(); it != mProfils.end(); ++it)
637 Profil* lProfil = new Profil();
638 lProfil->create((*it)->getName());
639 std::set<med_int> lSet;
640 if ((*it)->getBinding() == OnNodes)
642 (*it)->extractSetOfElement(setOfNodes, lSet);
646 (*it)->extractSetOfElement(setOfEltList[lProfil->getGeomIdx()], lSet);
648 if (lSet.size() == 0)
654 mesh->mProfils.push_back(lProfil);
657 //---------------------------------------------------------------------
658 // Create new fields and collect Gauss
659 //---------------------------------------------------------------------
661 set<string> newSetOfGauss;
662 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
664 Field* currentField = mFields[itField];
667 if (currentField->isFieldOnNodes())
669 newField = currentField->extractSubSet(setOfNodes);
673 if (setOfEltList[currentField->getGeomIdx()].size() != 0)
675 newField = currentField->extractSubSet(setOfEltList[currentField->getGeomIdx()]);
679 if (!newField->isEmpty())
681 mesh->mFields.push_back(newField);
682 newField->getSetOfGaussLoc(newSetOfGauss);
685 // Get gauss locs for optimized fields reading.
686 if (mFields.size() == 0)
688 for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
690 const string& gaussLocName = mGaussLoc[itGaussLoc]->getName();
692 if (gaussLocName.length() != 0)
694 newSetOfGauss.insert(gaussLocName);
698 MULTIPR_LOG("Collect fields: ok: #gauss=" << newSetOfGauss.size() << endl);
700 //---------------------------------------------------------------------
702 //---------------------------------------------------------------------
703 for (set<string>::iterator itSet = newSetOfGauss.begin() ; itSet != newSetOfGauss.end(); itSet++)
705 const string& keyName = (*itSet);
707 GaussLoc* gaussLoc = getGaussLocByName(keyName.c_str());
708 if (gaussLoc != NULL)
710 GaussLoc* copyGaussLoc = new GaussLoc(*gaussLoc);
711 mesh->mGaussLoc.push_back(copyGaussLoc);
712 mesh->mGaussLocNameToGaussLoc.insert(make_pair(copyGaussLoc->getName(), copyGaussLoc));
716 //---------------------------------------------------------------------
718 //---------------------------------------------------------------------
719 mesh->mNodes->getBBox(mesh->mMeshBBoxMin, mesh->mMeshBBoxMax);
725 Mesh* Mesh::createFromFamily(const Family* pFamily, const char* pNewMeshName)
727 if (pFamily == NULL) throw NullArgumentException("pFamily should not be NULL", __FILE__, __LINE__);
728 if (pNewMeshName == NULL) throw NullArgumentException("pNewMeshName should not be NULL", __FILE__, __LINE__);
729 if (strlen(pNewMeshName) > MED_TAILLE_NOM)
732 sprintf(msg, "pNewMeshName length (=%d) too long: max size allowed is %d", strlen(pNewMeshName), MED_TAILLE_NOM);
733 throw IllegalArgumentException(msg, __FILE__, __LINE__);
735 //---------------------------------------------------------------------
737 //---------------------------------------------------------------------
738 Mesh* mesh = new Mesh();
740 //---------------------------------------------------------------------
741 // Build name of the new mesh
742 //---------------------------------------------------------------------
743 strcpy(mesh->mMeshName, pNewMeshName);
745 MULTIPR_LOG("Mesh name=|" << mesh->mMeshName << "|" << endl);
747 //---------------------------------------------------------------------
748 // Fill general infos
749 //---------------------------------------------------------------------
750 strcpy(mesh->mMeshUName, mMeshUName);
751 strcpy(mesh->mMeshDesc, mMeshDesc);
753 mesh->mMeshDim = mMeshDim;
754 mesh->mMeshType = mMeshType;
756 MULTIPR_LOG("Mesh u. name=|" << mesh->mMeshUName << "|" << endl);
757 MULTIPR_LOG("Mesh desc=|" << mesh->mMeshDesc << "|" << endl);
758 MULTIPR_LOG("Mesh dim=" << mesh->mMeshDim << endl);
759 MULTIPR_LOG("Mesh Type=" << mesh->mMeshType << endl);
761 //---------------------------------------------------------------------
762 // Build nodes and elements
763 //---------------------------------------------------------------------
764 // Get all elements involved
765 std::set< med_int>* setOfEltList = new std::set< med_int>[eMaxMedMesh];
766 for (int i = 0; i < eMaxMedMesh; ++i)
768 if (mElements[i] != NULL)
770 const set<med_int> setOfElt = pFamily->getSetOfElt((eMeshType)i);
771 mesh->mElements[i] = mElements[i]->extractSubSet(setOfElt);
772 setOfEltList[i] = setOfElt;
776 // Get all nodes involved
777 // The nodes a common for all elements so we don't need to store them separately.
778 set<med_int> setOfNodes;
779 for (int i = 0; i < eMaxMedMesh; ++i)
781 if (mesh->mElements[i] != NULL)
783 const set<med_int>& curSetOfNodes = mesh->mElements[i]->getSetOfNodes();
784 setOfNodes.insert(curSetOfNodes.begin(), curSetOfNodes.end());
787 mesh->mNodes = mNodes->extractSubSet(setOfNodes);
789 // We need this for the optimized memory management.
790 this->mGaussIndex.push_back(IndexPair(setOfEltList, setOfNodes));
791 //---------------------------------------------------------------------
793 //---------------------------------------------------------------------
794 for (int i = 0; i < eMaxMedMesh; ++i)
796 if (mesh->mElements[i] != NULL)
798 mesh->mElements[i]->remap(setOfNodes);
802 //---------------------------------------------------------------------
804 //---------------------------------------------------------------------
805 MULTIPR_LOG("Build fam.:" << endl);
806 // get families of nodes
807 Family* lFam = new Family(*pFamily);
808 mesh->mFamilies.push_back(lFam);
810 MULTIPR_LOG("Finalize:");
812 // fill families with elements and build groups
813 mesh->finalizeFamiliesAndGroups();
817 //---------------------------------------------------------------------
819 //---------------------------------------------------------------------
820 for (std::vector<Profil*>::iterator it = mProfils.begin(); it != mProfils.end(); ++it)
822 Profil* lProfil = new Profil();
823 lProfil->create((*it)->getName());
824 std::set<med_int> lSet;
825 if ((*it)->getBinding() == OnNodes)
827 (*it)->extractSetOfElement(setOfNodes, lSet);
831 (*it)->extractSetOfElement(setOfEltList[lProfil->getGeomIdx()], lSet);
833 if (lSet.size() == 0)
839 mesh->mProfils.push_back(lProfil);
842 //---------------------------------------------------------------------
843 // Create new fields and collect Gauss
844 //---------------------------------------------------------------------
846 set<string> newSetOfGauss;
847 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
849 Field* currentField = mFields[itField];
852 if (currentField->isFieldOnNodes())
854 newField = currentField->extractSubSet(setOfNodes);
858 if (setOfEltList[currentField->getGeomIdx()].size() != 0)
860 newField = currentField->extractSubSet(setOfEltList[currentField->getGeomIdx()]);
864 if (!newField->isEmpty())
866 mesh->mFields.push_back(newField);
867 newField->getSetOfGaussLoc(newSetOfGauss);
870 // Get gauss locs for optimized fields reading.
871 if (mFields.size() == 0)
873 for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
875 const string& gaussLocName = mGaussLoc[itGaussLoc]->getName();
877 if (gaussLocName.length() != 0)
879 newSetOfGauss.insert(gaussLocName);
883 MULTIPR_LOG("Collect fields: ok: #gauss=" << newSetOfGauss.size() << endl);
885 //---------------------------------------------------------------------
887 //---------------------------------------------------------------------
888 for (set<string>::iterator itSet = newSetOfGauss.begin() ; itSet != newSetOfGauss.end(); itSet++)
890 const string& keyName = (*itSet);
892 GaussLoc* gaussLoc = getGaussLocByName(keyName.c_str());
893 if (gaussLoc != NULL)
895 GaussLoc* copyGaussLoc = new GaussLoc(*gaussLoc);
896 mesh->mGaussLoc.push_back(copyGaussLoc);
897 mesh->mGaussLocNameToGaussLoc.insert(make_pair(copyGaussLoc->getName(), copyGaussLoc));
901 //---------------------------------------------------------------------
903 //---------------------------------------------------------------------
904 mesh->mNodes->getBBox(mesh->mMeshBBoxMin, mesh->mMeshBBoxMax);
909 Mesh* Mesh::mergePartial(vector<Mesh*> pMeshes, const char* pFieldName, int pFieldIt)
911 if (pMeshes.size() == 0) throw IllegalArgumentException("list must contain one mesh at least", __FILE__, __LINE__);
913 //---------------------------------------------------------------------
915 //---------------------------------------------------------------------
916 Mesh* mesh = new Mesh();
918 //---------------------------------------------------------------------
919 // Build name of the new mesh
920 //---------------------------------------------------------------------
921 strcpy(mesh->mMeshName, mMeshName);
923 //---------------------------------------------------------------------
924 // Merge general infos
925 //---------------------------------------------------------------------
926 strcpy(mesh->mMeshUName, mMeshUName);
927 strcpy(mesh->mMeshDesc, mMeshDesc);
929 mesh->mMeshDim = mMeshDim;
930 mesh->mMeshType = mMeshType;
932 //---------------------------------------------------------------------
933 // Merge nodes and elements
934 //---------------------------------------------------------------------
935 vector<Nodes*> nodes;
936 vector<Elements*> elements[eMaxMedMesh];
937 vector<int> offsets[eMaxMedMesh];
939 int offset[eMaxMedMesh];
940 for (unsigned j = 0; j < eMaxMedMesh; ++j)
942 offset[j] = mNodes->getNumberOfNodes();
945 for (unsigned i = 0 ; i < pMeshes.size() ; i++)
947 if (mMeshDim != pMeshes[i]->mMeshDim) throw IllegalStateException("all meshes should have same dimension", __FILE__, __LINE__);
948 if (mMeshType != pMeshes[i]->mMeshType) throw IllegalStateException("all meshes should have same type", __FILE__, __LINE__);
951 nodes.push_back(pMeshes[i]->mNodes);
952 for (unsigned j = 0; j < eMaxMedMesh; ++j)
955 if (pMeshes[i]->mElements[j] != NULL)
957 elements[j].push_back(pMeshes[i]->mElements[j]);
958 offsets[j].push_back(offset[j]);
960 offset[j] += pMeshes[i]->mNodes->getNumberOfNodes();
964 mesh->mNodes = mNodes->mergePartial(nodes);
965 for (unsigned i = 0; i < eMaxMedMesh; ++i)
967 if (elements[i].size() != 0)
969 if (mElements[i] == NULL)
971 mElements[i] = new Elements(CELL_TYPES[i]);
972 mElements[i]->mergePartial(elements[i].front(), offsets[i].front());
973 elements[i].erase(elements[i].begin());
975 mesh->mElements[i] = mElements[i]->mergePartial(elements[i], offsets[i]);
977 else if (mElements[i] != NULL)
979 mesh->mElements[i] = mElements[i];
984 //---------------------------------------------------------------------
986 //---------------------------------------------------------------------
987 for (unsigned i = 0 ; i < mFamilies.size() ; i++)
989 Family* family = new Family(*(mFamilies[i]));
990 mesh->mFamilies.push_back(family);
991 mesh->mFamIdToFam.insert(make_pair(family->getId(), family));
994 for (unsigned j = 0 ; j < pMeshes.size() ; j++)
996 for (unsigned i = 0 ; i < pMeshes[j]->mFamilies.size() ; i++)
998 // test if there is a fimaly with the same id
999 map<med_int, Family*>::iterator itFam = mesh->mFamIdToFam.find(pMeshes[j]->mFamilies[i]->getId());
1001 if (itFam == mesh->mFamIdToFam.end())
1003 // id not found: create a new family
1004 Family* family = new Family(*(pMeshes[j]->mFamilies[i]));
1005 mesh->mFamilies.push_back(family);
1006 mesh->mFamIdToFam.insert(make_pair(family->getId(), family));
1011 //---------------------------------------------------------------------
1013 //---------------------------------------------------------------------
1016 vector<Field*> fields;
1017 for (unsigned i = 0 ; i < pMeshes.size() ; i++)
1019 for (std::vector<Field*>::iterator it = pMeshes[i]->mFields.begin();
1020 it != pMeshes[i]->mFields.end(); ++it)
1022 if (strcmp((*it)->getName(), pFieldName) == 0)
1024 fields.push_back(*it);
1029 bool hasField = false;
1030 for (std::vector<Field*>::iterator it = mFields.begin();
1031 it != mFields.end(); ++it)
1033 if (strcmp((*it)->getName(), pFieldName) == 0)
1035 Field* field = (*it)->merge(fields, pFieldIt);
1036 mesh->mFields.push_back(field);
1041 if (hasField == false)
1043 Field* lField = fields.back();
1045 Field* field = lField->merge(fields, pFieldIt);
1046 mesh->mFields.push_back(field);
1049 //---------------------------------------------------------------------
1050 // Merge Gauss infos
1051 //---------------------------------------------------------------------
1052 // WARNING: assume Gauss infos are the same for the two meshes.
1053 for (unsigned i = 0 ; i < mGaussLoc.size() ; i++)
1055 GaussLoc* copyGaussLoc = new GaussLoc(*(mGaussLoc[i]));
1056 mesh->mGaussLoc.push_back(copyGaussLoc);
1057 mesh->mGaussLocNameToGaussLoc.insert(make_pair(copyGaussLoc->getName(), copyGaussLoc));
1064 MeshDis* Mesh::splitGroupsOfElements()
1066 MeshDis* meshDis = new MeshDis();
1067 meshDis->setSequentialMEDFilename(mMEDfilename);
1069 // get prefix from the original MED filename
1070 string strPrefix = removeExtension(mMEDfilename, ".med");
1075 for (unsigned itGroup = 0 ; itGroup < mGroups.size() ; itGroup++)
1077 Group* currentGroup = mGroups[itGroup];
1079 // skip this group if it is a group of nodes
1080 if (currentGroup->isGroupOfNodes())
1082 this->mGaussIndex.push_back(IndexPair());
1086 char strPartName[256];
1087 sprintf(strPartName, "%s_%d", mMeshName, numGroup);
1089 char strMEDfilename[256];
1090 char strMedGroup[256];
1092 for (i = 0; currentGroup->getName()[i] && currentGroup->getName()[i] != ' '; ++i)
1094 strMedGroup[i] = currentGroup->getName()[i];
1096 strMedGroup[i] = '\0';
1097 sprintf(strMEDfilename, "%s_%s.med", strPrefix.c_str(), strMedGroup);
1099 Mesh* mesh = createFromGroup(currentGroup, mMeshName);
1101 // skip the group which contain all the others groups, even if it contains only 1 group
1102 if (mesh->getNumberOfElements() == this->getNumberOfElements())
1104 for (int i = 0; i < eMaxMedMesh; ++i)
1106 this->mGaussIndex.back().first[i].clear();
1108 this->mGaussIndex.back().second.clear();
1114 MeshDisPart::MULTIPR_WRITE_MESH,
1124 if (mGroups.size() == 0)
1126 for (unsigned itFam = 0; itFam < mFamilies.size(); ++itFam)
1129 Family* currentFam = mFamilies[itFam];
1131 // skip this family if it is a family of nodes
1132 if (currentFam->isFamilyOfNodes())
1134 this->mGaussIndex.push_back(IndexPair());
1138 char strPartName[256];
1139 sprintf(strPartName, "%s_%d", mMeshName, numGroup);
1141 char strMEDfilename[256];
1142 char strMedFam[256];
1144 for (i = 0; currentFam->getName()[i] && currentFam->getName()[i] != ' '; ++i)
1146 strMedFam[i] = currentFam->getName()[i];
1148 strMedFam[i] = '\0';
1149 sprintf(strMEDfilename, "%s_%s.med", strPrefix.c_str(), strMedFam);
1151 Mesh* mesh = createFromFamily(currentFam, mMeshName);
1154 MeshDisPart::MULTIPR_WRITE_MESH,
1170 Mesh* Mesh::decimate(
1171 const char* pFilterName,
1173 const char* pNameNewMesh)
1175 //---------------------------------------------------------------------
1177 //---------------------------------------------------------------------
1178 if (pFilterName == NULL) throw NullArgumentException("pFilterName should not be NULL", __FILE__, __LINE__);
1179 if (pArgv == NULL) throw NullArgumentException("pArgv should not be NULL", __FILE__, __LINE__);
1180 if (pNameNewMesh == NULL) throw NullArgumentException("pNameNewMesh should not be NULL", __FILE__, __LINE__);
1182 //---------------------------------------------------------------------
1183 // Instanciate filter used for decimation
1184 //---------------------------------------------------------------------
1185 DecimationFilter* filter = DecimationFilter::create(pFilterName);
1187 //---------------------------------------------------------------------
1188 // Create new mesh by decimating current one
1189 //---------------------------------------------------------------------
1190 Mesh* decimatedMesh = filter->apply(this, pArgv, pNameNewMesh);
1192 //---------------------------------------------------------------------
1194 //---------------------------------------------------------------------
1197 return decimatedMesh;
1202 void Mesh::getAllPointsOfField(Field* pField, int pTimeStepIt, std::vector<PointOfField>& pPoints, eMeshType pGeomType)
1204 //---------------------------------------------------------------------
1206 //---------------------------------------------------------------------
1207 if (pField == NULL) throw NullArgumentException("field should not be NULL", __FILE__, __LINE__);
1208 if (pTimeStepIt < 1) throw IllegalArgumentException("invalid field iteration; should be >= 1", __FILE__, __LINE__);
1210 if (mMeshDim != 3) throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
1211 if (pField->getType() != MED_FLOAT64) throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
1212 if (pField->getNumberOfComponents() != 1) throw UnsupportedOperationException("field have more than 1 component (vectorial field, expected scalar field)", __FILE__, __LINE__);
1214 //---------------------------------------------------------------------
1216 //---------------------------------------------------------------------
1218 const std::string& profilName = pField->getProfil(pTimeStepIt);
1219 std::vector<Profil*>::iterator it;
1220 Profil* profile = NULL;
1222 if (profilName.size() > 0)
1224 for (it = mProfils.begin(); it != mProfils.end(); ++it)
1226 if ((*it)->getName() == profilName)
1232 if (it == mProfils.end()) throw IllegalStateException("Can't find the profile in the mesh.", __FILE__, __LINE__);
1236 //---------------------------------------------------------------------
1238 //---------------------------------------------------------------------
1240 if (pField->isFieldOnNodes())
1242 //-------------------------------------------------------------
1243 // Case 1: field of nodes
1244 //-------------------------------------------------------------
1245 if (mNodes == NULL) throw IllegalStateException("no nodes in the current mesh", __FILE__, __LINE__);
1248 for (int itNode = 0, size = mNodes->getNumberOfNodes() ; itNode < size ; itNode++)
1250 if (profile && profile->find(itNode) == false)
1254 // collect coordinates and value of the point
1255 const med_float* coo = mNodes->getCoordinates(itNode);
1257 const med_float* val =
1258 reinterpret_cast<const med_float*>(pField->getValue(pTimeStepIt, count + 1));
1260 pPoints.push_back(PointOfField(coo[0], coo[1], coo[2], val[0]));
1266 //-------------------------------------------------------------
1267 // Case 2: field of elements
1268 //-------------------------------------------------------------
1270 if (mElements[pGeomType] == NULL) throw IllegalStateException("no elements in the current mesh", __FILE__, __LINE__);
1272 const string& nameGaussLoc = pField->getNameGaussLoc(pTimeStepIt);
1273 GaussLoc* gaussLoc = getGaussLocByName(nameGaussLoc.c_str());
1274 if (gaussLoc == NULL) throw IllegalStateException("no Gauss localization for these elements", __FILE__, __LINE__);
1276 int numGauss = pField->getNumberOfGaussPointsByElement(pTimeStepIt);
1277 int size = gaussLoc->getDim() * gaussLoc->getNumGaussPoints();
1278 med_float* cooGaussPts = new med_float[size];
1280 int dim = mElements[pGeomType]->getTypeOfPrimitives() / 100;
1281 //int numNodes = mElements[pGeomType]->getTypeOfPrimitives() % 100;
1282 size = dim * numGauss;
1283 med_float* cooNodes = new med_float[size];
1285 // for each elements
1286 for (int itElt = 0, size = mElements[pGeomType]->getNumberOfElements() ; itElt < size ; itElt++)
1288 if (profile && profile->find(itElt) == false)
1292 // get coordinates of nodes of the current elements
1293 mElements[pGeomType]->getCoordinates(itElt, mNodes, cooNodes, numGauss);
1295 // compute coordinates of gauss points
1296 gaussLoc->getCoordGaussPoints(cooNodes, cooGaussPts, numGauss);
1298 const med_float* val =
1299 reinterpret_cast<const med_float*>(pField->getValue(pTimeStepIt, count + 1));
1301 // for each point of Gauss of the element
1302 med_float* srcCoo = cooGaussPts;
1303 for (int itPtGauss = 0 ; itPtGauss < numGauss ; itPtGauss++)
1305 pPoints.push_back(PointOfField(srcCoo[0], srcCoo[1], srcCoo[2], val[itPtGauss]));
1312 delete[] cooGaussPts;
1317 float Mesh::evalDefaultRadius(int pN) const
1319 if (mFields.size() == 0) return 1.0f;
1321 //---------------------------------------------------------------------
1322 // Compute default radius
1323 //---------------------------------------------------------------------
1325 med_float volumeBBox =
1326 (mMeshBBoxMax[0] - mMeshBBoxMin[0]) *
1327 (mMeshBBoxMax[1] - mMeshBBoxMin[1]) *
1328 (mMeshBBoxMax[2] - mMeshBBoxMin[2]);
1330 if (isnan(volumeBBox))
1335 const med_float k = 0.8; // considered 80% of the volume
1337 // get number of gauss points in the field
1340 Field* anyField = mFields[mFields.size()-1];
1341 int numTimeSteps = anyField->getNumberOfTimeSteps();
1343 int numGaussPoints = getNumberOfElements() * anyField->getNumberOfGaussPointsByElement(numTimeSteps-1);
1345 med_float radius = med_float(pow( (3.0/4.0) * pN * k * volumeBBox / (3.1415 * numGaussPoints), 1.0/3.0));
1347 return float(radius);
1355 void Mesh::_openMEDFile(const char* pMEDfilename, med_mode_acces pMEDModeAccess)
1359 //---------------------------------------------------------------------
1361 //---------------------------------------------------------------------
1362 MULTIPR_LOG("Check arguments: ");
1363 if (pMEDfilename == NULL) throw NullArgumentException("pMEDfilename should not be NULL", __FILE__, __LINE__);
1364 MULTIPR_LOG("OK\n");
1366 strncpy(mMEDfilename, pMEDfilename, 256);
1368 //---------------------------------------------------------------------
1369 // Open MED file (READ_ONLY)
1370 //---------------------------------------------------------------------
1371 MULTIPR_LOG("Open MED file: ");
1372 mMEDfile = MEDouvrir(mMEDfilename, pMEDModeAccess);
1373 if (mMEDfile <= 0) throw FileNotFoundException("MED file not found", __FILE__, __LINE__);
1374 MULTIPR_LOG("OK\n");
1376 //---------------------------------------------------------------------
1377 // Check valid HDF format
1378 //---------------------------------------------------------------------
1379 MULTIPR_LOG("Format HDF: ");
1380 if (MEDformatConforme(mMEDfilename) != 0) throw IOException("invalid file", __FILE__, __LINE__);
1381 MULTIPR_LOG("OK\n");
1383 //---------------------------------------------------------------------
1385 //---------------------------------------------------------------------
1386 MULTIPR_LOG("MED version: ");
1387 med_int verMajor, verMinor, verRelease;
1388 med_err ret = MEDversionLire(mMEDfile, &verMajor, &verMinor, &verRelease);
1389 if (ret != 0) throw IOException("error while reading MED version", __FILE__, __LINE__);
1390 MULTIPR_LOG(verMajor << "." << verMinor << "." << verRelease << ": OK\n");
1394 void Mesh::_readSequentialMED(const char* pMeshName, bool pReadFields)
1398 //---------------------------------------------------------------------
1400 //---------------------------------------------------------------------
1401 MULTIPR_LOG("Check arguments: ");
1402 if (pMeshName == NULL) throw NullArgumentException("pMeshName should not be NULL", __FILE__, __LINE__);
1403 MULTIPR_LOG("OK\n");
1405 strncpy(mMeshName, pMeshName, MED_TAILLE_NOM);
1407 //---------------------------------------------------------------------
1409 //---------------------------------------------------------------------
1410 MULTIPR_LOG("Profils: ");
1411 med_int nbProfils = MEDnProfil(mMEDfile);
1412 for (med_int i = 1; i <= nbProfils; ++i)
1414 Profil* profil = new Profil();
1415 profil->readMED(mMEDfile, i);
1416 profil->readProfilBinding(mMEDfile, const_cast<char*>(pMeshName));
1417 this->mProfils.push_back(profil);
1419 MULTIPR_LOG("OK\n");
1421 //---------------------------------------------------------------------
1422 // Read all Gauss localizations
1423 //---------------------------------------------------------------------
1424 MULTIPR_LOG("Gauss localizations: ");
1427 //---------------------------------------------------------------------
1428 // Read scalars (should be 0)
1429 //---------------------------------------------------------------------
1430 MULTIPR_LOG("Scalars: ");
1431 med_int nbScalars = MEDnScalaire(mMEDfile);
1432 if (nbScalars != 0) throw UnsupportedOperationException("scalars information not yet implemented", __FILE__, __LINE__);
1433 MULTIPR_LOG(nbScalars << ": OK\n");
1435 //---------------------------------------------------------------------
1437 //---------------------------------------------------------------------
1438 // read number of meshes
1439 MULTIPR_LOG("Num meshes: ");
1440 med_int nbMeshes = MEDnMaa(mMEDfile);
1441 if (nbMeshes <= 0) throw IOException("i/o error while reading number of meshes in MED file", __FILE__, __LINE__);
1442 MULTIPR_LOG(nbMeshes << ": OK\n");
1444 med_int meshIndex = -1;
1445 // iteration over mesh to find the mesh we want
1446 // for each mesh in the file (warning: first mesh is number 1)
1447 for (int itMesh = 1 ; itMesh <= nbMeshes ; itMesh++)
1449 char meshName[MED_TAILLE_NOM + 1];
1459 if (ret != 0) throw IOException("i/o error while reading mesh information in MED file", __FILE__, __LINE__);
1460 MULTIPR_LOG("Mesh: |" << meshName << "|");
1462 // test if the current mesh is the mesh we want
1463 if (strcmp(pMeshName, meshName) == 0)
1465 // *** mesh found ***
1466 MULTIPR_LOG(" OK (found)\n");
1472 // not the mesh we want: skip this mesh
1473 MULTIPR_LOG(" skipped\n");
1477 if (meshIndex == -1)
1479 throw IllegalStateException("mesh not found in the given MED file", __FILE__, __LINE__);
1482 //---------------------------------------------------------------------
1483 // Check mesh validity
1484 //---------------------------------------------------------------------
1485 // dimension of the mesh must be 3 (= 3D mesh)
1486 MULTIPR_LOG("Mesh is 3D: ");
1487 if (mMeshDim != 3) throw UnsupportedOperationException("dimension of the mesh should be 3; other dimension not yet implemented", __FILE__, __LINE__);
1488 MULTIPR_LOG("OK\n");
1490 // mesh must not be a grid
1491 MULTIPR_LOG("Mesh is not a grid: ");
1492 if (mMeshType != MED_NON_STRUCTURE)
1493 throw UnsupportedOperationException("grid not supported", __FILE__, __LINE__);
1494 MULTIPR_LOG("OK\n");
1496 med_connectivite connectivite = MED_NOD; // NODAL CONNECTIVITY ONLY
1497 // Read all the supported geometry type.
1498 for (int itCell = 0; itCell < eMaxMedMesh ; ++itCell)
1500 med_int meshNumCells = MEDnEntMaa(
1509 //---------------------------------------------------------------------
1511 //---------------------------------------------------------------------
1512 if (meshNumCells > 0)
1514 mElements[itCell] = new Elements();
1515 mElements[itCell]->readMED(mMEDfile, mMeshName, mMeshDim, MED_MAILLE, CELL_TYPES[itCell]);
1518 // everything is OK...
1520 //---------------------------------------------------------------------
1521 // Check num joint = 0
1522 //---------------------------------------------------------------------
1523 MULTIPR_LOG("Num joints: ");
1524 med_int numJoints = MEDnJoint(mMEDfile, mMeshName);
1525 MULTIPR_LOG(numJoints << ": OK\n");
1527 //---------------------------------------------------------------------
1528 // Check num equivalence = 0
1529 //---------------------------------------------------------------------
1530 MULTIPR_LOG("Num equivalences: ");
1531 med_int numEquiv = MEDnEquiv(mMEDfile, mMeshName);
1532 MULTIPR_LOG(numEquiv << ": OK\n");
1534 //---------------------------------------------------------------------
1536 //---------------------------------------------------------------------
1537 mNodes = new Nodes();
1538 mNodes->readMED(mMEDfile, mMeshName, mMeshDim);
1539 mNodes->getBBox(mMeshBBoxMin, mMeshBBoxMax);
1541 if (mNodes->getNumberOfNodes() != 0)
1544 //---------------------------------------------------------------------
1546 //---------------------------------------------------------------------
1548 finalizeFamiliesAndGroups();
1550 //---------------------------------------------------------------------
1552 //---------------------------------------------------------------------
1559 //---------------------------------------------------------------------
1560 // Close the MED file
1561 //---------------------------------------------------------------------
1562 MULTIPR_LOG("Close MED file: ");
1563 ret = MEDfermer(mMEDfile);
1564 if (ret != 0) throw IOException("i/o error while closing MED file", __FILE__, __LINE__);
1565 MULTIPR_LOG("OK\n");
1569 void Mesh::readSequentialMED(const char* pMEDfilename, const char* pMeshName, bool pReadFields)
1571 _openMEDFile(pMEDfilename);
1572 _readSequentialMED(pMeshName, pReadFields);
1576 void Mesh::readSequentialMED(const char* pMEDfilename, med_int pMeshNumber, bool pReadFields)
1578 _openMEDFile(pMEDfilename);
1580 //---------------------------------------------------------------------
1582 //---------------------------------------------------------------------
1583 // read number of meshes
1584 MULTIPR_LOG("Num meshes: ");
1585 med_int nbMeshes = MEDnMaa(mMEDfile);
1586 if (nbMeshes <= 0) throw IOException("i/o error while reading number of meshes in MED file", __FILE__, __LINE__);
1587 MULTIPR_LOG(nbMeshes << ": OK\n");
1590 med_maillage meshType;
1591 char meshDesc[MED_TAILLE_DESC + 1];
1592 char meshName[MED_TAILLE_NOM + 1];
1594 med_err ret = MEDmaaInfo(mMEDfile, pMeshNumber, meshName, &meshDim, &meshType, meshDesc);
1595 if (ret != 0) throw IOException("i/o error while reading mesh information in MED file", __FILE__, __LINE__);
1597 _readSequentialMED(meshName, pReadFields);
1601 void Mesh::writeMED(const char* pMEDfilename)
1603 writeMED(pMEDfilename, getName());
1607 void Mesh::writeMED(const char* pMEDfilename, const char* pMeshName)
1610 MULTIPR_LOG("Write MED: " << pMEDfilename << endl);
1611 if (pMEDfilename == NULL) throw NullArgumentException("pMEDfilename should not be NULL", __FILE__, __LINE__);
1612 if (strlen(pMEDfilename) == 0) throw IllegalArgumentException("pMEDfilename size is 0", __FILE__, __LINE__);
1614 if (pMeshName == NULL) throw NullArgumentException("pMeshName should not be NULL", __FILE__, __LINE__);
1615 if (strlen(pMeshName) == 0) throw IllegalArgumentException("pMeshName size is 0", __FILE__, __LINE__);
1617 remove(pMEDfilename);
1619 char aMeshName[MED_TAILLE_NOM + 1];
1620 strncpy(aMeshName, pMeshName, MED_TAILLE_NOM);
1622 //---------------------------------------------------------------------
1623 // Create the new MED file (WRITE_ONLY)
1624 //---------------------------------------------------------------------
1625 med_idt newMEDfile = MEDouvrir(const_cast<char*>(pMEDfilename), MED_CREATION);
1626 if (newMEDfile == -1) throw IOException("", __FILE__, __LINE__);
1628 //---------------------------------------------------------------------
1630 //---------------------------------------------------------------------
1631 // no scalars to write
1633 //---------------------------------------------------------------------
1634 // Create mesh: must be created first
1635 //---------------------------------------------------------------------
1636 med_err ret = MEDmaaCr(
1643 if (ret != 0) throw IOException("", __FILE__, __LINE__);
1644 MULTIPR_LOG(" Create mesh: |" << aMeshName << "|: OK" << endl);
1646 //---------------------------------------------------------------------
1647 // Write nodes and elements (mesh must exist)
1648 //---------------------------------------------------------------------
1649 if (mNodes == NULL) throw IllegalStateException("mNodes should not be NULL", __FILE__, __LINE__);
1650 mNodes->writeMED(newMEDfile, aMeshName);
1651 MULTIPR_LOG(" Write nodes: ok" << endl);
1653 for (int i = 0; i < eMaxMedMesh; ++i)
1655 if (mElements[i] != NULL)
1658 mElements[i]->writeMED(newMEDfile, aMeshName, mMeshDim);
1663 //throw IllegalStateException("No mesh writen.", __FILE__, __LINE__);
1667 MULTIPR_LOG(" write elt: ok" << endl);
1669 //---------------------------------------------------------------------
1670 // Write families (mesh must exist)
1671 //---------------------------------------------------------------------
1672 // MED assume there is a family 0 in the file.
1673 bool createFamZero = true;
1674 for(std::vector<Family*>::iterator it = mFamilies.begin();
1675 it != mFamilies.end(); ++it)
1677 if ((*it)->getId() == 0)
1679 createFamZero = false;
1687 strcpy(const_cast<char*>(famZero.getName()), "FAMILLE_ZERO");
1688 famZero.writeMED(newMEDfile, aMeshName);
1691 for (unsigned itFam = 0 ; itFam < mFamilies.size() ; ++itFam)
1693 Family* fam = mFamilies[itFam];
1694 fam->writeMED(newMEDfile, aMeshName);
1696 MULTIPR_LOG(" Write families: ok" << endl);
1698 //---------------------------------------------------------------------
1700 //---------------------------------------------------------------------
1701 for (unsigned itProf = 0; itProf < mProfils.size(); ++itProf)
1703 Profil* prof = mProfils[itProf];
1704 prof->writeMED(newMEDfile);
1707 //---------------------------------------------------------------------
1708 // Write Gauss localization (must be written before fields)
1709 //---------------------------------------------------------------------
1710 for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ;
1713 GaussLoc* gaussLoc = mGaussLoc[itGaussLoc];
1714 gaussLoc->writeMED(newMEDfile);
1717 MULTIPR_LOG(" Write Gauss: ok" << endl);
1719 //---------------------------------------------------------------------
1721 //---------------------------------------------------------------------
1722 std::set<std::string> fieldNameList;
1723 for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
1725 Field* field = mFields[itField];
1726 if (fieldNameList.find(std::string(field->getName())) != fieldNameList.end())
1728 field->writeMED(newMEDfile, aMeshName, false);
1732 fieldNameList.insert(std::string(field->getName()));
1733 field->writeMED(newMEDfile, aMeshName);
1737 MULTIPR_LOG(" Write fields: ok" << endl);
1739 //---------------------------------------------------------------------
1740 // Close the new MED file
1741 //---------------------------------------------------------------------
1742 ret = MEDfermer(newMEDfile);
1743 if (ret != 0) throw IOException("", __FILE__, __LINE__);
1746 void Mesh::readGaussLoc()
1748 MULTIPR_LOG("Gauss ref: ");
1749 med_int numGauss = MEDnGauss(mMEDfile);
1750 if (numGauss < 0) throw IOException("", __FILE__, __LINE__);
1751 MULTIPR_LOG(numGauss << ": OK\n");
1753 for (int itGauss = 1 ; itGauss <= numGauss ; itGauss++)
1755 GaussLoc* gaussLoc = new GaussLoc();
1756 gaussLoc->readMED(mMEDfile, itGauss);
1757 MULTIPR_LOG((*gaussLoc) << endl);
1758 mGaussLoc.push_back(gaussLoc);
1759 mGaussLocNameToGaussLoc.insert(make_pair(gaussLoc->getName(), gaussLoc));
1763 void Mesh::readFamilies()
1765 med_int numFamilies = MEDnFam(mMEDfile, mMeshName);
1766 if (numFamilies <= 0) throw IOException("", __FILE__, __LINE__);
1768 for (int itFam = 1 ; itFam <= numFamilies ; ++itFam)
1770 Family* fam = new Family();
1771 fam->readMED(mMEDfile, mMeshName, itFam);
1772 mFamilies.push_back(fam);
1777 void Mesh::finalizeFamiliesAndGroups()
1779 if (mFamilies.size() == 0)
1783 //---------------------------------------------------------------------
1784 // Build mapping between family id and pointers towards families
1785 //---------------------------------------------------------------------
1786 for (unsigned itFam = 0 ; itFam < mFamilies.size() ; ++itFam)
1788 Family* fam = mFamilies[itFam];
1789 mFamIdToFam.insert(make_pair(fam->getId(), fam));
1791 //---------------------------------------------------------------------
1792 // Fill families of nodes
1793 //---------------------------------------------------------------------
1794 for (int itNode = 1 ; itNode <= mNodes->getNumberOfNodes() ; ++itNode)
1796 // get family of the ith nodes
1797 int famIdent = mNodes->getFamIdent(itNode - 1); // MED nodes start at 1
1799 map<med_int, Family*>::iterator itFam = mFamIdToFam.find(famIdent);
1801 if (itFam == mFamIdToFam.end())
1804 sprintf(msg, "wrong family of nodes for node #%d: family %d not found", itNode, famIdent);
1805 throw IllegalStateException(msg, __FILE__, __LINE__);
1808 Family* fam = (*itFam).second;
1810 // add the current node to its family
1811 fam->insertElt(itNode);
1812 fam->setIsFamilyOfNodes(true);
1814 //---------------------------------------------------------------------
1815 // Fill families of elements
1816 //---------------------------------------------------------------------
1817 for (int itMesh = 0; itMesh < eMaxMedMesh; ++itMesh)
1819 if (mElements[itMesh] != NULL)
1821 for (int itElt = 1 ; itElt <= mElements[itMesh]->getNumberOfElements() ; itElt++)
1823 // get family of the ith element (MED index start at 1)
1824 int famIdent = mElements[itMesh]->getFamilyIdentifier(itElt - 1);
1826 map<med_int, Family*>::iterator itFam = mFamIdToFam.find(famIdent);
1828 if (itFam == mFamIdToFam.end())
1831 sprintf(msg, "wrong family of elements for element #%d: family %d not found", itElt, famIdent);
1832 throw IllegalStateException(msg, __FILE__, __LINE__);
1835 Family* fam = (*itFam).second;
1837 // add the current element to its family
1838 fam->insertElt( itElt, (eMeshType)itMesh);
1839 fam->setIsFamilyOfNodes(false);
1843 //---------------------------------------------------------------------
1845 //---------------------------------------------------------------------
1847 for (unsigned itFam = 0 ; itFam < mFamilies.size() ; itFam++)
1849 mFamilies[itFam]->buildGroups(mGroups, mGroupNameToGroup);
1854 void Mesh::readFields()
1856 //---------------------------------------------------------------------
1857 // Read number of fields
1858 //---------------------------------------------------------------------
1859 MULTIPR_LOG("Read fields: ");
1860 med_int numFields = MEDnChamp(mMEDfile, 0);
1861 if (numFields <= 0) throw IOException("", __FILE__, __LINE__);
1862 MULTIPR_LOG(numFields << ": OK\n");
1864 //---------------------------------------------------------------------
1865 // Iterate over fields
1866 //---------------------------------------------------------------------
1867 // for each field, read number of components and others infos
1868 for (int itField = 1 ; itField <= numFields ; itField++)
1870 for (int i = 0; i < eMaxMedMesh; ++i)
1872 Field* field = new Field();
1873 field->readMED(mMEDfile, itField, mMeshName, CELL_TYPES[i]);
1875 // if the nth field does not apply on our mesh => slip it
1876 if (field->isEmpty())
1882 mFields.push_back(field);
1883 // ReadMed will always work with fields on node so we need to stop the first time.
1884 // ie : CELL_TYPES[i] is not used in this case.
1885 if (field->isFieldOnNodes())
1895 ostream& operator<<(ostream& pOs, Mesh& pM)
1897 pOs << "Mesh: " << endl;
1898 pOs << " MED file =|" << pM.mMEDfilename << "|" << endl;
1899 pOs << " Name =|" << pM.mMeshName << "|" << endl;
1900 pOs << " Unv name =|" << pM.mMeshUName << "|" << endl;
1901 pOs << " Desc =|" << pM.mMeshDesc << "|" << endl;
1902 pOs << " Dim =" << pM.mMeshDim << endl;
1903 pOs << " Type =" << ((pM.mMeshType == MED_STRUCTURE)?"STRUCTURE":"NON_STRUCTURE") << endl;
1904 pOs << " BBox =[" << pM.mMeshBBoxMin[0] << " ; " << pM.mMeshBBoxMax[0] << "] x [" << pM.mMeshBBoxMin[1] << " ; " << pM.mMeshBBoxMax[1] << "] x [" << pM.mMeshBBoxMin[2] << " ; " << pM.mMeshBBoxMax[2] << "]" << endl;
1906 int numFamOfNodes = 0;
1907 for (unsigned i = 0 ; i < pM.mFamilies.size() ; i++)
1909 if (pM.mFamilies[i]->isFamilyOfNodes())
1915 int numGroupsOfNodes = 0;
1916 for (unsigned i = 0 ; i < pM.mGroups.size() ; i++)
1918 if (pM.mGroups[i]->isGroupOfNodes())
1924 if (pM.mFlagPrintAll)
1926 cout << (*(pM.mNodes)) << endl;
1927 for (int i = 0; i < eMaxMedMesh; ++i)
1929 if (pM.mElements[i] != NULL)
1931 cout << (*(pM.mElements[i])) << endl;
1935 pOs << " Families : #=" << pM.mFamilies.size() << " (nodes=" << numFamOfNodes << " ; elements=" << (pM.mFamilies.size() - numFamOfNodes) << ")" << endl;
1936 for (unsigned i = 0 ; i < pM.mFamilies.size() ; i++)
1938 cout << (*(pM.mFamilies[i])) << endl;
1941 pOs << " Groups : #=" << pM.mGroups.size() << " (nodes=" << numGroupsOfNodes << " ; elements=" << (pM.mGroups.size() - numGroupsOfNodes) << ")" << endl;
1942 for (unsigned i = 0 ; i < pM.mGroups.size() ; i++)
1944 cout << (*(pM.mGroups[i])) << endl;
1947 pOs << " Gauss loc: #=" << pM.mGaussLoc.size() << endl;
1948 for (unsigned i = 0 ; i < pM.mGaussLoc.size() ; i++)
1950 cout << (*(pM.mGaussLoc[i])) << endl;
1953 pOs << " Fields : #=" << pM.mFields.size() << endl;
1954 for (unsigned i = 0 ; i < pM.mFields.size() ; i++)
1956 cout << (*(pM.mFields[i])) << endl;
1961 if (pM.mNodes != NULL)
1963 pOs << " Nodes : #=" << pM.mNodes->getNumberOfNodes() << endl;
1965 for (int i = 0; i < eMaxMedMesh; ++i)
1967 if (pM.mElements[i] != NULL)
1969 const set<med_int>& setOfNodes = pM.mElements[i]->getSetOfNodes();
1970 if (setOfNodes.size() == 0)
1972 pOs << " Elt : #=" << pM.mElements[i]->getNumberOfElements() << endl;
1976 set<med_int>::iterator itNode = setOfNodes.end();
1978 pOs << " Elt : #=" << pM.mElements[i]->getNumberOfElements() << " node_id_min=" << (*(setOfNodes.begin())) << " node_id_max=" << (*itNode) << endl;
1982 pOs << " Families : #=" << pM.mFamilies.size() << " (nodes=" << numFamOfNodes << " ; elements=" << (pM.mFamilies.size() - numFamOfNodes) << ")" << endl;
1983 pOs << " Groups : #=" << pM.mGroups.size() << " (nodes=" << numGroupsOfNodes << " ; elements=" << (pM.mGroups.size() - numGroupsOfNodes) << ")" << endl;
1984 pOs << " Gauss loc: #=" << pM.mGaussLoc.size() << endl;
1985 pOs << " Fields : #=" << pM.mFields.size() << endl;
1992 } // namespace multipr