-// Copyright (C) 2007-2016 CEA/DEN, EDF R&D
+// Copyright (C) 2007-2023 CEA, EDF
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
#include <algorithm>
#include <iterator>
+// From MEDLoader.cxx TU:
extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
extern med_geometry_type typmainoeud[1];
-extern med_geometry_type typmai3[34];
+extern med_geometry_type typmai3[INTERP_KERNEL::NORM_MAXTYPE];
using namespace MEDCoupling;
int MEDFileFields::getNumberOfFields() const
{
- return _fields.size();
+ return (int)_fields.size();
}
std::vector<std::string> MEDFileFields::getFieldsNames() const
for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++)
{
const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it);
- std::string chapter(17,'0'+i);
+ std::string chapter(17,(char)('0'+i));
oss << startLine << chapter << std::endl;
if(cur)
{
MEDFileFields::MEDFileFields(med_idt fid, bool loadAll, const MEDFileMeshes *ms, const MEDFileEntities *entities)
try:MEDFileFieldGlobsReal(fid)
{
- int nbFields(MEDnField(fid));
+ med_int nbFields(MEDnField(fid));
_fields.resize(nbFields);
med_field_type typcha;
for(int i=0;i<nbFields;i++)
}
case MED_INT32:
{
- _fields[i]=MEDFileIntFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
+ _fields[i]=MEDFileInt32FieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
+ break;
+ }
+ case MED_INT64:
+ {
+ _fields[i]=MEDFileInt64FieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
break;
}
case MED_FLOAT32:
{
if(sizeof(med_int)==sizeof(int))
{
- _fields[i]=MEDFileIntFieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
+ _fields[i]=MEDFileInt32FieldMultiTSWithoutSDA::New(fid,fieldName,meshName,typcha,infos,nbOfStep,dtunit,loadAll,ms,entities);
break;
}
}
default:
{
- std::ostringstream oss; oss << "constructor MEDFileFields(fileName) : file \'" << FileNameFromFID(fid) << "\' at pos #" << i << " field has name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32, MED_FLOAT32] !";
+ std::ostringstream oss; oss << "constructor MEDFileFields(fileName) : file \'" << FileNameFromFID(fid) << "\' at pos #" << i << " field has name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32, MED_FLOAT32, MED_INT64] !";
throw INTERP_KERNEL::Exception(oss.str());
}
}
void MEDFileFields::destroyFieldsAtPos2(int bg, int end, int step)
{
static const char msg[]="MEDFileFields::destroyFieldsAtPos2";
- int nbOfEntriesToKill(DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg));
+ mcIdType nbOfEntriesToKill(DataArrayIdType::GetNumberOfItemGivenBESRelative(bg,end,step,msg));
std::vector<bool> b(_fields.size(),true);
int k=bg;
for(int i=0;i<nbOfEntriesToKill;i++,k+=step)
* \return If true a renumbering has been performed. The structure in \a this has been modified. If false, nothing has been done: it is typically the case if \a meshName is not referred by any
* field in \a this.
*/
-bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N)
+bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<mcIdType>& oldCode, const std::vector<mcIdType>& newCode, const DataArrayIdType *renumO2N)
{
bool ret(false);
for(std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++)
*
* \return A new object that the caller is responsible to deallocate.
*/
-MEDFileFields *MEDFileFields::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef, MEDFileMesh *mm) const
+MEDFileFields *MEDFileFields::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef, MEDFileMesh *mm) const
{
if(!mm)
throw INTERP_KERNEL::Exception("MEDFileFields::extractPart : input mesh is NULL !");
{
public:
PFLData():_add_pts_in_pfl(0) { }
- PFLData(const MCAuto<DataArrayInt>& mat, const MCAuto<DataArrayInt>& pfl, int nbOfNewPts):_matrix(mat),_pfl(pfl),_add_pts_in_pfl(nbOfNewPts) { }
+ PFLData(const MCAuto<DataArrayIdType>& mat, const MCAuto<DataArrayIdType>& pfl, mcIdType nbOfNewPts):_matrix(mat),_pfl(pfl),_add_pts_in_pfl(nbOfNewPts) { }
std::string getPflName() const { if(_pfl.isNull()) { return std::string(); } else { return _pfl->getName(); } }
- int getNbOfAddPtsInPfl() const { return _add_pts_in_pfl; }
- MCAuto<DataArrayInt> getProfile() const { return _pfl; }
- MCAuto<DataArrayInt> getMatrix() const { return _matrix; }
+ mcIdType getNbOfAddPtsInPfl() const { return _add_pts_in_pfl; }
+ MCAuto<DataArrayIdType> getProfile() const { return _pfl; }
+ MCAuto<DataArrayIdType> getMatrix() const { return _matrix; }
private:
- MCAuto<DataArrayInt> _matrix;
- MCAuto<DataArrayInt> _pfl;
- int _add_pts_in_pfl;
+ MCAuto<DataArrayIdType> _matrix;
+ MCAuto<DataArrayIdType> _pfl;
+ mcIdType _add_pts_in_pfl;
};
class MEDFileFieldLin2QuadVisitor : public MEDFileFieldVisitor
//
void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
private:
- void updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd, int deltaNbNodes);
+ void updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd, mcIdType deltaNbNodes);
private:
const MEDFileUMesh *_lin;
const MEDFileUMesh *_quad;
updateData(pmtdToModify,(*itCache).second.getNbOfAddPtsInPfl());
return ;
}
- MCAuto<DataArrayInt> pfl;
+ MCAuto<DataArrayIdType> pfl;
if(pflName.empty())
- pfl=DataArrayInt::Range(0,pmptpd->getNumberOfVals(),1);
+ pfl=DataArrayIdType::Range(0,pmptpd->getNumberOfVals(),1);
else
pfl=_lin_globs->getProfile(pflName)->deepCopy();
//
MCAuto<MEDCouplingUMesh> mesh3D(_lin->getMeshAtLevel(0)),mesh3DQuadratic(_quad->getMeshAtLevel(0));
- MCAuto<DataArrayInt> cellIds(mesh3D->getCellIdsLyingOnNodes(pfl->begin(),pfl->end(),true));
+ MCAuto<DataArrayIdType> cellIds(mesh3D->getCellIdsLyingOnNodes(pfl->begin(),pfl->end(),true));
MCAuto<MEDCouplingUMesh> mesh3DQuadraticRestricted(mesh3DQuadratic->buildPartOfMySelf(cellIds->begin(),cellIds->end(),true));
- MCAuto<DataArrayInt> mesh3DQuadraticRestrictedNodeIds(mesh3DQuadraticRestricted->computeFetchedNodeIds());
+ MCAuto<DataArrayIdType> mesh3DQuadraticRestrictedNodeIds(mesh3DQuadraticRestricted->computeFetchedNodeIds());
mesh3DQuadraticRestrictedNodeIds->checkMonotonic(true);
- MCAuto<DataArrayInt> newPtsIds(mesh3DQuadraticRestrictedNodeIds->buildSubstraction(pfl));
+ MCAuto<DataArrayIdType> newPtsIds(mesh3DQuadraticRestrictedNodeIds->buildSubstraction(pfl));
MCAuto<MEDCoupling1SGTUMesh> allSeg3;
{
- MCAuto<DataArrayInt> a,b,c,d;
+ MCAuto<DataArrayIdType> a,b,c,d;
MCAuto<MEDCouplingUMesh> seg3Tmp(mesh3DQuadraticRestricted->explodeIntoEdges(a,b,c,d));
allSeg3=MEDCoupling1SGTUMesh::New(seg3Tmp);
}
if(allSeg3->getCellModelEnum()!=INTERP_KERNEL::NORM_SEG3)
throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypePerDisc : invalid situation where SEG3 expected !");
- MCAuto<DataArrayInt> midPts,cellSeg3Ids,matrix;
+ MCAuto<DataArrayIdType> midPts,cellSeg3Ids,matrix;
{
- DataArrayInt *nodeConn(allSeg3->getNodalConnectivity());
+ DataArrayIdType *nodeConn(allSeg3->getNodalConnectivity());
nodeConn->rearrange(3);
{
- std::vector<int> v(1,2);
+ std::vector<std::size_t> v(1,2);
midPts=nodeConn->keepSelectedComponents(v);
}
- cellSeg3Ids=DataArrayInt::FindPermutationFromFirstToSecond(midPts,newPtsIds);
+ cellSeg3Ids=DataArrayIdType::FindPermutationFromFirstToSecond(midPts,newPtsIds);
{
- std::vector<int> v(2); v[0]=0; v[1]=1;
- MCAuto<DataArrayInt> tmp(nodeConn->keepSelectedComponents(v));
+ std::vector<std::size_t> v(2); v[0]=0; v[1]=1;
+ MCAuto<DataArrayIdType> tmp(nodeConn->keepSelectedComponents(v));
matrix=tmp->selectByTupleId(cellSeg3Ids->begin(),cellSeg3Ids->end());
}
nodeConn->rearrange(1);
}
- MCAuto<DataArrayInt> pflq;
+ MCAuto<DataArrayIdType> pflq;
if(!pflName.empty())
{
- std::vector<const DataArrayInt *> vs(2);
+ std::vector<const DataArrayIdType *> vs(2);
vs[0]=pfl; vs[1]=newPtsIds;
- pflq=DataArrayInt::Aggregate(vs);
+ pflq=DataArrayIdType::Aggregate(vs);
pflq->setName(pflName);
}
PFLData pdata(matrix,pflq,newPtsIds->getNumberOfTuples());
updateData(pmtdToModify,pdata.getNbOfAddPtsInPfl());
}
-void MEDFileFieldLin2QuadVisitor::updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd, int deltaNbNodes)
+void MEDFileFieldLin2QuadVisitor::updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd, mcIdType deltaNbNodes)
{
pmtd->incrementNbOfVals(deltaNbNodes);
}
return ;
if(_1ts_update_requested)
{
- MCAuto<DataArrayInt> matrix,oldPfl;
+ MCAuto<DataArrayIdType> matrix,oldPfl;
for(std::vector<std::string>::const_iterator it=_pfls_to_be_updated.begin();it!=_pfls_to_be_updated.end();it++)
{
std::map< std::string, PFLData >::const_iterator it2(_cache.find(*it));
DataArrayDouble *arr(_cur_f1ts->getUndergroundDataArray());
MCAuto<DataArrayDouble> res;
{
- std::vector<int> v(1,0),v2(1,1);
- MCAuto<DataArrayInt> pts0(matrix->keepSelectedComponents(v));
- MCAuto<DataArrayInt> pts1(matrix->keepSelectedComponents(v2));
+ std::vector<std::size_t> v(1,0),v2(1,1);
+ MCAuto<DataArrayIdType> pts0(matrix->keepSelectedComponents(v));
+ MCAuto<DataArrayIdType> pts1(matrix->keepSelectedComponents(v2));
if(oldPfl.isNotNull())
{
pts0=oldPfl->findIdForEach(pts0->begin(),pts0->end());
return 0;
MCAuto<MEDFileAnyTypeFieldMultiTS> ret;
const MEDFileFieldMultiTSWithoutSDA *fmtsC(dynamic_cast<const MEDFileFieldMultiTSWithoutSDA *>(fmts));
- const MEDFileIntFieldMultiTSWithoutSDA *fmtsC2(dynamic_cast<const MEDFileIntFieldMultiTSWithoutSDA *>(fmts));
+ const MEDFileInt32FieldMultiTSWithoutSDA *fmtsC2(dynamic_cast<const MEDFileInt32FieldMultiTSWithoutSDA *>(fmts));
+ const MEDFileInt64FieldMultiTSWithoutSDA *fmtsC4(dynamic_cast<const MEDFileInt64FieldMultiTSWithoutSDA *>(fmts));
const MEDFileFloatFieldMultiTSWithoutSDA *fmtsC3(dynamic_cast<const MEDFileFloatFieldMultiTSWithoutSDA *>(fmts));
if(fmtsC)
ret=MEDFileFieldMultiTS::New(*fmtsC,false);
else if(fmtsC2)
- ret=MEDFileIntFieldMultiTS::New(*fmtsC2,false);
+ ret=MEDFileInt32FieldMultiTS::New(*fmtsC2,false);
+ else if(fmtsC4)
+ ret=MEDFileInt64FieldMultiTS::New(*fmtsC4,false);
else if(fmtsC3)
ret=MEDFileFloatFieldMultiTS::New(*fmtsC3,false);
else
{
- std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : At pos #" << i << " field is neither double (FLOAT64) nor float (FLOAT32) nor integer (INT32) !";
+ std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : At pos #" << i << " field is neither double (FLOAT64) nor float (FLOAT32) nor integer (INT32) nor integer (INT64) !";
throw INTERP_KERNEL::Exception(oss.str());
}
ret->shallowCpyGlobs(*this);
void MEDFileFields::blowUpSE(MEDFileMeshes *ms, const MEDFileStructureElements *ses)
{
MEDFileBlowStrEltUp::DealWithSE(this,ms,ses);
+ this->aggregateFieldsOnSameMeshes(ms);
+}
+
+/*!
+ * This method is dedicated to explosed Structured Elements that can lead to exotic situation.
+ * Especially when there are several structured elements for a same field.
+ *
+ * This method looks into meshes into \a ms if there is presence of multiple mesh having same name.
+ * If so, these meshes are aggregated in the same order than \a ms.
+ * The fields in \a this lying on the same meshName are also aggregated in the same order than \a this.
+ */
+void MEDFileFields::aggregateFieldsOnSameMeshes(MEDFileMeshes *ms)
+{
+ if(!ms)
+ THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : ms is nullptr !");
+ //
+ std::vector<std::string> msNames(ms->getMeshesNames());
+ std::set<std::string> msNamesSet(msNames.begin(),msNames.end());
+ if(msNames.size() == msNamesSet.size())
+ return ;
+ //
+ std::map<std::string,std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA>> > fsByName;
+ for(auto fmts : _fields)
+ {
+ fsByName[fmts->getMeshName()].push_back(fmts);
+ }
+ std::vector<std::string> fieldsNamesToBeAggregated;
+ std::vector< MCAuto<MEDFileAnyTypeFieldMultiTSWithoutSDA> > otherFields;
+ std::set<std::string> expectedMeshNamesToMerge;
+ for(auto fieldsWithSame : fsByName)
+ {
+ if(fieldsWithSame.second.size() > 1)
+ {
+ fieldsNamesToBeAggregated.push_back(fieldsWithSame.first);
+ std::set< std::string > zeMeshNames;
+ for(auto fmtsWithSameName : fieldsWithSame.second)
+ zeMeshNames.insert(fmtsWithSameName->getMeshName());
+ if(zeMeshNames.size()!=1)
+ THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : Presence of multiple MultiTS instances with same name but lying on same meshName. Looks bad !");
+ std::string meshNameToMerge = *zeMeshNames.begin();
+ if(expectedMeshNamesToMerge.find(meshNameToMerge) != expectedMeshNamesToMerge.end())
+ THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : unexpected situation ! Error in implementation !");
+ expectedMeshNamesToMerge.insert(*zeMeshNames.begin());
+ }
+ else
+ {
+ otherFields.push_back(fieldsWithSame.second.front());
+ }
+ }
+ for(auto fieldNameToBeAggregated : fieldsNamesToBeAggregated)
+ {
+ auto base_fs = fsByName[fieldNameToBeAggregated].front();
+ auto fieldsToBeAggregated = fsByName[fieldNameToBeAggregated];
+ std::vector< std::vector< std::pair<int,mcIdType> > > dtsToAggregate;
+ std::vector< MCAuto<MEDFileAnyTypeFieldMultiTS> > eltsToAggregate;
+ for(auto fieldToBeAggregated : fieldsToBeAggregated)
+ {
+ std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<mcIdType,mcIdType> > > entries;
+ int iteration,order;
+ {
+ auto dtits = fieldToBeAggregated->getIterations();
+ iteration = dtits.front().first;
+ order = dtits.front().second;
+ }
+ fieldToBeAggregated->getUndergroundDataArrayExt(iteration,order,entries);
+ std::vector< std::pair<int,mcIdType> > dtsToPush;
+ for(auto entry : entries)
+ dtsToPush.push_back({entry.first.first,entry.second.second-entry.second.first});
+ dtsToAggregate.push_back(dtsToPush);
+ MCAuto<MEDFileAnyTypeFieldMultiTS> eltToAggregate = MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent(fieldToBeAggregated);
+ eltsToAggregate.push_back(eltToAggregate);
+ }
+ MCAuto<MEDFileAnyTypeFieldMultiTS> gg = MEDFileAnyTypeFieldMultiTS::Aggregate(FromVecAutoToVecOfConst(eltsToAggregate),dtsToAggregate);
+ gg->setMeshName(base_fs->getMeshName());
+ otherFields.push_back(gg->getContent());
+ }
+ // now deal with meshes
+ std::map<std::string,std::vector< MEDFileMesh *> > msByName;
+ for(auto iMesh = 0 ; iMesh < ms->getNumberOfMeshes() ; ++iMesh)
+ {
+ auto curMesh = ms->getMeshAtPos(iMesh);
+ msByName[curMesh->getName()].push_back(curMesh);
+ }
+ std::set<std::string> meshesNamesToBeAggregated;
+ std::vector< MCAuto<MEDFileMesh> > otherMeshes;
+ for(auto msWithSameName : msByName)
+ {
+ if(msWithSameName.second.size()>1)
+ meshesNamesToBeAggregated.insert(msWithSameName.first);
+ else
+ {
+ otherMeshes.push_back( MCAuto<MEDFileMesh>::TakeRef(msWithSameName.second.front()) );
+ }
+ }
+ if(meshesNamesToBeAggregated != expectedMeshNamesToMerge)
+ THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : mismatch between meshes to be aggregated and meshnames into fields to be aggregated");
+ std::vector<const DataArrayDouble *> coos;
+ for(auto meshNameToBeAggregated : meshesNamesToBeAggregated)
+ {
+ for(auto curMesh : msByName[meshNameToBeAggregated])
+ {
+ if(!curMesh->getNonEmptyLevels().empty())
+ THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : only meshes without cells supported.");
+ MEDFileUMesh *curMeshU(dynamic_cast<MEDFileUMesh *>(curMesh));
+ if(!curMeshU)
+ THROW_IK_EXCEPTION("MEDFileFields::aggregateFieldsOnSameMeshes : only unstructured mesh supported.");
+ coos.push_back(curMeshU->getCoords());
+ }
+ MCAuto<DataArrayDouble> coo=DataArrayDouble::Aggregate(coos);
+ MCAuto<MEDFileUMesh> gg = MEDFileUMesh::New();
+ gg->setName(meshNameToBeAggregated);
+ gg->setCoords(coo);
+ otherMeshes.push_back(DynamicCast<MEDFileUMesh,MEDFileMesh>(gg));
+ }
+ // until this point nothing has changed in \a this nor in \a ms as if a const method.
+ ms->resize(0);
+ for(auto mesh : otherMeshes)
+ ms->pushMesh(mesh);
+ _fields = otherFields;
}
MCAuto<MEDFileFields> MEDFileFields::partOfThisOnStructureElements() const
{
std::string tmp(fieldName);
std::vector<std::string> poss;
- for(std::size_t i=0;i<_fields.size();i++)
+ for(unsigned int i=0;i<_fields.size();i++)
{
const MEDFileAnyTypeFieldMultiTSWithoutSDA *f(_fields[i]);
if(f)