X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileField.cxx;h=3cb2da239d9b8fb74d964460d76b5813812da5ed;hb=0b187729ac99d3e9e9bb9d2be8cb8600a783be6c;hp=cc9e3fe602fafb922f1683ed5fbdb286b722b74a;hpb=8227661836f1b2714381d2403ddc1b9c7483079d;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index cc9e3fe60..3cb2da239 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -22,6 +22,8 @@ #include "MEDFileMesh.hxx" #include "MEDLoaderBase.hxx" #include "MEDFileUtilities.hxx" +#include "MEDFileSafeCaller.txx" +#include "MEDFileFieldOverView.hxx" #include "MEDCouplingFieldDouble.hxx" #include "MEDCouplingFieldDiscretization.hxx" @@ -35,11 +37,14 @@ extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; extern med_geometry_type typmainoeud[1]; -extern med_geometry_type typmai3[32]; +extern med_geometry_type typmai3[34]; -using namespace ParaMEDMEM; +using namespace MEDCoupling; -MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, const char *locName) +const char MEDFileField1TSWithoutSDA::TYPE_STR[]="FLOAT64"; +const char MEDFileIntField1TSWithoutSDA::TYPE_STR[]="INT32"; + +MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, const std::string& locName) { return new MEDFileFieldLoc(fid,locName); } @@ -49,26 +54,26 @@ MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, int id) return new MEDFileFieldLoc(fid,id); } -MEDFileFieldLoc *MEDFileFieldLoc::New(const char *locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) +MEDFileFieldLoc *MEDFileFieldLoc::New(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) { return new MEDFileFieldLoc(locName,geoType,refCoo,gsCoo,w); } -MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, const char *locName):_name(locName) +MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, const std::string& locName):_name(locName) { med_geometry_type geotype; med_geometry_type sectiongeotype; int nsectionmeshcell; INTERP_KERNEL::AutoPtr geointerpname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); INTERP_KERNEL::AutoPtr sectionmeshname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDlocalizationInfoByName(fid,locName,&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,§iongeotype); - _geo_type=(INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+32,geotype))); + MEDlocalizationInfoByName(fid,locName.c_str(),&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,§iongeotype); + _geo_type=(INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+34,geotype))); const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); _nb_node_per_cell=cm.getNumberOfNodes(); _ref_coo.resize(_dim*_nb_node_per_cell); _gs_coo.resize(_dim*_nb_gauss_pt); _w.resize(_nb_gauss_pt); - MEDlocalizationRd(fid,locName,MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]); + MEDlocalizationRd(fid,locName.c_str(),MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]); } MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, int id) @@ -81,7 +86,7 @@ MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, int id) INTERP_KERNEL::AutoPtr sectionmeshname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); MEDlocalizationInfo(fid,id+1,locName,&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,§iongeotype); _name=locName; - _geo_type=(INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+32,geotype))); + _geo_type=(INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+34,geotype))); const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); _nb_node_per_cell=cm.getNumberOfNodes(); _ref_coo.resize(_dim*_nb_node_per_cell); @@ -90,9 +95,9 @@ MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, int id) MEDlocalizationRd(fid,locName,MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]); } -MEDFileFieldLoc::MEDFileFieldLoc(const char *locName, INTERP_KERNEL::NormalizedCellType geoType, +MEDFileFieldLoc::MEDFileFieldLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w):_name(locName),_geo_type(geoType),_ref_coo(refCoo),_gs_coo(gsCoo), - _w(w) + _w(w) { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); _dim=cm.getDimension(); @@ -105,11 +110,16 @@ MEDFileFieldLoc *MEDFileFieldLoc::deepCpy() const return new MEDFileFieldLoc(*this); } -std::size_t MEDFileFieldLoc::getHeapMemorySize() const +std::size_t MEDFileFieldLoc::getHeapMemorySizeWithoutChildren() const { return (_ref_coo.capacity()+_gs_coo.capacity()+_w.capacity())*sizeof(double)+_name.capacity(); } +std::vector MEDFileFieldLoc::getDirectChildrenWithNull() const +{ + return std::vector(); +} + void MEDFileFieldLoc::simpleRepr(std::ostream& oss) const { static const char OFF7[]="\n "; @@ -123,7 +133,7 @@ void MEDFileFieldLoc::simpleRepr(std::ostream& oss) const oss << "GaussPtsCoords="; std::copy(_gs_coo.begin(),_gs_coo.end(),std::ostream_iterator(oss," ")); oss << std::endl; } -void MEDFileFieldLoc::setName(const char *name) +void MEDFileFieldLoc::setName(const std::string& name) { _name=name; } @@ -140,13 +150,13 @@ bool MEDFileFieldLoc::isEqual(const MEDFileFieldLoc& other, double eps) const return false; if(_geo_type!=other._geo_type) return false; - if(MEDCouplingGaussLocalization::AreAlmostEqual(_ref_coo,other._ref_coo,eps)) + if(!MEDCouplingGaussLocalization::AreAlmostEqual(_ref_coo,other._ref_coo,eps)) return false; - if(MEDCouplingGaussLocalization::AreAlmostEqual(_gs_coo,other._gs_coo,eps)) + if(!MEDCouplingGaussLocalization::AreAlmostEqual(_gs_coo,other._gs_coo,eps)) return false; - if(MEDCouplingGaussLocalization::AreAlmostEqual(_w,other._w,eps)) + if(!MEDCouplingGaussLocalization::AreAlmostEqual(_w,other._w,eps)) return false; - + return true; } @@ -196,16 +206,15 @@ std::string MEDFileFieldLoc::repr() const return oss.str(); } -void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) { _type=field->getTypeOfField(); - const DataArrayDouble *da=field->getArray(); _start=start; switch(_type) - { + { case ON_CELLS: { - getArray()->setContigPartOfSelectedValues2(_start,da,offset,offset+nbOfCells,1); + getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,offset,offset+nbOfCells,1); _end=_start+nbOfCells; _nval=nbOfCells; break; @@ -214,7 +223,7 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int off { MEDCouplingAutoRefCountObjectPtr arr=field->getDiscretization()->getOffsetArr(field->getMesh()); const int *arrPtr=arr->getConstPointer(); - getArray()->setContigPartOfSelectedValues2(_start,da,arrPtr[offset],arrPtr[offset+nbOfCells],1); + getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,arrPtr[offset],arrPtr[offset+nbOfCells],1); _end=_start+(arrPtr[offset+nbOfCells]-arrPtr[offset]); _nval=nbOfCells; break; @@ -235,7 +244,7 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int off const int *da3Ptr=da3->getConstPointer(); if(da3->getNumberOfTuples()!=nbOfCells) {//profile : for gauss even in NoProfile !!! - std::ostringstream oss; oss << "Pfl_" << getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; + std::ostringstream oss; oss << "Pfl_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; _profile=oss.str(); da3->setName(_profile.c_str()); glob.appendProfile(da3); @@ -250,16 +259,16 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int off for(int j=0;jsetContigPartOfSelectedValues(_start,da,da4); + getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,da4); _end=_start+_nval*nbi; glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights()); break; } default: throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile : not implemented yet for such discretization type of field !"); - } + } start=_end; } @@ -272,13 +281,19 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int off * \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points. * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. */ -void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arrr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) { _profile.clear(); _type=field->getTypeOfField(); std::string pflName(multiTypePfl->getName()); std::ostringstream oss; oss << pflName; - if(_type!=ON_NODES) { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); oss << "_" << cm.getRepr(); } else { oss << "_NODE"; } + if(_type!=ON_NODES) + { + if(!isPflAlone) + { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); oss << "_" << cm.getRepr(); } + } + else + { oss << "_NODE"; } if(locIds) { if(pflName.empty()) @@ -290,21 +305,20 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(int& start, const Dat _profile=oss.str(); } } - const DataArrayDouble *da=field->getArray(); _start=start; switch(_type) - { + { case ON_NODES: { - _nval=idsInPfl->getNumberOfTuples(); - getArray()->setContigPartOfSelectedValues2(_start,da,0,da->getNumberOfTuples(),1); - _end=_start+_nval; - break; + _nval=idsInPfl->getNumberOfTuples(); + getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,0,arrr->getNumberOfTuples(),1); + _end=_start+_nval; + break; } case ON_CELLS: { _nval=idsInPfl->getNumberOfTuples(); - getArray()->setContigPartOfSelectedValues(_start,da,idsInPfl); + getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,idsInPfl); _end=_start+_nval; break; } @@ -317,7 +331,7 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(int& start, const Dat MEDCouplingAutoRefCountObjectPtr tmp=idsInPfl->buildExplicitArrByRanges(arr3); int trueNval=tmp->getNumberOfTuples(); _nval=idsInPfl->getNumberOfTuples(); - getArray()->setContigPartOfSelectedValues(_start,da,tmp); + getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,tmp); _end=_start+trueNval; break; } @@ -346,7 +360,7 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(int& start, const Dat *tmpPtr++=j; // _nval=da4->getNumberOfTuples(); - getArray()->setContigPartOfSelectedValues(_start,da,tmp); + getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,tmp); _end=_start+trueNval; oss << "_loc_" << _loc_id; if(locIds) @@ -358,36 +372,36 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(int& start, const Dat } else { - if(da3->getNumberOfTuples()!=nbOfEltsInWholeMesh || !da3->isIdentity()) + if(!da3->isIdentity2(nbOfEltsInWholeMesh)) { da3->setName(oss.str().c_str()); glob.appendProfile(da3); _profile=oss.str(); } } - std::ostringstream oss2; oss2 << "Loc_" << getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; + std::ostringstream oss2; oss2 << "Loc_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; _localization=oss2.str(); glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights()); break; } default: throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : not implemented yet for such discretization type of field !"); - } + } start=_end; } -void MEDFileFieldPerMeshPerTypePerDisc::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob) { _start=start; - _nval=field->getArray()->getNumberOfTuples(); - getArray()->setContigPartOfSelectedValues2(_start,field->getArray(),0,_nval,1); + _nval=arrr->getNumberOfTuples(); + getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,0,_nval,1); _end=_start+_nval; start=_end; } -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt) throw(INTERP_KERNEL::Exception) +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd) { - return new MEDFileFieldPerMeshPerTypePerDisc(fath,type,profileIt); + return new MEDFileFieldPerMeshPerTypePerDisc(fath,type,profileIt,pd); } MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId) @@ -400,38 +414,112 @@ MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(const return new MEDFileFieldPerMeshPerTypePerDisc(other); } -std::size_t MEDFileFieldPerMeshPerTypePerDisc::getHeapMemorySize() const +std::size_t MEDFileFieldPerMeshPerTypePerDisc::getHeapMemorySizeWithoutChildren() const { - return _profile.capacity()+_localization.capacity()+5*sizeof(int); + return _profile.capacity()+_localization.capacity()+sizeof(MEDFileFieldPerMeshPerTypePerDisc); +} + +std::vector MEDFileFieldPerMeshPerTypePerDisc::getDirectChildrenWithNull() const +{ + std::vector ret(1); + ret[0]=(const PartDefinition*)_pd; + return ret; } -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::deepCpy(MEDFileFieldPerMeshPerType *father) const throw(INTERP_KERNEL::Exception) +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::deepCpy(MEDFileFieldPerMeshPerType *father) const { MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldPerMeshPerTypePerDisc(*this); ret->_father=father; return ret.retn(); } -MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField atype, int profileIt) throw(INTERP_KERNEL::Exception) -try:_type(atype),_father(fath) - { - } +MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField atype, int profileIt, const PartDefinition *pd) +try:_type(atype),_father(fath),_profile_it(profileIt),_pd(const_cast(pd)) +{ + if(pd) + pd->incrRef(); +} catch(INTERP_KERNEL::Exception& e) { - throw e; + throw e; } MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId, const std::string& dummy):_type(type),_father(fath),_loc_id(locId) { } -MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc& other):_type(other._type),_father(0),_start(other._start),_end(other._end),_nval(other._nval),_profile(other._profile),_localization(other._localization),_loc_id(other._loc_id),_tmp_work1(other._tmp_work1) +MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc& other):RefCountObject(other),_type(other._type),_father(0),_start(other._start),_end(other._end),_nval(other._nval),_profile(other._profile),_localization(other._localization),_loc_id(other._loc_id),_profile_it(other._profile_it),_pd(other._pd),_tmp_work1(other._tmp_work1) { } MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc():_type(ON_CELLS),_father(0),_start(-std::numeric_limits::max()),_end(-std::numeric_limits::max()), - _nval(-std::numeric_limits::max()),_loc_id(-std::numeric_limits::max()) + _nval(-std::numeric_limits::max()),_loc_id(-std::numeric_limits::max()) +{ +} + +void MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile(med_idt fid, const std::string& fieldName, int nbOfCompo, int iteration, int order, med_entity_type menti, med_geometry_type mgeoti, unsigned char *startFeedingPtr) { + const PartDefinition *pd(_pd); + if(!pd) + { + INTERP_KERNEL::AutoPtr locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + int nbi,tmp1; + med_int nbValsInFile(MEDfieldnValueWithProfileByName(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile.c_str(),MED_COMPACT_PFLMODE,&tmp1,locname,&nbi)); + if(_end-_start!=nbValsInFile*nbi) + { + std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : The number of tuples to read is " << nbValsInFile << "*" << nbi << " (nb integration points) ! But in data structure it values " << _end-_start << " is expected !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFILESAFECALLERRD0(MEDfieldValueWithProfileRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,MED_COMPACT_PFLMODE,_profile.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,startFeedingPtr)); + } + else + { + if(!_profile.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : not implemented !"); + INTERP_KERNEL::AutoPtr pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)),locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + int profilesize,nbi; + int overallNval(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi)); + const SlicePartDefinition *spd(dynamic_cast(pd)); + if(spd) + { + int start,stop,step; + spd->getSlice(start,stop,step); + int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(start,stop,step,"MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile")); + med_filter filter=MED_FILTER_INIT; + MEDfilterBlockOfEntityCr(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo, + MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, + /*start*/start+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, + /*lastblocksize=useless because count=1*/0,&filter); + MEDFILESAFECALLERRD0(MEDfieldValueAdvancedRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,startFeedingPtr)); + MEDfilterClose(&filter); + return ; + } + const DataArrayPartDefinition *dpd(dynamic_cast(pd)); + if(dpd) + { + dpd->checkCoherency(); + MEDCouplingAutoRefCountObjectPtr myIds(dpd->toDAI()); + int a(myIds->getMinValueInArray()),b(myIds->getMaxValueInArray()); + myIds->applyLin(1,-a); + int nbOfEltsToLoad(b-a+1); + med_filter filter=MED_FILTER_INIT; + {//TODO : manage int32 ! + MEDCouplingAutoRefCountObjectPtr tmp(DataArrayDouble::New()); + tmp->alloc(nbOfEltsToLoad,nbOfCompo); + MEDfilterBlockOfEntityCr(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo, + MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, + /*start*/a+1,/*stride*/1,/*count*/1,/*blocksize*/nbOfEltsToLoad, + /*lastblocksize=useless because count=1*/0,&filter); + MEDFILESAFECALLERRD0(MEDfieldValueAdvancedRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,reinterpret_cast(tmp->getPointer()))); + MEDCouplingAutoRefCountObjectPtr feeder(DataArrayDouble::New()); + feeder->useExternalArrayWithRWAccess(reinterpret_cast(startFeedingPtr),_nval,nbOfCompo); + feeder->setContigPartOfSelectedValues(0,tmp,myIds); + } + MEDfilterClose(&filter); + } + else + throw INTERP_KERNEL::Exception("Not implemented yet for not slices!"); + } } const MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerTypePerDisc::getFather() const @@ -439,23 +527,31 @@ const MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerTypePerDisc::getFather() return _father; } -void MEDFileFieldPerMeshPerTypePerDisc::prepareLoading(med_idt fid, int profileIt, int& start) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc) { - INTERP_KERNEL::AutoPtr locname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr pflname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - std::string fieldName=getName(); - std::string meshName=getMeshName(); - int iteration=getIteration(); - int order=getOrder(); - TypeOfField type=getType(); - INTERP_KERNEL::NormalizedCellType geoType=getGeoType(); + INTERP_KERNEL::AutoPtr locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + INTERP_KERNEL::AutoPtr pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + std::string fieldName(nasc.getName()),meshName(getMeshName()); + int iteration(getIteration()),order(getOrder()); + TypeOfField type(getType()); + INTERP_KERNEL::NormalizedCellType geoType(getGeoType()); int profilesize,nbi; med_geometry_type mgeoti; - med_entity_type menti=MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti); - _nval=MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,profileIt,MED_COMPACT_PFLMODE, - pflname,&profilesize,locname,&nbi); + med_entity_type menti(MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti)); + int zeNVal(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi)); _profile=MEDLoaderBase::buildStringFromFortran(pflname,MED_NAME_SIZE); _localization=MEDLoaderBase::buildStringFromFortran(locname,MED_NAME_SIZE); + const PartDefinition *pd(_pd); + if(!pd) + { + _nval=zeNVal; + } + else + { + if(!_profile.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively : profiles are not managed yet with part of def !"); + _nval=pd->getNumberOfElems(); + } _start=start; _end=start+_nval*nbi; start=_end; @@ -471,43 +567,51 @@ void MEDFileFieldPerMeshPerTypePerDisc::prepareLoading(med_idt fid, int profileI } } -void MEDFileFieldPerMeshPerTypePerDisc::finishLoading(med_idt fid, int profileIt, int ft) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::loadBigArray(med_idt fid, const MEDFileFieldNameScope& nasc) { - std::string fieldName=getName(); - std::string meshName=getMeshName(); - int iteration=getIteration(); - int order=getOrder(); - TypeOfField type=getType(); - INTERP_KERNEL::NormalizedCellType geoType=getGeoType(); + std::string fieldName(nasc.getName()),meshName(getMeshName()); + int iteration(getIteration()),order(getOrder()); + TypeOfField type(getType()); + INTERP_KERNEL::NormalizedCellType geoType(getGeoType()); med_geometry_type mgeoti; - med_entity_type menti=MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti); - DataArrayDouble *arr=getArray(); - double *startFeeding=arr->getPointer()+_start*arr->getNumberOfComponents(); - switch(ft) + med_entity_type menti(MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti)); + if(_start>_end) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : internal error in range !"); + if(_start==_end) + return ; + DataArray *arr(getOrCreateAndGetArray());//arr is not null due to the spec of getOrCreateAndGetArray + if(_start<0 || _start>=arr->getNumberOfTuples()) { - case 0: - { - MEDfieldValueWithProfileRd(fid,fieldName.c_str(),iteration,order,menti,mgeoti,MED_COMPACT_PFLMODE, - _profile.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,reinterpret_cast(startFeeding)); - break; - } - case 1: - { - INTERP_KERNEL::AutoPtr tmpp=new int[(_end-_start)*arr->getNumberOfComponents()]; - MEDfieldValueWithProfileRd(fid,fieldName.c_str(),iteration,order,menti,mgeoti,MED_COMPACT_PFLMODE, - _profile.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,reinterpret_cast((int *)tmpp)); - std::copy((const int *)tmpp,(const int *)tmpp+(_end-_start)*arr->getNumberOfComponents(),startFeeding); - break; - } - default: - throw INTERP_KERNEL::Exception("Error on array reading ! Unrecognized type of field ! Should be in FLOAT64 or INT32 !"); + std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : Invalid start ("<< _start << ") regarding admissible range of allocated array [0," << arr->getNumberOfTuples() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(_end<0 || _end>arr->getNumberOfTuples()) + { + std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : Invalid start ("<< _start << ") regarding admissible range of allocated array [0," << arr->getNumberOfTuples() << "] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfCompo(arr->getNumberOfComponents()); + DataArrayDouble *arrD(dynamic_cast(arr)); + if(arrD) + { + double *startFeeding(arrD->getPointer()+_start*nbOfCompo); + goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast(startFeeding)); + return ; + } + DataArrayInt *arrI(dynamic_cast(arr)); + if(arrI) + { + int *startFeeding(arrI->getPointer()+_start*nbOfCompo); + goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast(startFeeding)); + return ; } + throw INTERP_KERNEL::Exception("Error on array reading ! Unrecognized type of field ! Should be in FLOAT64 or INT32 !"); } /*! * Set a \c this->_start **and** \c this->_end keeping the same delta between the two. */ -void MEDFileFieldPerMeshPerTypePerDisc::setNewStart(int newValueOfStart) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::setNewStart(int newValueOfStart) { int delta=_end-_start; _start=newValueOfStart; @@ -529,11 +633,6 @@ double MEDFileFieldPerMeshPerTypePerDisc::getTime() const return _father->getTime(); } -std::string MEDFileFieldPerMeshPerTypePerDisc::getName() const -{ - return _father->getName(); -} - std::string MEDFileFieldPerMeshPerTypePerDisc::getMeshName() const { return _father->getMeshName(); @@ -558,7 +657,7 @@ TypeOfField MEDFileFieldPerMeshPerTypePerDisc::getType() const return _type; } -void MEDFileFieldPerMeshPerTypePerDisc::fillTypesOfFieldAvailable(std::set& types) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::fillTypesOfFieldAvailable(std::set& types) const { types.insert(_type); } @@ -583,15 +682,15 @@ int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfTuples() const return _end-_start; } -DataArrayDouble *MEDFileFieldPerMeshPerTypePerDisc::getArray() +DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray() { - return _father->getArray(); + return _father->getOrCreateAndGetArray(); } -const DataArrayDouble *MEDFileFieldPerMeshPerTypePerDisc::getArray() const +const DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray() const { const MEDFileFieldPerMeshPerType *fath=_father; - return fath->getArray(); + return fath->getOrCreateAndGetArray(); } const std::vector& MEDFileFieldPerMeshPerTypePerDisc::getInfo() const @@ -604,7 +703,7 @@ std::string MEDFileFieldPerMeshPerTypePerDisc::getProfile() const return _profile; } -void MEDFileFieldPerMeshPerTypePerDisc::setProfile(const char *newPflName) +void MEDFileFieldPerMeshPerTypePerDisc::setProfile(const std::string& newPflName) { _profile=newPflName; } @@ -614,12 +713,12 @@ std::string MEDFileFieldPerMeshPerTypePerDisc::getLocalization() const return _localization; } -void MEDFileFieldPerMeshPerTypePerDisc::setLocalization(const char *newLocName) +void MEDFileFieldPerMeshPerTypePerDisc::setLocalization(const std::string& newLocName) { _localization=newLocName; } -void MEDFileFieldPerMeshPerTypePerDisc::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) { for(std::vector< std::pair, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) { @@ -631,7 +730,7 @@ void MEDFileFieldPerMeshPerTypePerDisc::changePflsRefsNamesGen(const std::vector } } -void MEDFileFieldPerMeshPerTypePerDisc::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) { for(std::vector< std::pair, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) { @@ -669,20 +768,30 @@ void MEDFileFieldPerMeshPerTypePerDisc::fillValues(int discId, int& startEntryId startEntryId++; } -void MEDFileFieldPerMeshPerTypePerDisc::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const { TypeOfField type=getType(); INTERP_KERNEL::NormalizedCellType geoType=getGeoType(); med_geometry_type mgeoti; med_entity_type menti=MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti); - const DataArrayDouble *arr=getArray(); - const double *locToWrite=arr->getConstPointer()+_start*arr->getNumberOfComponents(); - MEDfieldValueWithProfileWr(fid,getName().c_str(),getIteration(),getOrder(),getTime(),menti,mgeoti, - MED_COMPACT_PFLMODE,_profile.c_str(),_localization.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,_nval, - reinterpret_cast(locToWrite)); + const DataArray *arr=getOrCreateAndGetArray(); + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : no array set !"); + const DataArrayDouble *arrD=dynamic_cast(arr); + const DataArrayInt *arrI=dynamic_cast(arr); + const unsigned char *locToWrite=0; + if(arrD) + locToWrite=reinterpret_cast(arrD->getConstPointer()+_start*arr->getNumberOfComponents()); + else if(arrI) + locToWrite=reinterpret_cast(arrI->getConstPointer()+_start*arr->getNumberOfComponents()); + else + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : not recognized type of values ! Supported are FLOAT64 and INT32 !"); + MEDFILESAFECALLERWR0(MEDfieldValueWithProfileWr,(fid,nasc.getName().c_str(),getIteration(),getOrder(),getTime(),menti,mgeoti, + MED_COMPACT_PFLMODE,_profile.c_str(),_localization.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,_nval, + locToWrite)); } -void MEDFileFieldPerMeshPerTypePerDisc::getCoarseData(TypeOfField& type, std::pair& dad, std::string& pfl, std::string& loc) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerTypePerDisc::getCoarseData(TypeOfField& type, std::pair& dad, std::string& pfl, std::string& loc) const { type=_type; pfl=_profile; @@ -696,7 +805,7 @@ void MEDFileFieldPerMeshPerTypePerDisc::getCoarseData(TypeOfField& type, std::pa * \param [out] ptToFill memory zone where the output will be stored. * \return the size of data pushed into output param \a ptToFill */ -int MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode(int offset, const std::vector& codeOfMesh, const MEDFileFieldGlobsReal& glob, int *ptToFill) const throw(INTERP_KERNEL::Exception) +int MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode(int offset, const std::vector& codeOfMesh, const MEDFileFieldGlobsReal& glob, int *ptToFill) const { _loc_id=offset; std::ostringstream oss; @@ -745,17 +854,17 @@ int MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode(int offset, const std: return _nval; } -int MEDFileFieldPerMeshPerTypePerDisc::fillTupleIds(int *ptToFill) const throw(INTERP_KERNEL::Exception) +int MEDFileFieldPerMeshPerTypePerDisc::fillTupleIds(int *ptToFill) const { for(int i=_start;i<_end;i++) *ptToFill++=i; return _end-_start; } -int MEDFileFieldPerMeshPerTypePerDisc::ConvertType(TypeOfField type, int locId) throw(INTERP_KERNEL::Exception) +int MEDFileFieldPerMeshPerTypePerDisc::ConvertType(TypeOfField type, int locId) { switch(type) - { + { case ON_CELLS: return -2; case ON_GAUSS_NE: @@ -764,7 +873,7 @@ int MEDFileFieldPerMeshPerTypePerDisc::ConvertType(TypeOfField type, int locId) return locId; default: throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::ConvertType : not managed type of field !"); - } + } } std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entries) @@ -850,9 +959,9 @@ bool MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(int offset, const std::ve int nbEntityElts=subIds->getNumberOfTuples(); bool ret2; MEDCouplingAutoRefCountObjectPtr eltToAdd=MEDFileFieldPerMeshPerTypePerDisc:: - NewObjectOnSameDiscThanPool(type,(INTERP_KERNEL::NormalizedCellType)newCode[3*(*idIt)],subIds,!subIds->isIdentity() || nbEntityElts!=newCode[3*(*idIt)+1],nbi, - offset+offset2, - li,glob,ret2); + NewObjectOnSameDiscThanPool(type,(INTERP_KERNEL::NormalizedCellType)newCode[3*(*idIt)],subIds,!subIds->isIdentity2(newCode[3*(*idIt)+1]),nbi, + offset+offset2, + li,glob,ret2); ret=ret || ret2; result.push_back(eltToAdd); offset2+=nbEntityElts*nbi; @@ -879,7 +988,7 @@ MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewObjectO bool isPfl, int nbi, int offset, std::list< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, MEDFileFieldGlobsReal& glob, - bool ¬InExisting) throw(INTERP_KERNEL::Exception) + bool ¬InExisting) { int nbMeshEntities=idsOfMeshElt->getNumberOfTuples(); std::list< const MEDFileFieldPerMeshPerTypePerDisc *>::iterator it=entriesOnSameDisc.begin(); @@ -928,28 +1037,33 @@ MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewObjectO entriesOnSameDisc.erase(it); return ret; } - + } -MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception) +MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd) { - return new MEDFileFieldPerMeshPerType(fid,fath,type,geoType); + return new MEDFileFieldPerMeshPerType(fid,fath,type,geoType,nasc,pd); } -MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception) +MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType) { return new MEDFileFieldPerMeshPerType(fath,geoType); } -std::size_t MEDFileFieldPerMeshPerType::getHeapMemorySize() const +std::size_t MEDFileFieldPerMeshPerType::getHeapMemorySizeWithoutChildren() const +{ + return _field_pm_pt_pd.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); +} + +std::vector MEDFileFieldPerMeshPerType::getDirectChildrenWithNull() const { - std::size_t ret=_field_pm_pt_pd.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + std::vector ret; for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - ret+=(*it)->getHeapMemorySize(); + ret.push_back((const MEDFileFieldPerMeshPerTypePerDisc *)*it); return ret; } -MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::deepCpy(MEDFileFieldPerMesh *father) const throw(INTERP_KERNEL::Exception) +MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::deepCpy(MEDFileFieldPerMesh *father) const { MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldPerMeshPerType(*this); ret->_father=father; @@ -962,11 +1076,11 @@ MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::deepCpy(MEDFileFieldPerM return ret.retn(); } -void MEDFileFieldPerMeshPerType::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) { std::vector pos=addNewEntryIfNecessary(field,offset,nbOfCells); for(std::vector::const_iterator it=pos.begin();it!=pos.end();it++) - _field_pm_pt_pd[*it]->assignFieldNoProfile(start,offset,nbOfCells,field,glob); + _field_pm_pt_pd[*it]->assignFieldNoProfile(start,offset,nbOfCells,field,arr,glob,nasc); } /*! @@ -978,30 +1092,31 @@ void MEDFileFieldPerMeshPerType::assignFieldNoProfile(int& start, int offset, in * \param [in] nbOfEltsInWholeMesh nb of elts of type \a this->_geo_type in \b WHOLE mesh * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. */ -void MEDFileFieldPerMeshPerType::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) { std::vector pos=addNewEntryIfNecessary(field,idsInPfl); for(std::vector::const_iterator it=pos.begin();it!=pos.end();it++) - _field_pm_pt_pd[*it]->assignFieldProfile(start,multiTypePfl,idsInPfl,locIds,nbOfEltsInWholeMesh,field,mesh,glob); + _field_pm_pt_pd[*it]->assignFieldProfile(isPflAlone,start,multiTypePfl,idsInPfl,locIds,nbOfEltsInWholeMesh,field,arr,mesh,glob,nasc); } -void MEDFileFieldPerMeshPerType::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) { _field_pm_pt_pd.resize(1); _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3); - _field_pm_pt_pd[0]->assignNodeFieldNoProfile(start,field,glob); + _field_pm_pt_pd[0]->assignNodeFieldNoProfile(start,field,arr,glob); } -void MEDFileFieldPerMeshPerType::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) { MEDCouplingAutoRefCountObjectPtr pfl2=pfl->deepCpy(); - // + if(!arr || !arr->isAllocated()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerType::assignNodeFieldProfile : input array is null, or not allocated !"); _field_pm_pt_pd.resize(1); _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3); - _field_pm_pt_pd[0]->assignFieldProfile(start,pfl,pfl2,pfl2,-1,field,0,glob);//mesh is not requested so 0 is send. + _field_pm_pt_pd[0]->assignFieldProfile(true,start,pfl,pfl2,pfl2,-1,field,arr,0,glob,nasc);//mesh is not requested so 0 is send. } -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) throw(INTERP_KERNEL::Exception) +std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) { TypeOfField type=field->getTypeOfField(); if(type!=ON_GAUSS_PT) @@ -1022,7 +1137,7 @@ std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCou _field_pm_pt_pd.resize(sz+1); _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); } - std::vector ret(1,0); + std::vector ret(1,(int)sz); return ret; } else @@ -1056,7 +1171,7 @@ std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCou } } -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) throw(INTERP_KERNEL::Exception) +std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) { const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast(disc); @@ -1073,7 +1188,7 @@ std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const M return ret; } -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells) throw(INTERP_KERNEL::Exception) +std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells) { TypeOfField type=field->getTypeOfField(); if(type!=ON_GAUSS_PT) @@ -1128,7 +1243,7 @@ std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCou } } -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells) throw(INTERP_KERNEL::Exception) +std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells) { const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast(disc); @@ -1157,7 +1272,7 @@ void MEDFileFieldPerMeshPerType::getDimension(int& dim) const dim=std::max(dim,curDim); } -void MEDFileFieldPerMeshPerType::fillTypesOfFieldAvailable(std::set& types) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::fillTypesOfFieldAvailable(std::set& types) const { for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) { @@ -1165,7 +1280,7 @@ void MEDFileFieldPerMeshPerType::fillTypesOfFieldAvailable(std::set } } -void MEDFileFieldPerMeshPerType::fillFieldSplitedByType(std::vector< std::pair >& dads, std::vector& types, std::vector& pfls, std::vector& locs) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::fillFieldSplitedByType(std::vector< std::pair >& dads, std::vector& types, std::vector& pfls, std::vector& locs) const { int sz=_field_pm_pt_pd.size(); dads.resize(sz); types.resize(sz); pfls.resize(sz); locs.resize(sz); @@ -1190,11 +1305,6 @@ double MEDFileFieldPerMeshPerType::getTime() const return _father->getTime(); } -std::string MEDFileFieldPerMeshPerType::getName() const -{ - return _father->getName(); -} - std::string MEDFileFieldPerMeshPerType::getMeshName() const { return _father->getMeshName(); @@ -1247,15 +1357,27 @@ int MEDFileFieldPerMeshPerType::getNumberOfComponents() const return _father->getNumberOfComponents(); } -DataArrayDouble *MEDFileFieldPerMeshPerType::getArray() +bool MEDFileFieldPerMeshPerType::presenceOfMultiDiscPerGeoType() const +{ + std::size_t nb(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + { + const MEDFileFieldPerMeshPerTypePerDisc *fmtd(*it); + if(fmtd) + nb++; + } + return nb>1; +} + +DataArray *MEDFileFieldPerMeshPerType::getOrCreateAndGetArray() { - return _father->getArray(); + return _father->getOrCreateAndGetArray(); } -const DataArrayDouble *MEDFileFieldPerMeshPerType::getArray() const +const DataArray *MEDFileFieldPerMeshPerType::getOrCreateAndGetArray() const { const MEDFileFieldPerMesh *fath=_father; - return fath->getArray(); + return fath->getOrCreateAndGetArray(); } const std::vector& MEDFileFieldPerMeshPerType::getInfo() const @@ -1322,19 +1444,19 @@ std::vector MEDFileFieldPerMeshPerType::getLocsReallyUsedMulti() co return ret; } -void MEDFileFieldPerMeshPerType::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) { for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) (*it1)->changePflsRefsNamesGen(mapOfModif); } -void MEDFileFieldPerMeshPerType::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) { for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) (*it1)->changeLocsRefsNamesGen(mapOfModif); } -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId(int locId) throw(INTERP_KERNEL::Exception) +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId(int locId) { if(_field_pm_pt_pd.empty()) { @@ -1351,7 +1473,7 @@ MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId return static_cast(0); } -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId(int locId) const throw(INTERP_KERNEL::Exception) +const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId(int locId) const { if(_field_pm_pt_pd.empty()) { @@ -1389,62 +1511,105 @@ void MEDFileFieldPerMeshPerType::fillValues(int& startEntryId, std::vector< std: } } -void MEDFileFieldPerMeshPerType::setLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::setLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) { _field_pm_pt_pd=leaves; for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) (*it)->setFather(this); } -MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception):_father(fath),_geo_type(geoType) +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + * \return bool - false if the type of field \a tof is not contained in \a this. + */ +bool MEDFileFieldPerMeshPerType::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) +{ + bool ret(false); + std::vector< MEDCouplingAutoRefCountObjectPtr > newPmPtPd; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + if((*it)->getType()==tof) + { + newPmPtPd.push_back(*it); + std::pair bgEnd; bgEnd.first=(*it)->getStart(); bgEnd.second=(*it)->getEnd(); + (*it)->setNewStart(globalNum); + globalNum=(*it)->getEnd(); + its.push_back(bgEnd); + ret=true; + } + if(ret) + _field_pm_pt_pd=newPmPtPd; + return ret; +} + +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + * \return bool - false if the type of field \a tof is not contained in \a this. + */ +bool MEDFileFieldPerMeshPerType::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its) +{ + if(_field_pm_pt_pd.size()<=idOfDisc) + return false; + MEDCouplingAutoRefCountObjectPtr elt(_field_pm_pt_pd[idOfDisc]); + std::vector< MEDCouplingAutoRefCountObjectPtr > newPmPtPd(1,elt); + std::pair bgEnd; bgEnd.first=_field_pm_pt_pd[idOfDisc]->getStart(); bgEnd.second=_field_pm_pt_pd[idOfDisc]->getEnd(); + elt->setNewStart(globalNum); + globalNum=elt->getEnd(); + its.push_back(bgEnd); + _field_pm_pt_pd=newPmPtPd; + return true; +} + +MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType):_father(fath),_geo_type(geoType) { } -MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception):_father(fath),_geo_type(geoType) +MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd):_father(fath),_geo_type(geoType) { INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); INTERP_KERNEL::AutoPtr locName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); med_geometry_type mgeoti; - med_entity_type menti=ConvertIntoMEDFileType(type,geoType,mgeoti); - int nbProfiles=MEDfieldnProfile(fid,getName().c_str(),getIteration(),getOrder(),menti,mgeoti,pflName,locName); + med_entity_type menti(ConvertIntoMEDFileType(type,geoType,mgeoti)); + int nbProfiles(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),menti,mgeoti,pflName,locName)); _field_pm_pt_pd.resize(nbProfiles); for(int i=0;i >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,pflId++) - { - (*it)->prepareLoading(fid,pflId+1,start); - } + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + (*it)->loadOnlyStructureOfDataRecursively(fid,start,nasc); } -void MEDFileFieldPerMeshPerType::finishLoading(med_idt fid, int ft) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) { - int pflId=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,pflId++) - { - (*it)->finishLoading(fid,pflId+1,ft); - } + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + (*it)->loadBigArray(fid,nasc); } -void MEDFileFieldPerMeshPerType::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMeshPerType::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const { for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) { (*it)->copyOptionsFrom(*this); - (*it)->writeLL(fid); + (*it)->writeLL(fid,nasc); } } med_entity_type MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(TypeOfField ikType, INTERP_KERNEL::NormalizedCellType ikGeoType, med_geometry_type& medfGeoType) { switch(ikType) - { + { case ON_CELLS: medfGeoType=typmai3[(int)ikGeoType]; return MED_CELL; @@ -1459,30 +1624,34 @@ med_entity_type MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(TypeOfField i return MED_CELL; default: throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType : unexpected entity type ! internal error"); - } + } return MED_UNDEF_ENTITY_TYPE; } -MEDFileFieldPerMesh *MEDFileFieldPerMesh::NewOnRead(med_idt fid, MEDFileField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder) throw(INTERP_KERNEL::Exception) +MEDFileFieldPerMesh *MEDFileFieldPerMesh::NewOnRead(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair > *entities) { - return new MEDFileFieldPerMesh(fid,fath,meshCsit,meshIteration,meshOrder); + return new MEDFileFieldPerMesh(fid,fath,meshCsit,meshIteration,meshOrder,nasc,mm,entities); } -MEDFileFieldPerMesh *MEDFileFieldPerMesh::New(MEDFileField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh) +MEDFileFieldPerMesh *MEDFileFieldPerMesh::New(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh) { return new MEDFileFieldPerMesh(fath,mesh); } -std::size_t MEDFileFieldPerMesh::getHeapMemorySize() const +std::size_t MEDFileFieldPerMesh::getHeapMemorySizeWithoutChildren() const { - std::size_t ret=_mesh_name.capacity()+_field_pm_pt.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType >); + return _mesh_name.capacity()+_field_pm_pt.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType >); +} + +std::vector MEDFileFieldPerMesh::getDirectChildrenWithNull() const +{ + std::vector ret; for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - if((const MEDFileFieldPerMeshPerType *)*it) - ret+=(*it)->getHeapMemorySize(); + ret.push_back((const MEDFileFieldPerMeshPerType *)*it); return ret; } -MEDFileFieldPerMesh *MEDFileFieldPerMesh::deepCpy(MEDFileField1TSWithoutSDA *father) const throw(INTERP_KERNEL::Exception) +MEDFileFieldPerMesh *MEDFileFieldPerMesh::deepCpy(MEDFileAnyTypeField1TSWithoutSDA *father) const { MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > ret=new MEDFileFieldPerMesh(*this); ret->_father=father; @@ -1513,13 +1682,13 @@ void MEDFileFieldPerMesh::simpleRepr(int bkOffset, std::ostream& oss, int id) co } } -void MEDFileFieldPerMesh::copyTinyInfoFrom(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::copyTinyInfoFrom(const MEDCouplingMesh *mesh) { _mesh_name=mesh->getName(); mesh->getTime(_mesh_iteration,_mesh_order); } -void MEDFileFieldPerMesh::assignFieldNoProfileNoRenum(int& start, const std::vector& code, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::assignFieldNoProfileNoRenum(int& start, const std::vector& code, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) { int nbOfTypes=code.size()/3; int offset=0; @@ -1528,7 +1697,7 @@ void MEDFileFieldPerMesh::assignFieldNoProfileNoRenum(int& start, const std::vec INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)code[3*i]; int nbOfCells=code[3*i+1]; int pos=addNewEntryIfNecessary(type); - _field_pm_pt[pos]->assignFieldNoProfile(start,offset,nbOfCells,field,glob); + _field_pm_pt[pos]->assignFieldNoProfile(start,offset,nbOfCells,field,arr,glob,nasc); offset+=nbOfCells; } } @@ -1542,9 +1711,9 @@ void MEDFileFieldPerMesh::assignFieldNoProfileNoRenum(int& start, const std::vec * \param [in] idsPerType is a vector containing the profiles needed to be created for MED file format. \b WARNING these processed MED file profiles can be subdivided again in case of Gauss points. * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. */ -void MEDFileFieldPerMesh::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector& code, const std::vector& code2, const std::vector& idsInPflPerType, const std::vector& idsPerType, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector& code, const std::vector& code2, const std::vector& idsInPflPerType, const std::vector& idsPerType, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) { - int nbOfTypes=code.size()/3; + int nbOfTypes(code.size()/3); for(int i=0;iassignFieldProfile(start,multiTypePfl,idsInPflPerType[i],pfl,code2[3*found+1],field,mesh,glob); + _field_pm_pt[pos]->assignFieldProfile(nbOfTypes==1,start,multiTypePfl,idsInPflPerType[i],pfl,code2[3*found+1],field,arr,mesh,glob,nasc); } } -void MEDFileFieldPerMesh::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) { int pos=addNewEntryIfNecessary(INTERP_KERNEL::NORM_ERROR); - _field_pm_pt[pos]->assignNodeFieldNoProfile(start,field,glob); + _field_pm_pt[pos]->assignNodeFieldNoProfile(start,field,arr,glob); } -void MEDFileFieldPerMesh::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) { int pos=addNewEntryIfNecessary(INTERP_KERNEL::NORM_ERROR); - _field_pm_pt[pos]->assignNodeFieldProfile(start,pfl,field,glob); + _field_pm_pt[pos]->assignNodeFieldProfile(start,pfl,field,arr,glob,nasc); } -void MEDFileFieldPerMesh::prepareLoading(med_idt fid, int& start) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc) { for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->prepareLoading(fid,start); + (*it)->loadOnlyStructureOfDataRecursively(fid,start,nasc); } -void MEDFileFieldPerMesh::finishLoading(med_idt fid, int ft) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) { for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->finishLoading(fid,ft); + (*it)->loadBigArraysRecursively(fid,nasc); } -void MEDFileFieldPerMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const { int nbOfTypes=_field_pm_pt.size(); for(int i=0;icopyOptionsFrom(*this); - _field_pm_pt[i]->writeLL(fid); + _field_pm_pt[i]->writeLL(fid,nasc); } } @@ -1603,13 +1772,13 @@ void MEDFileFieldPerMesh::getDimension(int& dim) const (*it)->getDimension(dim); } -void MEDFileFieldPerMesh::fillTypesOfFieldAvailable(std::set& types) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::fillTypesOfFieldAvailable(std::set& types) const { for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) (*it)->fillTypesOfFieldAvailable(types); } -std::vector< std::vector< std::pair > > MEDFileFieldPerMesh::getFieldSplitedByType(std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector > & locs) const throw(INTERP_KERNEL::Exception) +std::vector< std::vector< std::pair > > MEDFileFieldPerMesh::getFieldSplitedByType(std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector > & locs) const { int sz=_field_pm_pt.size(); std::vector< std::vector > > ret(sz); @@ -1633,35 +1802,41 @@ int MEDFileFieldPerMesh::getIteration() const return _father->getIteration(); } -const std::string& MEDFileFieldPerMesh::getDtUnit() const -{ - return _father->getDtUnit(); -} - int MEDFileFieldPerMesh::getOrder() const { return _father->getOrder(); } -std::string MEDFileFieldPerMesh::getName() const +int MEDFileFieldPerMesh::getNumberOfComponents() const { - return _father->getName(); + return _father->getNumberOfComponents(); } -int MEDFileFieldPerMesh::getNumberOfComponents() const +bool MEDFileFieldPerMesh::presenceOfMultiDiscPerGeoType() const { - return _father->getNumberOfComponents(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + const MEDFileFieldPerMeshPerType *fpmt(*it); + if(!fpmt) + continue; + if(fpmt->presenceOfMultiDiscPerGeoType()) + return true; + } + return false; } -DataArrayDouble *MEDFileFieldPerMesh::getArray() +DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray() { + if(!_father) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getOrCreateAndGetArray : no father ! internal error !"); return _father->getOrCreateAndGetArray(); } -const DataArrayDouble *MEDFileFieldPerMesh::getArray() const +const DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray() const { - const MEDFileField1TSWithoutSDA *fath=_father; - return fath->getOrCreateAndGetArray(); + if(!_father) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getOrCreateAndGetArray : no father ! internal error !"); + return _father->getOrCreateAndGetArray(); } const std::vector& MEDFileFieldPerMesh::getInfo() const @@ -1725,7 +1900,7 @@ void MEDFileFieldPerMesh::SortArraysPerType(const MEDFileFieldGlobsReal *glob, T /*! * 'dads' 'geoTypes' and 'locs' are input parameters that should have same size sz. sz should be >=1. */ -int MEDFileFieldPerMesh::ComputeNbOfElems(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& locs) throw(INTERP_KERNEL::Exception) +int MEDFileFieldPerMesh::ComputeNbOfElems(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& locs) { int sz=dads.size(); int ret=0; @@ -1806,7 +1981,7 @@ std::vector MEDFileFieldPerMesh::getLocsReallyUsedMulti() const return ret; } -bool MEDFileFieldPerMesh::changeMeshNames(const std::vector< std::pair >& modifTab) throw(INTERP_KERNEL::Exception) +bool MEDFileFieldPerMesh::changeMeshNames(const std::vector< std::pair >& modifTab) { for(std::vector< std::pair >::const_iterator it=modifTab.begin();it!=modifTab.end();it++) { @@ -1819,8 +1994,8 @@ bool MEDFileFieldPerMesh::changeMeshNames(const std::vector< std::pair& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, - MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +bool MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, + MEDFileFieldGlobsReal& glob) { if(_mesh_name!=meshName) return false; @@ -1829,7 +2004,13 @@ bool MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh(const char *meshName, cons std::vector< std::pair,std::pair > > entries; std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> entriesKept; std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> otherEntries; - DataArrayDouble *arr=getUndergroundDataArrayExt(entries); + getUndergroundDataArrayExt(entries); + DataArray *arr0=getOrCreateAndGetArray();//tony + if(!arr0) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArray storing values of field is null !"); + DataArrayDouble *arr=dynamic_cast(arr0);//tony + if(!arr0) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArray storing values is double ! Not managed for the moment !"); int sz=0; if(!arr) throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArrayDouble storing values of field is null !"); @@ -1912,7 +2093,45 @@ bool MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh(const char *meshName, cons return true; } -void MEDFileFieldPerMesh::assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) throw(INTERP_KERNEL::Exception) +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + */ +void MEDFileFieldPerMesh::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + std::vector< std::pair > its2; + if((*it)->keepOnlySpatialDiscretization(tof,globalNum,its2)) + { + ret.push_back(*it); + its.insert(its.end(),its2.begin(),its2.end()); + } + } + _field_pm_pt=ret; +} + +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + */ +void MEDFileFieldPerMesh::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + std::vector< std::pair > its2; + if((*it)->keepOnlyGaussDiscretization(idOfDisc,globalNum,its2)) + { + ret.push_back(*it); + its.insert(its.end(),its2.begin(),its2.end()); + } + } + _field_pm_pt=ret; +} + +void MEDFileFieldPerMesh::assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) { std::map > > types; for( std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >::const_iterator it=leaves.begin();it!=leaves.end();it++) @@ -1930,13 +2149,13 @@ void MEDFileFieldPerMesh::assignNewLeaves(const std::vector< MEDCouplingAutoRefC _field_pm_pt=fieldPmPt; } -void MEDFileFieldPerMesh::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) { for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) (*it)->changePflsRefsNamesGen(mapOfModif); } -void MEDFileFieldPerMesh::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) { for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) (*it)->changeLocsRefsNamesGen(mapOfModif); @@ -1945,7 +2164,7 @@ void MEDFileFieldPerMesh::changeLocsRefsNamesGen(const std::vector< std::pair& arrOut, const MEDFileFieldNameScope& nasc) const { if(_field_pm_pt.empty()) throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : no types field set !"); @@ -1961,7 +2180,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(TypeOfField t SortArraysPerType(glob,type,geoTypes,dads,pfls,locs,code,notNullPflsPerGeoType); if(code.empty()) { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : " << "The field \"" << getName() << "\" exists but not with such spatial discretization or such dimension specified !"; + std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : " << "The field \"" << nasc.getName() << "\" exists but not with such spatial discretization or such dimension specified !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } // @@ -1971,11 +2190,11 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(TypeOfField t { DataArrayInt *arr=mesh->checkTypeConsistencyAndContig(code,notNullPflsPerGeoType3); if(!arr) - return finishField(type,glob,dads,locs,mesh,isPfl); + return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); else { MEDCouplingAutoRefCountObjectPtr arr2(arr); - return finishField2(type,glob,dads,locs,geoTypes,mesh,arr,isPfl); + return finishField2(type,glob,dads,locs,geoTypes,mesh,arr,isPfl,arrOut,nasc); } } else @@ -1991,14 +2210,14 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(TypeOfField t oss << " nodes in mesh !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - return finishField(type,glob,dads,locs,mesh,isPfl); + return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); } else - return finishFieldNode2(glob,dads,locs,mesh,notNullPflsPerGeoType3[0],isPfl); + return finishFieldNode2(glob,dads,locs,mesh,notNullPflsPerGeoType3[0],isPfl,arrOut,nasc); } } -DataArrayDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob) const throw(INTERP_KERNEL::Exception) +DataArray *MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const { if(_field_pm_pt.empty()) throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : no types field set !"); @@ -2014,7 +2233,7 @@ DataArrayDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl(TypeOfField t SortArraysPerType(glob,type,geoTypes,dads,pfls,locs,code,notNullPflsPerGeoType); if(code.empty()) { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl : " << "The field \"" << getName() << "\" exists but not with such spatial discretization or such dimension specified !"; + std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl : " << "The field \"" << nasc.getName() << "\" exists but not with such spatial discretization or such dimension specified !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } std::vector< MEDCouplingAutoRefCountObjectPtr > notNullPflsPerGeoType2(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); @@ -2044,7 +2263,7 @@ DataArrayDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl(TypeOfField t return 0; } -DataArrayDouble *MEDFileFieldPerMesh::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldPerMesh::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const { int globalSz=0; int nbOfEntries=0; @@ -2058,10 +2277,9 @@ DataArrayDouble *MEDFileFieldPerMesh::getUndergroundDataArrayExt(std::vector< st { (*it)->fillValues(nbOfEntries,entries); } - return _father->getUndergroundDataArray(); } -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) throw(INTERP_KERNEL::Exception) +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) { for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) { @@ -2079,7 +2297,7 @@ MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId throw INTERP_KERNEL::Exception(oss.str().c_str()); } -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) const throw(INTERP_KERNEL::Exception) +const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) const { for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) { @@ -2125,16 +2343,15 @@ int MEDFileFieldPerMesh::addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellTyp */ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob, const std::vector< std::pair >& dads, const std::vector& locs, - const MEDCouplingMesh *mesh, bool& isPfl) const throw(INTERP_KERNEL::Exception) + const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const { isPfl=false; MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(type,ONE_TIME); - ret->setMesh(mesh); ret->setName(getName().c_str()); ret->setTime(getTime(),getIteration(),getOrder()); ret->setTimeUnit(getDtUnit().c_str()); - MEDCouplingAutoRefCountObjectPtr da=getArray()->selectByTupleRanges(dads); + ret->setMesh(mesh); ret->setName(nasc.getName().c_str()); ret->setTime(getTime(),getIteration(),getOrder()); ret->setTimeUnit(nasc.getDtUnit().c_str()); + MEDCouplingAutoRefCountObjectPtr da=getOrCreateAndGetArray()->selectByTupleRanges(dads); const std::vector& infos=getInfo(); da->setInfoOnComponents(infos); da->setName(""); - ret->setArray(da); if(type==ON_GAUSS_PT) { int offset=0; @@ -2152,7 +2369,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const offset+=nbOfElems; } } - // + arrOut=da; return ret.retn(); } @@ -2166,17 +2383,13 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField2(TypeOfField type, const MEDFileFieldGlobsReal *glob, const std::vector >& dads, const std::vector& locs, const std::vector& geoTypes, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception) + const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const { - if(da->isIdentity()) - { - int nbOfTuples=da->getNumberOfTuples(); - if(nbOfTuples==mesh->getNumberOfCells()) - return finishField(type,glob,dads,locs,mesh,isPfl); - } + if(da->isIdentity2(mesh->getNumberOfCells())) + return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); MEDCouplingAutoRefCountObjectPtr m2=mesh->buildPart(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - m2->setName(mesh->getName()); - MEDCouplingAutoRefCountObjectPtr ret=finishField(type,glob,dads,locs,m2,isPfl); + m2->setName(mesh->getName().c_str()); + MEDCouplingAutoRefCountObjectPtr ret=finishField(type,glob,dads,locs,m2,isPfl,arrOut,nasc); isPfl=true; return ret.retn(); } @@ -2186,21 +2399,17 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField2(TypeOfField type, cons */ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileFieldGlobsReal *glob, const std::vector >& dads, const std::vector& locs, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl) const throw(INTERP_KERNEL::Exception) + const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const { - if(da->isIdentity()) - { - int nbOfTuples=da->getNumberOfTuples(); - if(nbOfTuples==mesh->getNumberOfNodes())//No problem for NORM_ERROR because it is in context of node - return finishField(ON_NODES,glob,dads,locs,mesh,isPfl); - } + if(da->isIdentity2(mesh->getNumberOfNodes())) + return finishField(ON_NODES,glob,dads,locs,mesh,isPfl,arrOut,nasc); // Treatment of particular case where nodal field on pfl is requested with a meshDimRelToMax=1. const MEDCouplingUMesh *meshu=dynamic_cast(mesh); if(meshu) { if(meshu->getNodalConnectivity()==0) { - MEDCouplingAutoRefCountObjectPtr ret=finishField(ON_CELLS,glob,dads,locs,mesh,isPfl); + MEDCouplingAutoRefCountObjectPtr ret=finishField(ON_CELLS,glob,dads,locs,mesh,isPfl,arrOut,nasc); int nb=da->getNbOfElems(); const int *ptr=da->getConstPointer(); MEDCouplingUMesh *meshuc=const_cast(meshu); @@ -2209,12 +2418,14 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileField meshuc->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,ptr+i); meshuc->finishInsertingCells(); ret->setMesh(meshuc); - ret->checkCoherency(); + const MEDCouplingFieldDiscretization *disc=ret->getDiscretization(); + if(!disc) throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::finishFieldNode2 : internal error, no discretization on field !"); + disc->checkCoherencyBetween(meshuc,arrOut); return ret.retn(); } } // - MEDCouplingAutoRefCountObjectPtr ret=finishField(ON_NODES,glob,dads,locs,mesh,isPfl); + MEDCouplingAutoRefCountObjectPtr ret=finishField(ON_NODES,glob,dads,locs,mesh,isPfl,arrOut,nasc); isPfl=true; DataArrayInt *arr2=0; MEDCouplingAutoRefCountObjectPtr cellIds=mesh->getCellIdsFullyIncludedInNodeIds(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); @@ -2224,8 +2435,8 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileField if(nnodes==(int)da->getNbOfElems()) { MEDCouplingAutoRefCountObjectPtr da3=da->transformWithIndArrR(arr2->begin(),arr2->end()); - ret->getArray()->renumberInPlace(da3->getConstPointer()); - mesh2->setName(mesh->getName()); + arrOut->renumberInPlace(da3->getConstPointer()); + mesh2->setName(mesh->getName().c_str()); ret->setMesh(mesh2); return ret.retn(); } @@ -2245,7 +2456,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileField /*! * This method is the most light method of field retrieving. */ -DataArrayDouble *MEDFileFieldPerMesh::finishField4(const std::vector >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const throw(INTERP_KERNEL::Exception) +DataArray *MEDFileFieldPerMesh::finishField4(const std::vector >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const { if(!pflIn) { @@ -2259,7 +2470,7 @@ DataArrayDouble *MEDFileFieldPerMesh::finishField4(const std::vectorincrRef(); } MEDCouplingAutoRefCountObjectPtr safePfl(pflOut); - MEDCouplingAutoRefCountObjectPtr da=getArray()->selectByTupleRanges(dads); + MEDCouplingAutoRefCountObjectPtr da=getOrCreateAndGetArray()->selectByTupleRanges(dads); const std::vector& infos=getInfo(); int nbOfComp=infos.size(); for(int i=0;i meshName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr locName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - for(int i=0;i > *entities); + static bool IsPresenceOfNode(const std::vector< std::pair > *entities); + virtual ~MFFPMIter() { } + virtual void begin() = 0; + virtual bool finished() const = 0; + virtual void next() = 0; + virtual int current() const = 0; +}; + +class MFFPMIterSimple : public MFFPMIter +{ +public: + MFFPMIterSimple():_pos(0) { } + void begin() { _pos=0; } + bool finished() const { return _pos>=MED_N_CELL_FIXED_GEO; } + void next() { _pos++; } + int current() const { return _pos; } +private: + int _pos; +}; + +class MFFPMIter2 : public MFFPMIter +{ +public: + MFFPMIter2(const std::vector& cts); + void begin() { _it=_ids.begin(); } + bool finished() const { return _it==_ids.end(); } + void next() { _it++; } + int current() const { return *_it; } +private: + std::vector _ids; + std::vector::const_iterator _it; +}; + +MFFPMIter *MFFPMIter::NewCell(const std::vector< std::pair > *entities) +{ + if(!entities) + return new MFFPMIterSimple; + else { - int nbProfile=MEDfield23nProfile(fid,getName().c_str(),getIteration(),getOrder(),MED_CELL,typmai[i],_mesh_csit,meshName,pflName,locName); - if(nbProfile>0) + std::vector tmp; + for(std::vector< std::pair >::const_iterator it=(*entities).begin();it!=(*entities).end();it++) { - _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_CELLS,typmai2[i])); - _mesh_name=MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1); + if((*it).first==ON_CELLS || (*it).first==ON_GAUSS_NE || (*it).first==ON_GAUSS_PT) + tmp.push_back((*it).second); } - nbProfile=MEDfield23nProfile(fid,getName().c_str(),getIteration(),getOrder(),MED_NODE_ELEMENT,typmai[i],_mesh_csit,meshName,pflName,locName); - if(nbProfile>0) + return new MFFPMIter2(tmp); + } +} + +bool MFFPMIter::IsPresenceOfNode(const std::vector< std::pair > *entities) +{ + if(!entities) + return true; + else + { + for(std::vector< std::pair >::const_iterator it=(*entities).begin();it!=(*entities).end();it++) + if((*it).first==ON_NODES) + return true; + return false; + } +} + +MFFPMIter2::MFFPMIter2(const std::vector& cts) +{ + std::size_t sz(cts.size()); + _ids.resize(sz); + for(std::size_t i=0;i > *entities):_mesh_iteration(meshIteration),_mesh_order(meshOrder), + _father(fath) +{ + INTERP_KERNEL::AutoPtr meshName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + INTERP_KERNEL::AutoPtr pflName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + INTERP_KERNEL::AutoPtr locName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + const MEDFileUMesh *mmu(dynamic_cast(mm)); + INTERP_KERNEL::AutoCppPtr iter0(MFFPMIter::NewCell(entities)); + for(iter0->begin();!iter0->finished();iter0->next()) + { + int nbProfile (MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_CELL ,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName)); + std::string name0(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); + int nbProfile2(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE_ELEMENT,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName)); + std::string name1(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); + if(nbProfile>0 || nbProfile2>0) { - _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_GAUSS_NE,typmai2[i])); - _mesh_name=MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1); + const PartDefinition *pd(0); + if(mmu) + pd=mmu->getPartDefAtLevel(mmu->getRelativeLevOnGeoType(typmai2[iter0->current()]),typmai2[iter0->current()]); + _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_CELLS,typmai2[iter0->current()],nasc,pd)); + if(nbProfile>0) + _mesh_name=name0; + else + _mesh_name=name1; } } - int nbProfile=MEDfield23nProfile(fid,getName().c_str(),getIteration(),getOrder(),MED_NODE,MED_NONE,_mesh_csit,meshName,pflName,locName); - if(nbProfile>0) + if(MFFPMIter::IsPresenceOfNode(entities)) { - _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_NODES,INTERP_KERNEL::NORM_ERROR)); - _mesh_name=MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1); + int nbProfile(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE,MED_NONE,meshCsit+1,meshName,pflName,locName)); + if(nbProfile>0) + { + const PartDefinition *pd(0); + if(mmu) + pd=mmu->getPartDefAtLevel(1,INTERP_KERNEL::NORM_ERROR); + _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_NODES,INTERP_KERNEL::NORM_ERROR,nasc,pd)); + _mesh_name=MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1); + } } } -MEDFileFieldPerMesh::MEDFileFieldPerMesh(MEDFileField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh):_father(fath) +MEDFileFieldPerMesh::MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh):_father(fath) { copyTinyInfoFrom(mesh); } -void MEDFileFieldGlobs::loadProfileInFile(med_idt fid, int id, const char *pflName) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::loadProfileInFile(med_idt fid, int id, const std::string& pflName) { if(id>=(int)_pfls.size()) _pfls.resize(id+1); _pfls[id]=DataArrayInt::New(); - int lgth=MEDprofileSizeByName(fid,pflName); + int lgth(MEDprofileSizeByName(fid,pflName.c_str())); _pfls[id]->setName(pflName); _pfls[id]->alloc(lgth,1); - MEDprofileRd(fid,pflName,_pfls[id]->getPointer()); + MEDFILESAFECALLERRD0(MEDprofileRd,(fid,pflName.c_str(),_pfls[id]->getPointer())); _pfls[id]->applyLin(1,-1,0);//Converting into C format } @@ -2318,18 +2625,18 @@ void MEDFileFieldGlobs::loadProfileInFile(med_idt fid, int i) { INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); int sz; - MEDprofileInfo(fid,i+1,pflName,&sz); + MEDFILESAFECALLERRD0(MEDprofileInfo,(fid,i+1,pflName,&sz)); std::string pflCpp=MEDLoaderBase::buildStringFromFortran(pflName,MED_NAME_SIZE); if(i>=(int)_pfls.size()) _pfls.resize(i+1); _pfls[i]=DataArrayInt::New(); _pfls[i]->alloc(sz,1); _pfls[i]->setName(pflCpp.c_str()); - MEDprofileRd(fid,pflName,_pfls[i]->getPointer()); + MEDFILESAFECALLERRD0(MEDprofileRd,(fid,pflName,_pfls[i]->getPointer())); _pfls[i]->applyLin(1,-1,0);//Converting into C format } -void MEDFileFieldGlobs::writeGlobals(med_idt fid, const MEDFileWritable& opt) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::writeGlobals(med_idt fid, const MEDFileWritable& opt) const { int nbOfPfls=_pfls.size(); for(int i=0;iapplyLin(1,1,0); INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); MEDLoaderBase::safeStrCpy(_pfls[i]->getName().c_str(),MED_NAME_SIZE,pflName,opt.getTooLongStrPolicy()); - MEDprofileWr(fid,pflName,_pfls[i]->getNumberOfTuples(),cpy->getConstPointer()); + MEDFILESAFECALLERWR0(MEDprofileWr,(fid,pflName,_pfls[i]->getNumberOfTuples(),cpy->getConstPointer())); } // int nbOfLocs=_locs.size(); @@ -2346,7 +2653,7 @@ void MEDFileFieldGlobs::writeGlobals(med_idt fid, const MEDFileWritable& opt) co _locs[i]->writeLL(fid); } -void MEDFileFieldGlobs::appendGlobs(const MEDFileFieldGlobs& other, double eps) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::appendGlobs(const MEDFileFieldGlobs& other, double eps) { std::vector pfls=getPfls(); for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=other._pfls.begin();it!=other._pfls.end();it++) @@ -2367,7 +2674,7 @@ void MEDFileFieldGlobs::appendGlobs(const MEDFileFieldGlobs& other, double eps) } } std::vector locs=getLocs(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=other._locs.begin();it!=other._locs.end();it++) { std::vector::iterator it2=std::find(locs.begin(),locs.end(),(*it)->getName()); if(it2==locs.end()) @@ -2386,7 +2693,19 @@ void MEDFileFieldGlobs::appendGlobs(const MEDFileFieldGlobs& other, double eps) } } -void MEDFileFieldGlobs::loadGlobals(med_idt fid, const MEDFileFieldGlobsReal& real) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::checkGlobsPflsPartCoherency(const std::vector& pflsUsed) const +{ + for(std::vector::const_iterator it=pflsUsed.begin();it!=pflsUsed.end();it++) + getProfile((*it).c_str()); +} + +void MEDFileFieldGlobs::checkGlobsLocsPartCoherency(const std::vector& locsUsed) const +{ + for(std::vector::const_iterator it=locsUsed.begin();it!=locsUsed.end();it++) + getLocalization((*it).c_str()); +} + +void MEDFileFieldGlobs::loadGlobals(med_idt fid, const MEDFileFieldGlobsReal& real) { std::vector profiles=real.getPflsReallyUsed(); int sz=profiles.size(); @@ -2401,7 +2720,7 @@ void MEDFileFieldGlobs::loadGlobals(med_idt fid, const MEDFileFieldGlobsReal& re _locs[i]=MEDFileFieldLoc::New(fid,locs[i].c_str()); } -void MEDFileFieldGlobs::loadAllGlobals(med_idt fid) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::loadAllGlobals(med_idt fid) { int nProfil=MEDnProfile(fid); for(int i=0;i)+_locs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++) - ret+=(*it)->getHeapMemorySize(); + return _file_name.capacity()+_pfls.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr)+_locs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); +} + +std::vector MEDFileFieldGlobs::getDirectChildrenWithNull() const +{ + std::vector ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< DataArrayInt > >::const_iterator it=_pfls.begin();it!=_pfls.end();it++) + ret.push_back((const DataArrayInt *)*it); for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++) - ret+=(*it)->getHeapMemorySize(); + ret.push_back((const MEDFileFieldLoc *)*it); return ret; } -MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpy() const throw(INTERP_KERNEL::Exception) +MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpy() const { MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldGlobs(*this); std::size_t i=0; @@ -2452,7 +2776,63 @@ MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpy() const throw(INTERP_KERNEL::Excep return ret.retn(); } -MEDFileFieldGlobs::MEDFileFieldGlobs(const char *fname):_file_name(fname) +/*! + * \throw if a profile in \a pfls in not in \a this. + * \throw if a localization in \a locs in not in \a this. + * \sa MEDFileFieldGlobs::deepCpyPart + */ +MEDFileFieldGlobs *MEDFileFieldGlobs::shallowCpyPart(const std::vector& pfls, const std::vector& locs) const +{ + MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldGlobs::New(); + for(std::vector::const_iterator it1=pfls.begin();it1!=pfls.end();it1++) + { + DataArrayInt *pfl=const_cast(getProfile((*it1).c_str())); + if(!pfl) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::shallowCpyPart : internal error ! pfl null !"); + pfl->incrRef(); + MEDCouplingAutoRefCountObjectPtr pfl2(pfl); + ret->_pfls.push_back(pfl2); + } + for(std::vector::const_iterator it2=locs.begin();it2!=locs.end();it2++) + { + MEDFileFieldLoc *loc=const_cast(&getLocalization((*it2).c_str())); + if(!loc) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::shallowCpyPart : internal error ! loc null !"); + loc->incrRef(); + MEDCouplingAutoRefCountObjectPtr loc2(loc); + ret->_locs.push_back(loc2); + } + ret->setFileName(getFileName()); + return ret.retn(); +} + +/*! + * \throw if a profile in \a pfls in not in \a this. + * \throw if a localization in \a locs in not in \a this. + * \sa MEDFileFieldGlobs::shallowCpyPart + */ +MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpyPart(const std::vector& pfls, const std::vector& locs) const +{ + MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldGlobs::New(); + for(std::vector::const_iterator it1=pfls.begin();it1!=pfls.end();it1++) + { + DataArrayInt *pfl=const_cast(getProfile((*it1).c_str())); + if(!pfl) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::deepCpyPart : internal error ! pfl null !"); + ret->_pfls.push_back(pfl->deepCpy()); + } + for(std::vector::const_iterator it2=locs.begin();it2!=locs.end();it2++) + { + MEDFileFieldLoc *loc=const_cast(&getLocalization((*it2).c_str())); + if(!loc) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::deepCpyPart : internal error ! loc null !"); + ret->_locs.push_back(loc->deepCpy()); + } + ret->setFileName(getFileName()); + return ret.retn(); +} + +MEDFileFieldGlobs::MEDFileFieldGlobs(const std::string& fname):_file_name(fname) { } @@ -2490,12 +2870,12 @@ void MEDFileFieldGlobs::simpleRepr(std::ostream& oss) const } } -void MEDFileFieldGlobs::setFileName(const char *fileName) +void MEDFileFieldGlobs::setFileName(const std::string& fileName) { _file_name=fileName; } -void MEDFileFieldGlobs::changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) { for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_pfls.begin();it!=_pfls.end();it++) { @@ -2515,7 +2895,7 @@ void MEDFileFieldGlobs::changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) { for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_locs.begin();it!=_locs.end();it++) { @@ -2535,34 +2915,35 @@ void MEDFileFieldGlobs::changeLocsNamesInStruct(const std::vector< std::pair=(int)_locs.size()) throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getNbOfGaussPtPerCell : Invalid localization id !"); return _locs[locId]->getNbOfGaussPtPerCell(); } -const MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const char *locName) const throw(INTERP_KERNEL::Exception) +const MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const std::string& locName) const { return getLocalizationFromId(getLocalizationId(locName)); } -const MEDFileFieldLoc& MEDFileFieldGlobs::getLocalizationFromId(int locId) const throw(INTERP_KERNEL::Exception) +const MEDFileFieldLoc& MEDFileFieldGlobs::getLocalizationFromId(int locId) const { if(locId<0 || locId>=(int)_locs.size()) throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getLocalizationFromId : Invalid localization id !"); return *_locs[locId]; } -namespace ParaMEDMEMImpl +/// @cond INTERNAL +namespace MEDCouplingImpl { class LocFinder { public: - LocFinder(const char *loc):_loc(loc) { } + LocFinder(const std::string& loc):_loc(loc) { } bool operator() (const MEDCouplingAutoRefCountObjectPtr& loc) { return loc->isName(_loc); } private: - const char *_loc; + const std::string &_loc; }; class PflFinder @@ -2574,10 +2955,11 @@ namespace ParaMEDMEMImpl const std::string& _pfl; }; } +/// @endcond -int MEDFileFieldGlobs::getLocalizationId(const char *loc) const throw(INTERP_KERNEL::Exception) +int MEDFileFieldGlobs::getLocalizationId(const std::string& loc) const { - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=std::find_if(_locs.begin(),_locs.end(),ParaMEDMEMImpl::LocFinder(loc)); + std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=std::find_if(_locs.begin(),_locs.end(),MEDCouplingImpl::LocFinder(loc)); if(it==_locs.end()) { std::ostringstream oss; oss << "MEDFileFieldGlobs::getLocalisationId : no such localisation name : \"" << loc << "\" Possible localizations are : "; @@ -2588,10 +2970,13 @@ int MEDFileFieldGlobs::getLocalizationId(const char *loc) const throw(INTERP_KER return std::distance(_locs.begin(),it); } -const DataArrayInt *MEDFileFieldGlobs::getProfile(const char *pflName) const throw(INTERP_KERNEL::Exception) +/*! + * The returned value is never null. + */ +const DataArrayInt *MEDFileFieldGlobs::getProfile(const std::string& pflName) const { std::string pflNameCpp(pflName); - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=std::find_if(_pfls.begin(),_pfls.end(),ParaMEDMEMImpl::PflFinder(pflNameCpp)); + std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=std::find_if(_pfls.begin(),_pfls.end(),MEDCouplingImpl::PflFinder(pflNameCpp)); if(it==_pfls.end()) { std::ostringstream oss; oss << "MEDFileFieldGlobs::getProfile: no such profile name : \"" << pflNameCpp << "\" Possible profiles are : "; @@ -2602,29 +2987,32 @@ const DataArrayInt *MEDFileFieldGlobs::getProfile(const char *pflName) const thr return *it; } -const DataArrayInt *MEDFileFieldGlobs::getProfileFromId(int pflId) const throw(INTERP_KERNEL::Exception) +const DataArrayInt *MEDFileFieldGlobs::getProfileFromId(int pflId) const { if(pflId<0 || pflId>=(int)_pfls.size()) throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getProfileFromId : Invalid profile id !"); return _pfls[pflId]; } -MEDFileFieldLoc& MEDFileFieldGlobs::getLocalizationFromId(int locId) throw(INTERP_KERNEL::Exception) +MEDFileFieldLoc& MEDFileFieldGlobs::getLocalizationFromId(int locId) { if(locId<0 || locId>=(int)_locs.size()) throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getLocalizationFromId : Invalid localization id !"); return *_locs[locId]; } -MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const char *locName) throw(INTERP_KERNEL::Exception) +MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const std::string& locName) { return getLocalizationFromId(getLocalizationId(locName)); } -DataArrayInt *MEDFileFieldGlobs::getProfile(const char *pflName) throw(INTERP_KERNEL::Exception) +/*! + * The returned value is never null. + */ +DataArrayInt *MEDFileFieldGlobs::getProfile(const std::string& pflName) { std::string pflNameCpp(pflName); - std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=std::find_if(_pfls.begin(),_pfls.end(),ParaMEDMEMImpl::PflFinder(pflNameCpp)); + std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=std::find_if(_pfls.begin(),_pfls.end(),MEDCouplingImpl::PflFinder(pflNameCpp)); if(it==_pfls.end()) { std::ostringstream oss; oss << "MEDFileFieldGlobs::getProfile: no such profile name : \"" << pflNameCpp << "\" Possible profiles are : "; @@ -2635,14 +3023,14 @@ DataArrayInt *MEDFileFieldGlobs::getProfile(const char *pflName) throw(INTERP_KE return *it; } -DataArrayInt *MEDFileFieldGlobs::getProfileFromId(int pflId) throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDFileFieldGlobs::getProfileFromId(int pflId) { if(pflId<0 || pflId>=(int)_pfls.size()) throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getProfileFromId : Invalid profile id !"); return _pfls[pflId]; } -void MEDFileFieldGlobs::killProfileIds(const std::vector& pflIds) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::killProfileIds(const std::vector& pflIds) { std::vector< MEDCouplingAutoRefCountObjectPtr > newPfls; int i=0; @@ -2654,7 +3042,7 @@ void MEDFileFieldGlobs::killProfileIds(const std::vector& pflIds) throw(INT _pfls=newPfls; } -void MEDFileFieldGlobs::killLocalizationIds(const std::vector& locIds) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::killLocalizationIds(const std::vector& locIds) { std::vector< MEDCouplingAutoRefCountObjectPtr > newLocs; int i=0; @@ -2684,14 +3072,14 @@ std::vector MEDFileFieldGlobs::getLocs() const return ret; } -bool MEDFileFieldGlobs::existsPfl(const char *pflName) const +bool MEDFileFieldGlobs::existsPfl(const std::string& pflName) const { std::vector v=getPfls(); std::string s(pflName); return std::find(v.begin(),v.end(),s)!=v.end(); } -bool MEDFileFieldGlobs::existsLoc(const char *locName) const +bool MEDFileFieldGlobs::existsLoc(const std::string& locName) const { std::vector v=getLocs(); std::string s(locName); @@ -2743,7 +3131,7 @@ std::vector< std::vector > MEDFileFieldGlobs::whichAreEqualLocs(double eps) throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::whichAreEqualLocs : no implemented yet ! Sorry !"); } -void MEDFileFieldGlobs::appendProfile(DataArrayInt *pfl) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::appendProfile(DataArrayInt *pfl) { std::string name(pfl->getName()); if(name.empty()) @@ -2761,7 +3149,7 @@ void MEDFileFieldGlobs::appendProfile(DataArrayInt *pfl) throw(INTERP_KERNEL::Ex _pfls.push_back(pfl); } -void MEDFileFieldGlobs::appendLoc(const char *locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobs::appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) { std::string name(locName); if(name.empty()) @@ -2779,19 +3167,19 @@ void MEDFileFieldGlobs::appendLoc(const char *locName, INTERP_KERNEL::Normalized _locs.push_back(obj); } -std::string MEDFileFieldGlobs::createNewNameOfPfl() const throw(INTERP_KERNEL::Exception) +std::string MEDFileFieldGlobs::createNewNameOfPfl() const { std::vector names=getPfls(); return CreateNewNameNotIn("NewPfl_",names); } -std::string MEDFileFieldGlobs::createNewNameOfLoc() const throw(INTERP_KERNEL::Exception) +std::string MEDFileFieldGlobs::createNewNameOfLoc() const { std::vector names=getLocs(); return CreateNewNameNotIn("NewLoc_",names); } -std::string MEDFileFieldGlobs::CreateNewNameNotIn(const char *prefix, const std::vector& namesToAvoid) throw(INTERP_KERNEL::Exception) +std::string MEDFileFieldGlobs::CreateNewNameNotIn(const std::string& prefix, const std::vector& namesToAvoid) { for(std::size_t sz=0;sz<100000;sz++) { @@ -2807,7 +3195,7 @@ std::string MEDFileFieldGlobs::CreateNewNameNotIn(const char *prefix, const std: * Creates a MEDFileFieldGlobsReal on a given file name. Nothing is read here. * \param [in] fname - the file name. */ -MEDFileFieldGlobsReal::MEDFileFieldGlobsReal(const char *fname):_globals(MEDFileFieldGlobs::New(fname)) +MEDFileFieldGlobsReal::MEDFileFieldGlobsReal(const std::string& fname):_globals(MEDFileFieldGlobs::New(fname)) { } @@ -2818,11 +3206,15 @@ MEDFileFieldGlobsReal::MEDFileFieldGlobsReal():_globals(MEDFileFieldGlobs::New() { } -std::size_t MEDFileFieldGlobsReal::getHeapMemorySize() const +std::size_t MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren() const { - std::size_t ret=0; - if((const MEDFileFieldGlobs *)_globals) - ret+=_globals->getHeapMemorySize(); + return 0; +} + +std::vector MEDFileFieldGlobsReal::getDirectChildrenWithNull() const +{ + std::vector ret; + ret.push_back((const MEDFileFieldGlobs *)_globals); return ret; } @@ -2830,17 +3222,24 @@ std::size_t MEDFileFieldGlobsReal::getHeapMemorySize() const * Returns a string describing profiles and Gauss points held in \a this. * \return std::string - the description string. */ -void MEDFileFieldGlobsReal::simpleRepr(std::ostream& oss) const +void MEDFileFieldGlobsReal::simpleReprGlobs(std::ostream& oss) const { - oss << "Globals information on fields :" << "\n*******************************\n\n"; const MEDFileFieldGlobs *glob=_globals; + std::ostringstream oss2; oss2 << glob; + std::string stars(oss2.str().length(),'*'); + oss << "Globals information on fields (at " << oss2.str() << "):" << "\n************************************" << stars << "\n\n"; if(glob) glob->simpleRepr(oss); else oss << "NO GLOBAL INFORMATION !\n"; } -MEDFileFieldGlobsReal::~MEDFileFieldGlobsReal() +void MEDFileFieldGlobsReal::resetContent() +{ + _globals=MEDFileFieldGlobs::New(); +} + +MEDFileFieldGlobsReal::~MEDFileFieldGlobsReal() { } @@ -2853,6 +3252,30 @@ void MEDFileFieldGlobsReal::shallowCpyGlobs(const MEDFileFieldGlobsReal& other) _globals=other._globals; } +/*! + * Copies references to ** only used ** by \a this, profiles and Gauss points from another MEDFileFieldGlobsReal. + * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. + */ +void MEDFileFieldGlobsReal::shallowCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) +{ + const MEDFileFieldGlobs *otherg(other._globals); + if(!otherg) + return ; + _globals=otherg->shallowCpyPart(getPflsReallyUsed(),getLocsReallyUsed()); +} + +/*! + * Copies deeply to ** only used ** by \a this, profiles and Gauss points from another MEDFileFieldGlobsReal. + * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. + */ +void MEDFileFieldGlobsReal::deepCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) +{ + const MEDFileFieldGlobs *otherg(other._globals); + if(!otherg) + return ; + _globals=otherg->deepCpyPart(getPflsReallyUsed(),getLocsReallyUsed()); +} + void MEDFileFieldGlobsReal::deepCpyGlobs(const MEDFileFieldGlobsReal& other) { _globals=other._globals; @@ -2868,34 +3291,58 @@ void MEDFileFieldGlobsReal::deepCpyGlobs(const MEDFileFieldGlobsReal& other) * \throw If \a this and \a other hold profiles with equal names but different ids. * \throw If \a this and \a other hold different Gauss points with equal names. */ -void MEDFileFieldGlobsReal::appendGlobs(const MEDFileFieldGlobsReal& other, double eps) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::appendGlobs(const MEDFileFieldGlobsReal& other, double eps) { + const MEDFileFieldGlobs *thisGlobals(_globals),*otherGlobals(other._globals); + if(thisGlobals==otherGlobals) + return ; + if(!thisGlobals) + { + _globals=other._globals; + return ; + } _globals->appendGlobs(*other._globals,eps); } -void MEDFileFieldGlobsReal::loadProfileInFile(med_idt fid, int id, const char *pflName) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::checkGlobsCoherency() const +{ + checkGlobsPflsPartCoherency(); + checkGlobsLocsPartCoherency(); +} + +void MEDFileFieldGlobsReal::checkGlobsPflsPartCoherency() const { - _globals->loadProfileInFile(fid,id,pflName); + contentNotNull()->checkGlobsPflsPartCoherency(getPflsReallyUsed()); +} + +void MEDFileFieldGlobsReal::checkGlobsLocsPartCoherency() const +{ + contentNotNull()->checkGlobsLocsPartCoherency(getLocsReallyUsed()); +} + +void MEDFileFieldGlobsReal::loadProfileInFile(med_idt fid, int id, const std::string& pflName) +{ + contentNotNull()->loadProfileInFile(fid,id,pflName); } void MEDFileFieldGlobsReal::loadProfileInFile(med_idt fid, int id) { - _globals->loadProfileInFile(fid,id); + contentNotNull()->loadProfileInFile(fid,id); } -void MEDFileFieldGlobsReal::loadGlobals(med_idt fid) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::loadGlobals(med_idt fid) { - _globals->loadGlobals(fid,*this); + contentNotNull()->loadGlobals(fid,*this); } -void MEDFileFieldGlobsReal::loadAllGlobals(med_idt fid) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::loadAllGlobals(med_idt fid) { - _globals->loadAllGlobals(fid); + contentNotNull()->loadAllGlobals(fid); } -void MEDFileFieldGlobsReal::writeGlobals(med_idt fid, const MEDFileWritable& opt) const throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::writeGlobals(med_idt fid, const MEDFileWritable& opt) const { - _globals->writeGlobals(fid,opt); + contentNotNull()->writeGlobals(fid,opt); } /*! @@ -2905,7 +3352,7 @@ void MEDFileFieldGlobsReal::writeGlobals(med_idt fid, const MEDFileWritable& opt */ std::vector MEDFileFieldGlobsReal::getPfls() const { - return _globals->getPfls(); + return contentNotNull()->getPfls(); } /*! @@ -2915,7 +3362,7 @@ std::vector MEDFileFieldGlobsReal::getPfls() const */ std::vector MEDFileFieldGlobsReal::getLocs() const { - return _globals->getLocs(); + return contentNotNull()->getLocs(); } /*! @@ -2923,9 +3370,9 @@ std::vector MEDFileFieldGlobsReal::getLocs() const * \param [in] pflName - the profile name of interest. * \return bool - \c true if the profile named \a pflName exists. */ -bool MEDFileFieldGlobsReal::existsPfl(const char *pflName) const +bool MEDFileFieldGlobsReal::existsPfl(const std::string& pflName) const { - return _globals->existsPfl(pflName); + return contentNotNull()->existsPfl(pflName); } /*! @@ -2933,28 +3380,28 @@ bool MEDFileFieldGlobsReal::existsPfl(const char *pflName) const * \param [in] locName - the localization name of interest. * \return bool - \c true if the localization named \a locName exists. */ -bool MEDFileFieldGlobsReal::existsLoc(const char *locName) const +bool MEDFileFieldGlobsReal::existsLoc(const std::string& locName) const { - return _globals->existsLoc(locName); + return contentNotNull()->existsLoc(locName); } -std::string MEDFileFieldGlobsReal::createNewNameOfPfl() const throw(INTERP_KERNEL::Exception) +std::string MEDFileFieldGlobsReal::createNewNameOfPfl() const { - return _globals->createNewNameOfPfl(); + return contentNotNull()->createNewNameOfPfl(); } -std::string MEDFileFieldGlobsReal::createNewNameOfLoc() const throw(INTERP_KERNEL::Exception) +std::string MEDFileFieldGlobsReal::createNewNameOfLoc() const { - return _globals->createNewNameOfLoc(); + return contentNotNull()->createNewNameOfLoc(); } /*! * Sets the name of a MED file. * \param [inout] fileName - the file name. */ -void MEDFileFieldGlobsReal::setFileName(const char *fileName) +void MEDFileFieldGlobsReal::setFileName(const std::string& fileName) { - _globals->setFileName(fileName); + contentNotNull()->setFileName(fileName); } /*! @@ -2965,7 +3412,7 @@ void MEDFileFieldGlobsReal::setFileName(const char *fileName) */ std::vector< std::vector > MEDFileFieldGlobsReal::whichAreEqualProfiles() const { - return _globals->whichAreEqualProfiles(); + return contentNotNull()->whichAreEqualProfiles(); } /*! @@ -2976,7 +3423,7 @@ std::vector< std::vector > MEDFileFieldGlobsReal::whichAreEqualProfiles() c */ std::vector< std::vector > MEDFileFieldGlobsReal::whichAreEqualLocs(double eps) const { - return _globals->whichAreEqualLocs(eps); + return contentNotNull()->whichAreEqualLocs(eps); } /*! @@ -2986,9 +3433,9 @@ std::vector< std::vector > MEDFileFieldGlobsReal::whichAreEqualLocs(double * - the first item is a vector of profile names to replace by the second item, * - the second item is a profile name to replace every profile name of the first item. */ -void MEDFileFieldGlobsReal::changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) { - _globals->changePflsNamesInStruct(mapOfModif); + contentNotNull()->changePflsNamesInStruct(mapOfModif); } /*! @@ -2998,9 +3445,9 @@ void MEDFileFieldGlobsReal::changePflsNamesInStruct(const std::vector< std::pair * - the first item is a vector of localization names to replace by the second item, * - the second item is a localization name to replace every localization name of the first item. */ -void MEDFileFieldGlobsReal::changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) { - _globals->changeLocsNamesInStruct(mapOfModif); + contentNotNull()->changeLocsNamesInStruct(mapOfModif); } /*! @@ -3015,7 +3462,7 @@ void MEDFileFieldGlobsReal::changeLocsNamesInStruct(const std::vector< std::pair * \sa changePflsRefsNamesGen() * \sa changePflName() */ -void MEDFileFieldGlobsReal::changePflsNames(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::changePflsNames(const std::vector< std::pair, std::string > >& mapOfModif) { changePflsRefsNamesGen(mapOfModif); changePflsNamesInStruct(mapOfModif); @@ -3033,7 +3480,7 @@ void MEDFileFieldGlobsReal::changePflsNames(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::changeLocsNames(const std::vector< std::pair, std::string > >& mapOfModif) { changeLocsRefsNamesGen(mapOfModif); changeLocsNamesInStruct(mapOfModif); @@ -3045,7 +3492,7 @@ void MEDFileFieldGlobsReal::changeLocsNames(const std::vector< std::pair, std::string > > mapOfModif(1); std::pair, std::string > p(std::vector(1,std::string(oldName)),std::string(newName)); @@ -3059,7 +3506,7 @@ void MEDFileFieldGlobsReal::changePflName(const char *oldName, const char *newNa * \param [in] newName - a new name of the localization. * \sa changeLocsNames(). */ -void MEDFileFieldGlobsReal::changeLocName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::changeLocName(const std::string& oldName, const std::string& newName) { std::vector< std::pair, std::string > > mapOfModif(1); std::pair, std::string > p(std::vector(1,std::string(oldName)),std::string(newName)); @@ -3077,7 +3524,7 @@ void MEDFileFieldGlobsReal::changeLocName(const char *oldName, const char *newNa * - the first item is a vector of profile names replaced by the second item, * - the second item is a profile name replacing every profile of the first item. */ -std::vector< std::pair, std::string > > MEDFileFieldGlobsReal::zipPflsNames() throw(INTERP_KERNEL::Exception) +std::vector< std::pair, std::string > > MEDFileFieldGlobsReal::zipPflsNames() { std::vector< std::vector > pseudoRet=whichAreEqualProfiles(); std::vector< std::pair, std::string > > ret(pseudoRet.size()); @@ -3108,7 +3555,7 @@ std::vector< std::pair, std::string > > MEDFileFieldGlo * - the first item is a vector of localization names replaced by the second item, * - the second item is a localization name replacing every localization of the first item. */ -std::vector< std::pair, std::string > > MEDFileFieldGlobsReal::zipLocsNames(double eps) throw(INTERP_KERNEL::Exception) +std::vector< std::pair, std::string > > MEDFileFieldGlobsReal::zipLocsNames(double eps) { std::vector< std::vector > pseudoRet=whichAreEqualLocs(eps); std::vector< std::pair, std::string > > ret(pseudoRet.size()); @@ -3133,9 +3580,9 @@ std::vector< std::pair, std::string > > MEDFileFieldGlo * \param [in] locId - an id of the localization of interest. * \return int - the number of the Gauss points per cell. */ -int MEDFileFieldGlobsReal::getNbOfGaussPtPerCell(int locId) const throw(INTERP_KERNEL::Exception) +int MEDFileFieldGlobsReal::getNbOfGaussPtPerCell(int locId) const { - return _globals->getNbOfGaussPtPerCell(locId); + return contentNotNull()->getNbOfGaussPtPerCell(locId); } /*! @@ -3144,23 +3591,18 @@ int MEDFileFieldGlobsReal::getNbOfGaussPtPerCell(int locId) const throw(INTERP_K * \return int - the id of the localization. * \throw If there is no a localization named \a loc. */ -int MEDFileFieldGlobsReal::getLocalizationId(const char *loc) const throw(INTERP_KERNEL::Exception) +int MEDFileFieldGlobsReal::getLocalizationId(const std::string& loc) const { - return _globals->getLocalizationId(loc); + return contentNotNull()->getLocalizationId(loc); } /*! * Returns the name of the MED file. - * \return const char * - the MED file name. + * \return const std::string& - the MED file name. */ -const char *MEDFileFieldGlobsReal::getFileName() const -{ - return _globals->getFileName(); -} - -std::string MEDFileFieldGlobsReal::getFileName2() const +std::string MEDFileFieldGlobsReal::getFileName() const { - return _globals->getFileName2(); + return contentNotNull()->getFileName(); } /*! @@ -3169,9 +3611,9 @@ std::string MEDFileFieldGlobsReal::getFileName2() const * \return const MEDFileFieldLoc& - the localization object having the name \a locName. * \throw If there is no a localization named \a locName. */ -const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const char *locName) const throw(INTERP_KERNEL::Exception) +const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const std::string& locName) const { - return _globals->getLocalization(locName); + return contentNotNull()->getLocalization(locName); } /*! @@ -3180,9 +3622,9 @@ const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const char *locNam * \return const MEDFileFieldLoc& - the localization object having the id \a locId. * \throw If there is no a localization with id \a locId. */ -const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) const throw(INTERP_KERNEL::Exception) +const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) const { - return _globals->getLocalizationFromId(locId); + return contentNotNull()->getLocalizationFromId(locId); } /*! @@ -3191,9 +3633,9 @@ const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) c * \return const DataArrayInt * - the profile array having the name \a pflName. * \throw If there is no a profile named \a pflName. */ -const DataArrayInt *MEDFileFieldGlobsReal::getProfile(const char *pflName) const throw(INTERP_KERNEL::Exception) +const DataArrayInt *MEDFileFieldGlobsReal::getProfile(const std::string& pflName) const { - return _globals->getProfile(pflName); + return contentNotNull()->getProfile(pflName); } /*! @@ -3202,9 +3644,9 @@ const DataArrayInt *MEDFileFieldGlobsReal::getProfile(const char *pflName) const * \return const DataArrayInt * - the profile array having the id \a pflId. * \throw If there is no a profile with id \a pflId. */ -const DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) const throw(INTERP_KERNEL::Exception) +const DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) const { - return _globals->getProfileFromId(pflId); + return contentNotNull()->getProfileFromId(pflId); } /*! @@ -3214,9 +3656,9 @@ const DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) const thr * having the id \a locId. * \throw If there is no a localization with id \a locId. */ -MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) throw(INTERP_KERNEL::Exception) +MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) { - return _globals->getLocalizationFromId(locId); + return contentNotNull()->getLocalizationFromId(locId); } /*! @@ -3226,9 +3668,9 @@ MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) throw(I * having the name \a locName. * \throw If there is no a localization named \a locName. */ -MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const char *locName) throw(INTERP_KERNEL::Exception) +MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const std::string& locName) { - return _globals->getLocalization(locName); + return contentNotNull()->getLocalization(locName); } /*! @@ -3237,9 +3679,9 @@ MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const char *locName) thr * \return DataArrayInt * - a non-const pointer to the profile array having the name \a pflName. * \throw If there is no a profile named \a pflName. */ -DataArrayInt *MEDFileFieldGlobsReal::getProfile(const char *pflName) throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDFileFieldGlobsReal::getProfile(const std::string& pflName) { - return _globals->getProfile(pflName); + return contentNotNull()->getProfile(pflName); } /*! @@ -3248,27 +3690,27 @@ DataArrayInt *MEDFileFieldGlobsReal::getProfile(const char *pflName) throw(INTER * \return DataArrayInt * - a non-const pointer to the profile array having the id \a pflId. * \throw If there is no a profile with id \a pflId. */ -DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) { - return _globals->getProfileFromId(pflId); + return contentNotNull()->getProfileFromId(pflId); } /*! * Removes profiles given by their ids. No data is updated to track this removal. * \param [in] pflIds - a sequence of ids of the profiles to remove. */ -void MEDFileFieldGlobsReal::killProfileIds(const std::vector& pflIds) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::killProfileIds(const std::vector& pflIds) { - _globals->killProfileIds(pflIds); + contentNotNull()->killProfileIds(pflIds); } /*! * Removes localizations given by their ids. No data is updated to track this removal. * \param [in] locIds - a sequence of ids of the localizations to remove. */ -void MEDFileFieldGlobsReal::killLocalizationIds(const std::vector& locIds) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::killLocalizationIds(const std::vector& locIds) { - _globals->killLocalizationIds(locIds); + contentNotNull()->killLocalizationIds(locIds); } /*! @@ -3278,9 +3720,9 @@ void MEDFileFieldGlobsReal::killLocalizationIds(const std::vector& locIds) * \throw If a profile with the same name as that of \a pfl already exists but contains * different ids. */ -void MEDFileFieldGlobsReal::appendProfile(DataArrayInt *pfl) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::appendProfile(DataArrayInt *pfl) { - _globals->appendProfile(pfl); + contentNotNull()->appendProfile(pfl); } /*! @@ -3296,143 +3738,82 @@ void MEDFileFieldGlobsReal::appendProfile(DataArrayInt *pfl) throw(INTERP_KERNEL * \throw If a localization with the name \a locName already exists but is * different form the new one. */ -void MEDFileFieldGlobsReal::appendLoc(const char *locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) throw(INTERP_KERNEL::Exception) +void MEDFileFieldGlobsReal::appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) { - _globals->appendLoc(locName,geoType,refCoo,gsCoo,w); + contentNotNull()->appendLoc(locName,geoType,refCoo,gsCoo,w); } -/*! - * Returns the maximal dimension of supporting elements. Returns -2 if \a this is - * empty. Returns -1 if this in on nodes. - * \return int - the dimension of \a this. - */ -int MEDFileField1TSWithoutSDA::getDimension() const +MEDFileFieldGlobs *MEDFileFieldGlobsReal::contentNotNull() { - int ret=-2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->getDimension(ret); - return ret; + MEDFileFieldGlobs *g(_globals); + if(!g) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobsReal::contentNotNull : no content in not const !"); + return g; } -/*! - * Throws if a given value is not a valid (non-extended) relative dimension. - * \param [in] meshDimRelToMax - the relative dimension value. - * \throw If \a meshDimRelToMax > 0. - */ -void MEDFileField1TSWithoutSDA::CheckMeshDimRel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception) +const MEDFileFieldGlobs *MEDFileFieldGlobsReal::contentNotNull() const { - if(meshDimRelToMax>0) - throw INTERP_KERNEL::Exception("CheckMeshDimRel : This is a meshDimRel not a meshDimRelExt ! So value should be <=0 !"); + const MEDFileFieldGlobs *g(_globals); + if(!g) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobsReal::contentNotNull : no content in const !"); + return g; } -/*! - * Checks if elements of a given mesh are in the order suitable for writing - * to the MED file. If this is not so, an exception is thrown. In a case of success, returns a - * vector describing types of elements and their number. - * \param [in] mesh - the mesh to check. - * \return std::vector - a vector holding for each element type (1) item of - * INTERP_KERNEL::NormalizedCellType, (2) number of elements, (3) -1. - * These values are in full-interlace mode. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - */ -std::vector MEDFileField1TSWithoutSDA::CheckSBTMesh(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) -{ - // - std::set geoTypes=mesh->getAllGeoTypes(); - int nbOfTypes=geoTypes.size(); - std::vector code(3*nbOfTypes); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayInt::New(); - arr1->alloc(nbOfTypes,1); - int *arrPtr=arr1->getPointer(); - std::set::const_iterator it=geoTypes.begin(); - for(int i=0;i arr2=arr1->checkAndPreparePermutation(); - const int *arrPtr2=arr2->getConstPointer(); - int i=0; - for(it=geoTypes.begin();it!=geoTypes.end();it++,i++) - { - int pos=arrPtr2[i]; - int nbCells=mesh->getNumberOfCellsWithType(*it); - code[3*pos]=(int)(*it); - code[3*pos+1]=nbCells; - code[3*pos+2]=-1;//no profiles - } - std::vector idsPerType;//no profiles - DataArrayInt *da=mesh->checkTypeConsistencyAndContig(code,idsPerType); - if(da) - { - da->decrRef(); - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::CheckSBTMesh : underlying mesh is not sorted by type as MED file expects !"); - } - return code; -} +//= MEDFileFieldNameScope -MEDFileField1TSWithoutSDA *MEDFileField1TSWithoutSDA::New(const char *fieldName, int csit, int fieldtype, int iteration, int order, const std::vector& infos) +MEDFileFieldNameScope::MEDFileFieldNameScope() { - return new MEDFileField1TSWithoutSDA(fieldName,csit,fieldtype,iteration,order,infos); } -/*! - * Copies tiny info and allocates \a this->_arr instance of DataArrayDouble to - * append data of a given MEDCouplingFieldDouble. So that the size of \a this->_arr becomes - * larger by the size of \a field. Returns an id of the first not filled - * tuple of \a this->_arr. - * \param [in] field - the field to copy the info on components and the name from. - * \return int - the id of first not initialized tuple of \a this->_arr. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If \a this->_arr is already allocated but has different number of components - * than \a field. - */ -int MEDFileField1TSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) +MEDFileFieldNameScope::MEDFileFieldNameScope(const std::string& fieldName):_name(fieldName) { - std::string name(field->getName()); - getOrCreateAndGetArray()->setName(name.c_str()); - if(name.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : unsupported fields with no name in MED file !"); - const DataArrayDouble *arr=field->getArray(); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : no array set !"); - _dt=field->getTime(_iteration,_order); - int nbOfComponents=arr->getNumberOfComponents(); - getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(arr->getInfoOnComponents()); - if(!getOrCreateAndGetArray()->isAllocated()) - { - _arr->alloc(arr->getNumberOfTuples(),arr->getNumberOfComponents()); - return 0; - } - else - { - int oldNbOfTuples=getOrCreateAndGetArray()->getNumberOfTuples(); - int newNbOfTuples=oldNbOfTuples+arr->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayDouble::New(); - tmp->alloc(newNbOfTuples,nbOfComponents); - tmp->copyStringInfoFrom(*_arr); - std::copy(_arr->begin(),_arr->end(),tmp->getPointer()); - _arr=tmp; - return oldNbOfTuples; - } } /*! * Returns the name of \a this field. * \return std::string - a string containing the field name. */ -std::string MEDFileField1TSWithoutSDA::getName() const +std::string MEDFileFieldNameScope::getName() const { - const DataArrayDouble *arr=getOrCreateAndGetArray(); - return arr->getName(); + return _name; } /*! * Sets name of \a this field * \param [in] name - the new field name. */ -void MEDFileField1TSWithoutSDA::setName(const char *name) +void MEDFileFieldNameScope::setName(const std::string& fieldName) +{ + _name=fieldName; +} + +std::string MEDFileFieldNameScope::getDtUnit() const +{ + return _dt_unit; +} + +void MEDFileFieldNameScope::setDtUnit(const std::string& dtUnit) +{ + _dt_unit=dtUnit; +} + +void MEDFileFieldNameScope::copyNameScope(const MEDFileFieldNameScope& other) +{ + _name=other._name; + _dt_unit=other._dt_unit; +} + +//= MEDFileAnyTypeField1TSWithoutSDA + +void MEDFileAnyTypeField1TSWithoutSDA::deepCpyLeavesFrom(const MEDFileAnyTypeField1TSWithoutSDA& other) { - DataArrayDouble *arr=getOrCreateAndGetArray(); - arr->setName(name); + _field_per_mesh.resize(other._field_per_mesh.size()); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=other._field_per_mesh.begin();it!=other._field_per_mesh.end();it++,i++) + { + if((const MEDFileFieldPerMesh *)*it) + _field_per_mesh[i]=(*it)->deepCpy(this); + } } /*! @@ -3443,21 +3824,23 @@ void MEDFileField1TSWithoutSDA::setName(const char *name) * \param [in] f1tsId - the field index within a MED file. If \a f1tsId < 0, the tiny * info id printed, else, not. */ -void MEDFileField1TSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const +void MEDFileAnyTypeField1TSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const { std::string startOfLine(bkOffset,' '); - oss << startOfLine << "Field on One time Step "; + oss << startOfLine << "Field "; + if(bkOffset==0) + oss << "[Type=" << getTypeStr() << "] with name \"" << getName() << "\" "; + oss << "on one time Step "; if(f1tsId>=0) oss << "(" << f1tsId << ") "; oss << "on iteration=" << _iteration << " order=" << _order << "." << std::endl; oss << startOfLine << "Time attached is : " << _dt << " [" << _dt_unit << "]." << std::endl; - const DataArrayDouble *arr=_arr; + const DataArray *arr=getUndergroundDataArray(); if(arr) { const std::vector &comps=arr->getInfoOnComponents(); if(f1tsId<0) { - oss << startOfLine << "Field Name : \"" << arr->getName() << "\"." << std::endl; oss << startOfLine << "Field has " << comps.size() << " components with the following infos :" << std::endl; for(std::vector::const_iterator it=comps.begin();it!=comps.end();it++) oss << startOfLine << " - \"" << (*it) << "\"" << std::endl; @@ -3493,19 +3876,57 @@ void MEDFileField1TSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int oss << startOfLine << "----------------------" << std::endl; } +std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitComponents() const +{ + const DataArray *arr(getUndergroundDataArray()); + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitComponents : no array defined !"); + int nbOfCompo=arr->getNumberOfComponents(); + std::vector< MEDCouplingAutoRefCountObjectPtr > ret(nbOfCompo); + for(int i=0;i v(1,i); + MEDCouplingAutoRefCountObjectPtr arr2=arr->keepSelectedComponents(v); + ret[i]->setArray(arr2); + } + return ret; +} + +MEDFileAnyTypeField1TSWithoutSDA::MEDFileAnyTypeField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order):MEDFileFieldNameScope(fieldName),_iteration(iteration),_order(order),_csit(csit),_nb_of_tuples_to_be_allocated(-2) +{ +} + +MEDFileAnyTypeField1TSWithoutSDA::MEDFileAnyTypeField1TSWithoutSDA():_iteration(-1),_order(-1),_dt(0.),_csit(-1),_nb_of_tuples_to_be_allocated(-1) +{ +} + +/*! + * Returns the maximal dimension of supporting elements. Returns -2 if \a this is + * empty. Returns -1 if this in on nodes. + * \return int - the dimension of \a this. + */ +int MEDFileAnyTypeField1TSWithoutSDA::getDimension() const +{ + int ret=-2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->getDimension(ret); + return ret; +} + /*! * Returns the mesh name. * \return std::string - a string holding the mesh name. * \throw If \c _field_per_mesh.empty() */ -std::string MEDFileField1TSWithoutSDA::getMeshName() const throw(INTERP_KERNEL::Exception) +std::string MEDFileAnyTypeField1TSWithoutSDA::getMeshName() const { if(_field_per_mesh.empty()) throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshName : No field set !"); return _field_per_mesh[0]->getMeshName(); } -void MEDFileField1TSWithoutSDA::setMeshName(const char *newMeshName) throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeField1TSWithoutSDA::setMeshName(const std::string& newMeshName) { std::string oldName(getMeshName()); std::vector< std::pair > v(1); @@ -3513,7 +3934,7 @@ void MEDFileField1TSWithoutSDA::setMeshName(const char *newMeshName) throw(INTER changeMeshNames(v); } -bool MEDFileField1TSWithoutSDA::changeMeshNames(const std::vector< std::pair >& modifTab) throw(INTERP_KERNEL::Exception) +bool MEDFileAnyTypeField1TSWithoutSDA::changeMeshNames(const std::vector< std::pair >& modifTab) { bool ret=false; for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) @@ -3525,25 +3946,12 @@ bool MEDFileField1TSWithoutSDA::changeMeshNames(const std::vector< std::pair& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, - MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - MEDFileFieldPerMesh *fpm(*it); - if(fpm) - ret=fpm->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,glob) || ret; - } - return ret; -} - /*! * Returns the number of iteration of the state of underlying mesh. * \return int - the iteration number. * \throw If \c _field_per_mesh.empty() */ -int MEDFileField1TSWithoutSDA::getMeshIteration() const throw(INTERP_KERNEL::Exception) +int MEDFileAnyTypeField1TSWithoutSDA::getMeshIteration() const { if(_field_per_mesh.empty()) throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshIteration : No field set !"); @@ -3555,22 +3963,13 @@ int MEDFileField1TSWithoutSDA::getMeshIteration() const throw(INTERP_KERNEL::Exc * \return int - the order number. * \throw If \c _field_per_mesh.empty() */ -int MEDFileField1TSWithoutSDA::getMeshOrder() const throw(INTERP_KERNEL::Exception) +int MEDFileAnyTypeField1TSWithoutSDA::getMeshOrder() const { if(_field_per_mesh.empty()) throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshOrder : No field set !"); return _field_per_mesh[0]->getMeshOrder(); } -/*! - * Returns number of components in \a this field - * \return int - the number of components. - */ -int MEDFileField1TSWithoutSDA::getNumberOfComponents() const -{ - return getOrCreateAndGetArray()->getNumberOfComponents(); -} - /*! * Checks if \a this field is tagged by a given iteration number and a given * iteration order number. @@ -3579,7 +3978,7 @@ int MEDFileField1TSWithoutSDA::getNumberOfComponents() const * \return bool - \c true if \a this->getIteration() == \a iteration && * \a this->getOrder() == \a order. */ -bool MEDFileField1TSWithoutSDA::isDealingTS(int iteration, int order) const +bool MEDFileAnyTypeField1TSWithoutSDA::isDealingTS(int iteration, int order) const { return iteration==_iteration && order==_order; } @@ -3590,7 +3989,7 @@ bool MEDFileField1TSWithoutSDA::isDealingTS(int iteration, int order) const * \return std::pair - a pair of the iteration number and the iteration * order number. */ -std::pair MEDFileField1TSWithoutSDA::getDtIt() const +std::pair MEDFileAnyTypeField1TSWithoutSDA::getDtIt() const { std::pair p; fillIteration(p); @@ -3603,7 +4002,7 @@ std::pair MEDFileField1TSWithoutSDA::getDtIt() const * \param [in,out] p - a pair returning the iteration number and the iteration * order number. */ -void MEDFileField1TSWithoutSDA::fillIteration(std::pair& p) const +void MEDFileAnyTypeField1TSWithoutSDA::fillIteration(std::pair& p) const { p.first=_iteration; p.second=_order; @@ -3613,7 +4012,7 @@ void MEDFileField1TSWithoutSDA::fillIteration(std::pair& p) const * Returns all types of spatial discretization of \a this field. * \param [in,out] types - a sequence of types of \a this field. */ -void MEDFileField1TSWithoutSDA::fillTypesOfFieldAvailable(std::vector& types) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeField1TSWithoutSDA::fillTypesOfFieldAvailable(std::vector& types) const { std::set types2; for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) @@ -3625,106 +4024,86 @@ void MEDFileField1TSWithoutSDA::fillTypesOfFieldAvailable(std::vector& - a sequence of strings each being an - * information on _i_-th component. + * Returns all types of spatial discretization of \a this field. + * \return std::vector - a sequence of types of spatial discretization + * of \a this field. */ -const std::vector& MEDFileField1TSWithoutSDA::getInfo() const +std::vector MEDFileAnyTypeField1TSWithoutSDA::getTypesOfFieldAvailable() const { - const DataArrayDouble *arr=getOrCreateAndGetArray(); - return arr->getInfoOnComponents(); + std::vector ret; + fillTypesOfFieldAvailable(ret); + return ret; } -/*! - * Returns a mutable info on components of \a this field. - * \return std::vector& - a sequence of strings each being an - * information on _i_-th component. - */ -std::vector& MEDFileField1TSWithoutSDA::getInfo() +std::vector MEDFileAnyTypeField1TSWithoutSDA::getPflsReallyUsed2() const { - DataArrayDouble *arr=getOrCreateAndGetArray(); - return arr->getInfoOnComponents(); + std::vector ret; + std::set ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + std::vector tmp=(*it)->getPflsReallyUsed(); + for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; } -/*! - * Returns dimensions of mesh elements \a this field lies on. The returned value is a - * maximal absolute dimension and values returned via the out parameter \a levs are - * dimensions relative to the maximal absolute dimension.
- * This method is designed for MEDFileField1TS instances that have a discretization - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS", - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE". - * Only these 3 discretizations will be taken into account here. If \a this is - * \ref ParaMEDMEM::ON_NODES "ON_NODES", -1 is returned and \a levs are empty.
- * This method is useful to make the link between the dimension of the underlying mesh - * and the levels of \a this, because it is possible that the highest dimension of \a this - * field is not equal to the dimension of the underlying mesh. - * - * Let's consider the following case: - * - mesh \a m1 has a meshDimension 3 and has non empty levels [0,-1,-2] with elements - * TETRA4, HEXA8, TRI3 and SEG2. - * - field \a f1 lies on \a m1 and is defined on 3D and 1D elements TETRA4 and SEG2. - * - field \a f2 lies on \a m1 and is defined on 2D and 1D elements TRI3 and SEG2. - * - * In this case \a f1->getNonEmptyLevels() returns (3,[0,-2]) and \a - * f2->getNonEmptyLevels() returns (2,[0,-1]).
- * The returned values can be used for example to retrieve a MEDCouplingFieldDouble lying - * on elements of a certain relative level by calling getFieldAtLevel(). \a meshDimRelToMax - * parameter of getFieldAtLevel() is computed basing on the returned values as this: - * meshDimRelToMax = absDim - meshDim + relativeLev . - * For example
- * to retrieve the highest level of - * \a f1: f1->getFieldAtLevel( ON_CELLS, 3-3+0 ); // absDim - meshDim + relativeLev
- * to retrieve the lowest level of \a f1: f1->getFieldAtLevel( ON_CELLS, 3-3+(-2) );
- * to retrieve the highest level of \a f2: f2->getFieldAtLevel( ON_CELLS, 2-3+0 );
- * to retrieve the lowest level of \a f2: f2->getFieldAtLevel( ON_CELLS, 2-3+(-1) ). - * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid - * for the case with only one underlying mesh. (Actually, the number of meshes is - * not checked if \a mname == \c NULL). - * \param [in,out] levs - a sequence returning the dimensions relative to the maximal - * absolute one. They are in decreasing order. This sequence is cleared before - * filling it in. - * \return int - the maximal absolute dimension of elements \a this fields lies on. - * \throw If no field is lying on \a mname. - */ -int MEDFileField1TSWithoutSDA::getNonEmptyLevels(const char *mname, std::vector& levs) const throw(INTERP_KERNEL::Exception) +std::vector MEDFileAnyTypeField1TSWithoutSDA::getLocsReallyUsed2() const { - levs.clear(); - int meshId=getMeshIdFromMeshName(mname); - std::vector types; - std::vector< std::vector > typesF; - std::vector< std::vector > pfls, locs; - _field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); - if(types.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getNonEmptyLevels : 'this' is empty !"); - std::set st(types.begin(),types.end()); - if(st.size()==1 && (*st.begin())==INTERP_KERNEL::NORM_ERROR) - return -1; - st.erase(INTERP_KERNEL::NORM_ERROR); - std::set ret1; - for(std::set::const_iterator it=st.begin();it!=st.end();it++) + std::vector ret; + std::set ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*it); - ret1.insert((int)cm.getDimension()); + std::vector tmp=(*it)->getLocsReallyUsed(); + for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } } - int ret=*std::max_element(ret1.begin(),ret1.end()); - std::copy(ret1.rbegin(),ret1.rend(),std::back_insert_iterator >(levs)); - std::transform(levs.begin(),levs.end(),levs.begin(),std::bind2nd(std::plus(),-ret)); return ret; } -/*! - * Returns all types of spatial discretization of \a this field. - * \return std::vector - a sequence of types of spatial discretization - * of \a this field. - */ -std::vector MEDFileField1TSWithoutSDA::getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) +std::vector MEDFileAnyTypeField1TSWithoutSDA::getPflsReallyUsedMulti2() const { - std::vector ret; - fillTypesOfFieldAvailable(ret); + std::vector ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + std::vector tmp=(*it)->getPflsReallyUsedMulti(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +std::vector MEDFileAnyTypeField1TSWithoutSDA::getLocsReallyUsedMulti2() const +{ + std::vector ret; + std::set ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + std::vector tmp=(*it)->getLocsReallyUsedMulti(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } return ret; } +void MEDFileAnyTypeField1TSWithoutSDA::changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->changePflsRefsNamesGen(mapOfModif); +} + +void MEDFileAnyTypeField1TSWithoutSDA::changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->changeLocsRefsNamesGen(mapOfModif); +} + /*! * Returns all attributes of parts of \a this field lying on a given mesh. * Each part differs from other ones by a type of supporting mesh entity. The _i_-th @@ -3732,7 +4111,7 @@ std::vector MEDFileField1TSWithoutSDA::getTypesOfFieldAvailable() c * Thus all sequences returned by this method are of the same length equal to number * of different types of supporting entities.
* A field part can include sub-parts with several different spatial discretizations, - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" + * \ref MEDCoupling::ON_CELLS "ON_CELLS" and \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" * for example. Hence, some of the returned sequences contains nested sequences, and an item * of a nested sequence corresponds to a type of spatial discretization.
* This method allows for iteration over MEDFile DataStructure without any overhead. @@ -3755,10 +4134,10 @@ std::vector MEDFileField1TSWithoutSDA::getTypesOfFieldAvailable() c * Length of this and of nested sequences is the same as that of \a typesF. * \throw If no field is lying on \a mname. */ -std::vector< std::vector< std::pair > > MEDFileField1TSWithoutSDA::getFieldSplitedByType(const char *mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception) +std::vector< std::vector< std::pair > > MEDFileAnyTypeField1TSWithoutSDA::getFieldSplitedByType(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const { int meshId=0; - if(mname) + if(!mname.empty()) meshId=getMeshIdFromMeshName(mname); else if(_field_per_mesh.empty()) @@ -3767,175 +4146,388 @@ std::vector< std::vector< std::pair > > MEDFileField1TSWithoutSDA::getF } /*! - * Returns all attributes and values of parts of \a this field lying on a given mesh. - * Each part differs from other ones by a type of supporting mesh entity. The _i_-th - * item of every of returned sequences refers to the _i_-th part of \a this field. - * Thus all sequences returned by this method are of the same length equal to number - * of different types of supporting entities.
- * A field part can include sub-parts with several different spatial discretizations, - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" - * for example. Hence, some of the returned sequences contains nested sequences, and an item - * of a nested sequence corresponds to a type of spatial discretization.
- * This method allows for iteration over MEDFile DataStructure with a reduced overhead. - * The overhead is due to selecting values into new instances of DataArrayDouble. + * Returns dimensions of mesh elements \a this field lies on. The returned value is a + * maximal absolute dimension and values returned via the out parameter \a levs are + * dimensions relative to the maximal absolute dimension.
+ * This method is designed for MEDFileField1TS instances that have a discretization + * \ref MEDCoupling::ON_CELLS "ON_CELLS", + * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT", + * \ref MEDCoupling::ON_GAUSS_NE "ON_GAUSS_NE". + * Only these 3 discretizations will be taken into account here. If \a this is + * \ref MEDCoupling::ON_NODES "ON_NODES", -1 is returned and \a levs are empty.
+ * This method is useful to make the link between the dimension of the underlying mesh + * and the levels of \a this, because it is possible that the highest dimension of \a this + * field is not equal to the dimension of the underlying mesh. + * + * Let's consider the following case: + * - mesh \a m1 has a meshDimension 3 and has non empty levels [0,-1,-2] with elements + * TETRA4, HEXA8, TRI3 and SEG2. + * - field \a f1 lies on \a m1 and is defined on 3D and 1D elements TETRA4 and SEG2. + * - field \a f2 lies on \a m1 and is defined on 2D and 1D elements TRI3 and SEG2. + * + * In this case \a f1->getNonEmptyLevels() returns (3,[0,-2]) and \a + * f2->getNonEmptyLevels() returns (2,[0,-1]).
+ * The returned values can be used for example to retrieve a MEDCouplingFieldDouble lying + * on elements of a certain relative level by calling getFieldAtLevel(). \a meshDimRelToMax + * parameter of getFieldAtLevel() is computed basing on the returned values as this: + * meshDimRelToMax = absDim - meshDim + relativeLev . + * For example
+ * to retrieve the highest level of + * \a f1: f1->getFieldAtLevel( ON_CELLS, 3-3+0 ); // absDim - meshDim + relativeLev
+ * to retrieve the lowest level of \a f1: f1->getFieldAtLevel( ON_CELLS, 3-3+(-2) );
+ * to retrieve the highest level of \a f2: f2->getFieldAtLevel( ON_CELLS, 2-3+0 );
+ * to retrieve the lowest level of \a f2: f2->getFieldAtLevel( ON_CELLS, 2-3+(-1) ). * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid * for the case with only one underlying mesh. (Actually, the number of meshes is * not checked if \a mname == \c NULL). - * \param [in,out] types - a sequence of types of underlying mesh entities. A type per - * a field part is returned. - * \param [in,out] typesF - a sequence of sequences of types of spatial discretizations. - * A field part can include sub-parts with several different spatial discretizations, - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" for example. - * This sequence is of the same length as \a types. - * \param [in,out] pfls - a sequence returning a profile name per each type of spatial - * discretization. A profile name can be empty. - * Length of this and of nested sequences is the same as that of \a typesF. - * \param [in,out] locs - a sequence returning a localization name per each type of spatial - * discretization. A localization name can be empty. - * Length of this and of nested sequences is the same as that of \a typesF. - * \return std::vector< std::vector > - a sequence holding arrays of values - * per each type of spatial discretization within one mesh entity type. - * The caller is to delete each DataArrayDouble using decrRef() as it is no more needed. - * Length of this and of nested sequences is the same as that of \a typesF. + * \param [in,out] levs - a sequence returning the dimensions relative to the maximal + * absolute one. They are in decreasing order. This sequence is cleared before + * filling it in. + * \return int - the maximal absolute dimension of elements \a this fields lies on. * \throw If no field is lying on \a mname. */ -std::vector< std::vector > MEDFileField1TSWithoutSDA::getFieldSplitedByType2(const char *mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception) +int MEDFileAnyTypeField1TSWithoutSDA::getNonEmptyLevels(const std::string& mname, std::vector& levs) const { - int meshId=0; - if(mname) - meshId=getMeshIdFromMeshName(mname); - else - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldSplitedByType : This is empty !"); - std::vector< std::vector< std::pair > > ret0=_field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); - int nbOfRet=ret0.size(); - std::vector< std::vector > ret(nbOfRet); - for(int i=0;i types; + std::vector< std::vector > typesF; + std::vector< std::vector > pfls, locs; + _field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); + if(types.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getNonEmptyLevels : 'this' is empty !"); + std::set st(types.begin(),types.end()); + if(st.size()==1 && (*st.begin())==INTERP_KERNEL::NORM_ERROR) + return -1; + st.erase(INTERP_KERNEL::NORM_ERROR); + std::set ret1; + for(std::set::const_iterator it=st.begin();it!=st.end();it++) { - const std::vector< std::pair >& p=ret0[i]; - int nbOfRet1=p.size(); - ret[i].resize(nbOfRet1); - for(int j=0;jselectByTupleId2(p[j].first,p[j].second,1); - ret[i][j]=tmp; - } + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*it); + ret1.insert((int)cm.getDimension()); } + int ret=*std::max_element(ret1.begin(),ret1.end()); + std::copy(ret1.rbegin(),ret1.rend(),std::back_insert_iterator >(levs)); + std::transform(levs.begin(),levs.end(),levs.begin(),std::bind2nd(std::plus(),-ret)); return ret; } -void MEDFileField1TSWithoutSDA::finishLoading(med_idt fid) throw(INTERP_KERNEL::Exception) +/*! + * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. + * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. + * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of + * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. + */ +MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TSWithoutSDA::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) { - med_int numdt,numit; - med_float dt; - med_int nmesh; - med_bool localMesh; - med_int meshnumdt,meshnumit; - INTERP_KERNEL::AutoPtr meshName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDfieldComputingStepInfo(fid,getName().c_str(),_csit,&numdt,&numit,&_dt); - MEDfield23ComputingStepMeshInfo(fid,getName().c_str(),_csit,&numdt,&numit,&dt,&nmesh,meshName,&localMesh,&meshnumdt,&meshnumit); - if(_iteration!=numdt || _order!=numit) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::finishLoading : unexpected exception internal error !"); - _field_per_mesh.resize(nmesh); - for(int i=0;iprepareLoading(fid,start); - } - getOrCreateAndGetArray()->alloc(start,getNumberOfComponents()); - for(int i=0;ifinishLoading(fid,_field_type); - } + int mid=getMeshIdFromMeshName(mName); + return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); } -std::vector MEDFileField1TSWithoutSDA::getPflsReallyUsed2() const +/*! + * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. + * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. + * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of + * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. + */ +const MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TSWithoutSDA::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const { - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsed(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; + int mid=getMeshIdFromMeshName(mName); + return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); +} + +/*! + * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. + */ +int MEDFileAnyTypeField1TSWithoutSDA::getMeshIdFromMeshName(const std::string& mName) const +{ + if(_field_per_mesh.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getMeshIdFromMeshName : No field set !"); + if(mName.empty()) + return 0; + std::string mName2(mName); + int ret=0; + std::vector msg; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++,ret++) + if(mName2==(*it)->getMeshName()) + return ret; + else + msg.push_back((*it)->getMeshName()); + std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getMeshIdFromMeshName : No such mesh \"" << mName2 << "\" as underlying mesh of field \"" << getName() << "\" !\n"; + oss << "Possible meshes are : "; + for(std::vector::const_iterator it2=msg.begin();it2!=msg.end();it2++) + oss << "\"" << (*it2) << "\" "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } -std::vector MEDFileField1TSWithoutSDA::getLocsReallyUsed2() const +int MEDFileAnyTypeField1TSWithoutSDA::addNewEntryIfNecessary(const MEDCouplingMesh *mesh) { - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::addNewEntryIfNecessary : input mesh is NULL !"); + std::string tmp(mesh->getName()); + if(tmp.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::addNewEntryIfNecessary : empty mesh name ! unsupported by MED file !"); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin(); + int i=0; + for(;it!=_field_per_mesh.end();it++,i++) { - std::vector tmp=(*it)->getLocsReallyUsed(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } + if((*it)->getMeshName()==tmp) + return i; } - return ret; + int sz=_field_per_mesh.size(); + _field_per_mesh.resize(sz+1); + _field_per_mesh[sz]=MEDFileFieldPerMesh::New(this,mesh); + return sz; } -std::vector MEDFileField1TSWithoutSDA::getPflsReallyUsedMulti2() const +bool MEDFileAnyTypeField1TSWithoutSDA::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, + MEDFileFieldGlobsReal& glob) { - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) { - std::vector tmp=(*it)->getPflsReallyUsedMulti(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); + MEDFileFieldPerMesh *fpm(*it); + if(fpm) + ret=fpm->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,glob) || ret; } return ret; } -std::vector MEDFileField1TSWithoutSDA::getLocsReallyUsedMulti2() const +/*! + * This method splits \a this into several sub-parts so that each sub parts have exactly one spatial discretization. This method implements the minimal + * splitting that leads to single spatial discretization of this. + * + * \sa splitMultiDiscrPerGeoTypes + */ +std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations() const { - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsedMulti(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); + std::vector types; + std::vector< std::vector > typesF; + std::vector< std::vector > pfls,locs; + std::vector< std::vector > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs)); + std::set allEnt; + for(std::vector< std::vector >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++) + for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + allEnt.insert(*it2); + std::vector< MEDCouplingAutoRefCountObjectPtr > ret(allEnt.size()); + std::set::const_iterator it3(allEnt.begin()); + for(std::size_t i=0;i > its; + ret[i]=shallowCpy(); + int newLgth(ret[i]->keepOnlySpatialDiscretization(*it3,its)); + ret[i]->updateData(newLgth,its); } return ret; } -void MEDFileField1TSWithoutSDA::changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) -{ +/*! + * This method performs a sub splitting as splitDiscretizations does but finer. This is the finest spliting level that can be done. + * This method implements the minimal splitting so that each returned elements are mono Gauss discretization per geometric type. + * + * \sa splitDiscretizations + */ +std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes() const +{ + std::vector types; + std::vector< std::vector > typesF; + std::vector< std::vector > pfls,locs; + std::vector< std::vector > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs)); + std::set allEnt; + std::size_t nbOfMDPGT(0),ii(0); + for(std::vector< std::vector >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++,ii++) + { + nbOfMDPGT=std::max(nbOfMDPGT,locs[ii].size()); + for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + allEnt.insert(*it2); + } + if(allEnt.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : this field is expected to be defined only on one spatial discretization !"); + if(nbOfMDPGT==0) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !"); + if(nbOfMDPGT==1) + { + std::vector< MEDCouplingAutoRefCountObjectPtr > ret0(1); + ret0[0]=const_cast(this); this->incrRef(); + return ret0; + } + std::vector< MEDCouplingAutoRefCountObjectPtr > ret(nbOfMDPGT); + for(std::size_t i=0;i > its; + ret[i]=shallowCpy(); + int newLgth(ret[i]->keepOnlyGaussDiscretization(i,its)); + ret[i]->updateData(newLgth,its); + } + return ret; +} + +int MEDFileAnyTypeField1TSWithoutSDA::keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair >& its) +{ + int globalCounter(0); for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->changePflsRefsNamesGen(mapOfModif); + (*it)->keepOnlySpatialDiscretization(tof,globalCounter,its); + return globalCounter; } -void MEDFileField1TSWithoutSDA::changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +int MEDFileAnyTypeField1TSWithoutSDA::keepOnlyGaussDiscretization(std::size_t idOfDisc, std::vector< std::pair >& its) { + int globalCounter(0); for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->changeLocsRefsNamesGen(mapOfModif); + (*it)->keepOnlyGaussDiscretization(idOfDisc,globalCounter,its); + return globalCounter; +} + +void MEDFileAnyTypeField1TSWithoutSDA::updateData(int newLgth, const std::vector< std::pair >& oldStartStops) +{ + if(_nb_of_tuples_to_be_allocated>=0) + { + _nb_of_tuples_to_be_allocated=newLgth; + const DataArray *oldArr(getUndergroundDataArray()); + if(oldArr) + { + MEDCouplingAutoRefCountObjectPtr newArr(createNewEmptyDataArrayInstance()); + newArr->setInfoAndChangeNbOfCompo(oldArr->getInfoOnComponents()); + setArray(newArr); + _nb_of_tuples_to_be_allocated=newLgth;//force the _nb_of_tuples_to_be_allocated because setArray has been used specialy + } + return ; + } + if(_nb_of_tuples_to_be_allocated==-1) + return ; + if(_nb_of_tuples_to_be_allocated==-2 || _nb_of_tuples_to_be_allocated==-3) + { + const DataArray *oldArr(getUndergroundDataArray()); + if(!oldArr || !oldArr->isAllocated()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : internal error 1 !"); + MEDCouplingAutoRefCountObjectPtr newArr(createNewEmptyDataArrayInstance()); + newArr->alloc(newLgth,getNumberOfComponents()); + if(oldArr) + newArr->copyStringInfoFrom(*oldArr); + int pos=0; + for(std::vector< std::pair >::const_iterator it=oldStartStops.begin();it!=oldStartStops.end();it++) + { + if((*it).second<(*it).first) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : the range in the leaves was invalid !"); + newArr->setContigPartOfSelectedValues2(pos,oldArr,(*it).first,(*it).second,1); + pos+=(*it).second-(*it).first; + } + setArray(newArr); + return ; + } + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : internal error 2 !"); } -void MEDFileField1TSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeField1TSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts, const MEDFileFieldNameScope& nasc) const { if(_field_per_mesh.empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::writeLL : empty field !"); if(_field_per_mesh.size()>1) throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::writeLL : In MED3.0 mode in writting mode only ONE underlying mesh supported !"); _field_per_mesh[0]->copyOptionsFrom(opts); - _field_per_mesh[0]->writeLL(fid); + _field_per_mesh[0]->writeLL(fid,nasc); +} + +/*! + * This methods returns true is the allocation has been needed leading to a modification of state in \a this->_nb_of_tuples_to_be_allocated. + * If false is returned the memory allocation is not required. + */ +bool MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile() +{ + if(_nb_of_tuples_to_be_allocated>=0) + { + getOrCreateAndGetArray()->alloc(_nb_of_tuples_to_be_allocated,getNumberOfComponents()); + _nb_of_tuples_to_be_allocated=-2; + return true; + } + if(_nb_of_tuples_to_be_allocated==-2 || _nb_of_tuples_to_be_allocated==-3) + return false; + if(_nb_of_tuples_to_be_allocated==-1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : trying to read from a file an empty instance ! Need to prepare the structure before !"); + if(_nb_of_tuples_to_be_allocated<-3) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : internal error !"); + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : internal error !"); +} + +void MEDFileAnyTypeField1TSWithoutSDA::loadOnlyStructureOfDataRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +{ + med_int numdt,numit; + med_float dt; + med_int nmesh; + med_bool localMesh; + med_int meshnumdt,meshnumit; + INTERP_KERNEL::AutoPtr meshName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nasc.getName().c_str(),_csit,&numdt,&numit,&_dt)); + MEDFILESAFECALLERRD0(MEDfield23ComputingStepMeshInfo,(fid,nasc.getName().c_str(),_csit,&numdt,&numit,&dt,&nmesh,meshName,&localMesh,&meshnumdt,&meshnumit)); + if(_iteration!=numdt || _order!=numit) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursively : unexpected exception internal error !"); + _field_per_mesh.resize(nmesh); + // + MEDFileMesh *mm(0); + if(ms) + { + std::string meshNameCpp(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); + mm=ms->getMeshWithName(meshNameCpp); + } + // + for(int i=0;iloadOnlyStructureOfDataRecursively(fid,_nb_of_tuples_to_be_allocated,nasc); +} + +void MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + allocIfNecessaryTheArrayToReceiveDataFromFile(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->loadBigArraysRecursively(fid,nasc); +} + +void MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + if(allocIfNecessaryTheArrayToReceiveDataFromFile()) + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->loadBigArraysRecursively(fid,nasc); +} + +void MEDFileAnyTypeField1TSWithoutSDA::loadStructureAndBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +{ + loadOnlyStructureOfDataRecursively(fid,nasc,ms,entities); + loadBigArraysRecursively(fid,nasc); +} + +void MEDFileAnyTypeField1TSWithoutSDA::unloadArrays() +{ + DataArray *thisArr(getUndergroundDataArray()); + if(thisArr && thisArr->isAllocated()) + { + _nb_of_tuples_to_be_allocated=thisArr->getNumberOfTuples(); + thisArr->desallocate(); + } +} + +std::size_t MEDFileAnyTypeField1TSWithoutSDA::getHeapMemorySizeWithoutChildren() const +{ + return _dt_unit.capacity()+_field_per_mesh.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh >); +} + +std::vector MEDFileAnyTypeField1TSWithoutSDA::getDirectChildrenWithNull() const +{ + std::vector ret; + if(getUndergroundDataArray()) + ret.push_back(getUndergroundDataArray()); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + ret.push_back((const MEDFileFieldPerMesh *)*it); + return ret; } /*! * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is * checked if its elements are sorted suitable for writing to MED file ("STB" stands for * "Sort By Type"), if not, an exception is thrown. - * \param [in] field - the field to add to \a this. + * \param [in] field - the field to add to \a this. The array of field \a field is ignored + * \param [in] arr - the array of values. * \param [in,out] glob - the global data where profiles and localization present in * \a field, if any, are added. * \throw If the name of \a field is empty. @@ -3945,21 +4537,21 @@ void MEDFileField1TSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts * \throw If the underlying mesh of \a field has no name. * \throw If elements in the mesh are not in the order suitable for writing to the MED file. */ -void MEDFileField1TSWithoutSDA::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeField1TSWithoutSDA::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) { const MEDCouplingMesh *mesh=field->getMesh(); // TypeOfField type=field->getTypeOfField(); std::vector dummy; - int start=copyTinyInfoFrom(field); + int start=copyTinyInfoFrom(field,arr); int pos=addNewEntryIfNecessary(mesh); if(type!=ON_NODES) { std::vector code=MEDFileField1TSWithoutSDA::CheckSBTMesh(mesh); - _field_per_mesh[pos]->assignFieldNoProfileNoRenum(start,code,field,glob); + _field_per_mesh[pos]->assignFieldNoProfileNoRenum(start,code,field,arr,glob,nasc); } else - _field_per_mesh[pos]->assignNodeFieldNoProfile(start,field,glob); + _field_per_mesh[pos]->assignNodeFieldNoProfile(start,field,arr,glob); } /*! @@ -3970,7 +4562,8 @@ void MEDFileField1TSWithoutSDA::setFieldNoProfileSBT(const MEDCouplingFieldDoubl * is not prescribed; this method permutes field values to have them sorted by element * type as required for writing to MED file. A new profile is added only if no equal * profile is missing. - * \param [in] field - the field to add to \a this. + * \param [in] field - the field to add to \a this. The field double values are ignored. + * \param [in] arrOfVals - the values of the field \a field used. * \param [in] mesh - the supporting mesh of \a field. * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on. * \param [in] profile - ids of mesh entities on which corresponding field values lie. @@ -3984,34 +4577,162 @@ void MEDFileField1TSWithoutSDA::setFieldNoProfileSBT(const MEDCouplingFieldDoubl * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. * \sa setFieldNoProfileSBT() */ -void MEDFileField1TSWithoutSDA::setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) { + if(!field) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input field is null !"); + if(!arrOfVals || !arrOfVals->isAllocated()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input array is null or not allocated !"); TypeOfField type=field->getTypeOfField(); - int start=copyTinyInfoFrom(field); std::vector idsInPflPerType; std::vector idsPerType; std::vector code,code2; - MEDCouplingAutoRefCountObjectPtr m=mesh->getGenMeshAtLevel(meshDimRelToMax); + MEDCouplingAutoRefCountObjectPtr m(mesh->getMeshAtLevel(meshDimRelToMax)); if(type!=ON_NODES) { m->splitProfilePerType(profile,code,idsInPflPerType,idsPerType); + std::vector< MEDCouplingAutoRefCountObjectPtr > idsInPflPerType2(idsInPflPerType.size()); std::copy(idsInPflPerType.begin(),idsInPflPerType.end(),idsInPflPerType2.begin()); + std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerType2(idsPerType.size()); std::copy(idsPerType.begin(),idsPerType.end(),idsPerType2.begin()); + std::vector idsPerType3(idsPerType.size()); std::copy(idsPerType.begin(),idsPerType.end(),idsPerType3.begin()); + // start of check + MEDCouplingAutoRefCountObjectPtr field2=field->clone(false); + int nbOfTuplesExp=field2->getNumberOfTuplesExpectedRegardingCode(code,idsPerType3); + if(nbOfTuplesExp!=arrOfVals->getNumberOfTuples()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : The array is expected to have " << nbOfTuplesExp << " tuples ! It has " << arrOfVals->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // end of check + int start=copyTinyInfoFrom(field,arrOfVals); code2=m->getDistributionOfTypes(); // - std::vector< MEDCouplingAutoRefCountObjectPtr > idsInPflPerType2(idsInPflPerType.size()); - for(std::size_t i=0;i > idsPerType2(idsPerType.size()); - for(std::size_t i=0;iassignFieldProfile(start,profile,code,code2,idsInPflPerType,idsPerType,field,m,glob); + _field_per_mesh[pos]->assignFieldProfile(start,profile,code,code2,idsInPflPerType,idsPerType,field,arrOfVals,m,glob,nasc); } else { + if(!profile || !profile->isAllocated() || profile->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input profile is null, not allocated or with number of components != 1 !"); + std::vector v(3); v[0]=-1; v[1]=profile->getNumberOfTuples(); v[2]=0; + std::vector idsPerType3(1); idsPerType3[0]=profile; + int nbOfTuplesExp=field->getNumberOfTuplesExpectedRegardingCode(v,idsPerType3); + if(nbOfTuplesExp!=arrOfVals->getNumberOfTuples()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : For node field, the array is expected to have " << nbOfTuplesExp << " tuples ! It has " << arrOfVals->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int start=copyTinyInfoFrom(field,arrOfVals); int pos=addNewEntryIfNecessary(m); - _field_per_mesh[pos]->assignNodeFieldProfile(start,profile,field,glob); + _field_per_mesh[pos]->assignNodeFieldProfile(start,profile,field,arrOfVals,glob,nasc); + } +} + +/*! + * \param [in] newNbOfTuples - The new nb of tuples to be allocated. + */ +void MEDFileAnyTypeField1TSWithoutSDA::allocNotFromFile(int newNbOfTuples) +{ + if(_nb_of_tuples_to_be_allocated>=0) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocNotFromFile : the object is expected to be appended to a data coming from a file but not loaded ! Load before appending data !"); + DataArray *arr(getOrCreateAndGetArray()); + arr->alloc(newNbOfTuples,arr->getNumberOfComponents()); + _nb_of_tuples_to_be_allocated=-3; +} + +/*! + * Copies tiny info and allocates \a this->_arr instance of DataArrayDouble to + * append data of a given MEDCouplingFieldDouble. So that the size of \a this->_arr becomes + * larger by the size of \a field. Returns an id of the first not filled + * tuple of \a this->_arr. + * \param [in] field - the field to copy the info on components and the name from. + * \return int - the id of first not initialized tuple of \a this->_arr. + * \throw If the name of \a field is empty. + * \throw If the data array of \a field is not set. + * \throw If \a this->_arr is already allocated but has different number of components + * than \a field. + */ +int MEDFileAnyTypeField1TSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::copyTinyInfoFrom : input field is NULL !"); + std::string name(field->getName()); + setName(name.c_str()); + setDtUnit(field->getTimeUnit()); + if(name.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : unsupported fields with no name in MED file !"); + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : no array set !"); + if(!arr->isAllocated()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : array is not allocated !"); + _dt=field->getTime(_iteration,_order); + getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(arr->getInfoOnComponents()); + if(!getOrCreateAndGetArray()->isAllocated()) + { + allocNotFromFile(arr->getNumberOfTuples()); + return 0; + } + else + { + int oldNbOfTuples=getOrCreateAndGetArray()->getNumberOfTuples(); + int newNbOfTuples=oldNbOfTuples+arr->getNumberOfTuples(); + getOrCreateAndGetArray()->reAlloc(newNbOfTuples); + _nb_of_tuples_to_be_allocated=-3; + return oldNbOfTuples; + } +} + +/*! + * Returns number of components in \a this field + * \return int - the number of components. + */ +int MEDFileAnyTypeField1TSWithoutSDA::getNumberOfComponents() const +{ + return getOrCreateAndGetArray()->getNumberOfComponents(); +} + +/*! + * Change info on components in \a this. + * \throw If size of \a infos is not equal to the number of components already in \a this. + */ +void MEDFileAnyTypeField1TSWithoutSDA::setInfo(const std::vector& infos) +{ + DataArray *arr=getOrCreateAndGetArray(); + arr->setInfoOnComponents(infos);//will throw an exception if number of components mimatches +} + +/*! + * Returns info on components of \a this field. + * \return const std::vector& - a sequence of strings each being an + * information on _i_-th component. + */ +const std::vector& MEDFileAnyTypeField1TSWithoutSDA::getInfo() const +{ + const DataArray *arr=getOrCreateAndGetArray(); + return arr->getInfoOnComponents(); +} + +/*! + * Returns a mutable info on components of \a this field. + * \return std::vector& - a sequence of strings each being an + * information on _i_-th component. + */ +std::vector& MEDFileAnyTypeField1TSWithoutSDA::getInfo() +{ + DataArray *arr=getOrCreateAndGetArray(); + return arr->getInfoOnComponents(); +} + +bool MEDFileAnyTypeField1TSWithoutSDA::presenceOfMultiDiscPerGeoType() const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + const MEDFileFieldPerMesh *fpm(*it); + if(!fpm) + continue; + if(fpm->presenceOfMultiDiscPerGeoType()) + return true; } + return false; } /*! @@ -4035,14 +4756,14 @@ void MEDFileField1TSWithoutSDA::setFieldProfile(const MEDCouplingFieldDouble *fi * \throw If no field of \a this is lying on the mesh \a mName. * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. */ -MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, const char *mName, int renumPol, const MEDFileFieldGlobsReal *glob) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const { MEDCouplingAutoRefCountObjectPtr mm; - if(mName==0) + if(mName.empty()) mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder()); else mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder()); - return MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm); + return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm,arrOut,nasc); } /*! @@ -4065,14 +4786,14 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldAtLevel(TypeOfField t * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. */ -MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDFileMesh *mesh, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const { - MEDCouplingAutoRefCountObjectPtr m=mesh->getGenMeshAtLevel(meshDimRelToMax,false); + MEDCouplingAutoRefCountObjectPtr m(mesh->getMeshAtLevel(meshDimRelToMax,false)); const DataArrayInt *d=mesh->getNumberFieldAtLevel(meshDimRelToMax); const DataArrayInt *e=mesh->getNumberFieldAtLevel(1); if(meshDimRelToMax==1) (static_cast((MEDCouplingMesh *)m))->setMeshDimension(0); - return MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(type,renumPol,glob,m,d,e); + return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,renumPol,glob,m,d,e,arrOut,nasc); } /*! @@ -4095,16 +4816,16 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF * \throw If there are no mesh entities in the mesh. * \throw If no field values of the given \a type are available. */ -MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldAtTopLevel(TypeOfField type, const char *mName, int renumPol, const MEDFileFieldGlobsReal *glob) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldAtTopLevel(TypeOfField type, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const { - MEDCouplingAutoRefCountObjectPtr mm; - if(mName==0) + MEDCouplingAutoRefCountObjectPtr mm; + if(mName.empty()) mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder()); else mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder()); int absDim=getDimension(); int meshDimRelToMax=absDim-mm->getMeshDimension(); - return MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm); + return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm,arrOut,nasc); } /*! @@ -4129,14 +4850,14 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldAtTopLevel(TypeOfFiel * \throw If no field of \a this is lying on \a mesh. * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. */ -MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, const DataArrayInt *cellRenum, const DataArrayInt *nodeRenum) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, const DataArrayInt *cellRenum, const DataArrayInt *nodeRenum, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const { static const char msg1[]="MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : request for a renumbered field following mesh numbering whereas it is a profile field !"; int meshId=getMeshIdFromMeshName(mesh->getName()); bool isPfl=false; - MEDCouplingAutoRefCountObjectPtr ret=_field_per_mesh[meshId]->getFieldOnMeshAtLevel(type,glob,mesh,isPfl); + MEDCouplingAutoRefCountObjectPtr ret=_field_per_mesh[meshId]->getFieldOnMeshAtLevel(type,glob,mesh,isPfl,arrOut,nasc); switch(renumPol) - { + { case 0: { //no need to test _field_per_mesh.empty() because geMeshName has already done it @@ -4156,7 +4877,12 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF oss << "\"" << getName() << "\" has partial renumbering (some geotype has no renumber) !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - ret->renumberCells(cellRenum->getConstPointer(),true); + MEDCouplingFieldDiscretization *disc=ret->getDiscretization(); + if(!disc) throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel : internal error, no discretization on field !"); + std::vector arrOut2(1,arrOut); + // 2 following lines replace ret->renumberCells(cellRenum->getConstPointer()) if not DataArrayDouble + disc->renumberArraysForCell(ret->getMesh(),arrOut2,cellRenum->getConstPointer(),true); + (const_cast(ret->getMesh()))->renumberCells(cellRenum->getConstPointer(),true); } if(renumPol==1) return ret.retn(); @@ -4171,17 +4897,19 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF if((int)nodeRenum->getNbOfElems()!=mesh->getNumberOfNodes()) { std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : Request of simple renumbering but it seems that underlying mesh \"" << mesh->getName() << "\" of requested field "; - oss << "\"" << getName() << "\" not defined on all nodes !"; + oss << "\"" << nasc.getName() << "\" not defined on all nodes !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } MEDCouplingAutoRefCountObjectPtr nodeRenumSafe=nodeRenum->checkAndPreparePermutation(); + if(!dynamic_cast((DataArray *)arrOut)) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : node renumbering not implemented for not double DataArrays !"); ret->renumberNodes(nodeRenumSafe->getConstPointer()); } return ret.retn(); } default: throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : unsupported renum policy ! Dealing with policy 0 1 2 and 3 !"); - } + } } /*! @@ -4200,157 +4928,278 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF * \throw If no field of \a this is lying on \a mesh. * \throw If no field values of the given \a type are available. */ -DataArrayDouble *MEDFileField1TSWithoutSDA::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob) const throw(INTERP_KERNEL::Exception) +DataArray *MEDFileAnyTypeField1TSWithoutSDA::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const { - MEDCouplingAutoRefCountObjectPtr m=mesh->getGenMeshAtLevel(meshDimRelToMax); - int meshId=getMeshIdFromMeshName(mesh->getName()); - return _field_per_mesh[meshId]->getFieldOnMeshAtLevelWithPfl(type,m,pfl,glob); + MEDCouplingAutoRefCountObjectPtr m(mesh->getMeshAtLevel(meshDimRelToMax)); + int meshId=getMeshIdFromMeshName(mesh->getName().c_str()); + MEDCouplingAutoRefCountObjectPtr ret=_field_per_mesh[meshId]->getFieldOnMeshAtLevelWithPfl(type,m,pfl,glob,nasc); + ret->setName(nasc.getName().c_str()); + return ret.retn(); } +//= MEDFileField1TSWithoutSDA + /*! - * Returns a pointer to the underground DataArrayDouble instance. So the - * caller should not decrRef() it. This method allows for a direct access to the field - * values. This method is quite unusable if there is more than a nodal field or a cell - * field on single geometric cell type. - * \return DataArrayDouble * - the pointer to the field values array. + * Throws if a given value is not a valid (non-extended) relative dimension. + * \param [in] meshDimRelToMax - the relative dimension value. + * \throw If \a meshDimRelToMax > 0. */ -DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArray() const throw(INTERP_KERNEL::Exception) +void MEDFileField1TSWithoutSDA::CheckMeshDimRel(int meshDimRelToMax) { - const DataArrayDouble *ret=_arr; - if(ret) - return const_cast(ret); - else - return 0; + if(meshDimRelToMax>0) + throw INTERP_KERNEL::Exception("CheckMeshDimRel : This is a meshDimRel not a meshDimRelExt ! So value should be <=0 !"); } /*! - * Returns a pointer to the underground DataArrayDouble instance and a - * sequence describing parameters of a support of each part of \a this field. The - * caller should not decrRef() the returned DataArrayDouble. This method allows for a - * direct access to the field values. This method is intended for the field lying on one - * mesh only. - * \param [in,out] entries - the sequence describing parameters of a support of each - * part of \a this field. Each item of this sequence consists of two parts. The - * first part describes a type of mesh entity and an id of discretization of a - * current field part. The second part describes a range of values [begin,end) - * within the returned array relating to the current field part. - * \return DataArrayDouble * - the pointer to the field values array. - * \throw If the number of underlying meshes is not equal to 1. - * \throw If no field values are available. - * \sa getUndergroundDataArray() + * Checks if elements of a given mesh are in the order suitable for writing + * to the MED file. If this is not so, an exception is thrown. In a case of success, returns a + * vector describing types of elements and their number. + * \param [in] mesh - the mesh to check. + * \return std::vector - a vector holding for each element type (1) item of + * INTERP_KERNEL::NormalizedCellType, (2) number of elements, (3) -1. + * These values are in full-interlace mode. + * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. */ -DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const throw(INTERP_KERNEL::Exception) -{ - if(_field_per_mesh.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !"); - if(_field_per_mesh[0]==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !"); - return _field_per_mesh[0]->getUndergroundDataArrayExt(entries); -} - -MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA(const char *fieldName, int csit, int fieldtype, int iteration, int order, - const std::vector& infos):_iteration(iteration),_order(order),_csit(csit),_field_type(fieldtype) -{ - DataArrayDouble *arr=getOrCreateAndGetArray(); - arr->setName(fieldName); - arr->setInfoAndChangeNbOfCompo(infos); -} - -MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA():_csit(-1),_field_type(-1) -{ -} - -int MEDFileField1TSWithoutSDA::addNewEntryIfNecessary(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception) +std::vector MEDFileField1TSWithoutSDA::CheckSBTMesh(const MEDCouplingMesh *mesh) { - std::string tmp(mesh->getName()); - if(tmp.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::addNewEntryIfNecessary : empty mesh name ! unsupported by MED file !"); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin(); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::CheckSBTMesh : input mesh is NULL !"); + std::set geoTypes=mesh->getAllGeoTypes(); + int nbOfTypes=geoTypes.size(); + std::vector code(3*nbOfTypes); + MEDCouplingAutoRefCountObjectPtr arr1=DataArrayInt::New(); + arr1->alloc(nbOfTypes,1); + int *arrPtr=arr1->getPointer(); + std::set::const_iterator it=geoTypes.begin(); + for(int i=0;i arr2=arr1->checkAndPreparePermutation(); + const int *arrPtr2=arr2->getConstPointer(); int i=0; - for(;it!=_field_per_mesh.end();it++,i++) + for(it=geoTypes.begin();it!=geoTypes.end();it++,i++) { - if((*it)->getMeshName()==tmp) - return i; + int pos=arrPtr2[i]; + int nbCells=mesh->getNumberOfCellsWithType(*it); + code[3*pos]=(int)(*it); + code[3*pos+1]=nbCells; + code[3*pos+2]=-1;//no profiles } - int sz=_field_per_mesh.size(); - _field_per_mesh.resize(sz+1); - _field_per_mesh[sz]=MEDFileFieldPerMesh::New(this,mesh); - return sz; + std::vector idsPerType;//no profiles + DataArrayInt *da=mesh->checkTypeConsistencyAndContig(code,idsPerType); + if(da) + { + da->decrRef(); + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::CheckSBTMesh : underlying mesh is not sorted by type as MED file expects !"); + } + return code; } -/*! - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - */ -int MEDFileField1TSWithoutSDA::getMeshIdFromMeshName(const char *mName) const throw(INTERP_KERNEL::Exception) +MEDFileField1TSWithoutSDA *MEDFileField1TSWithoutSDA::New(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos) { - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getMeshIdFromMeshName : No field set !"); - if(mName==0) + return new MEDFileField1TSWithoutSDA(fieldName,csit,iteration,order,infos); +} + +/*! + * Returns all attributes and values of parts of \a this field lying on a given mesh. + * Each part differs from other ones by a type of supporting mesh entity. The _i_-th + * item of every of returned sequences refers to the _i_-th part of \a this field. + * Thus all sequences returned by this method are of the same length equal to number + * of different types of supporting entities.
+ * A field part can include sub-parts with several different spatial discretizations, + * \ref MEDCoupling::ON_CELLS "ON_CELLS" and \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" + * for example. Hence, some of the returned sequences contains nested sequences, and an item + * of a nested sequence corresponds to a type of spatial discretization.
+ * This method allows for iteration over MEDFile DataStructure with a reduced overhead. + * The overhead is due to selecting values into new instances of DataArrayDouble. + * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid + * for the case with only one underlying mesh. (Actually, the number of meshes is + * not checked if \a mname == \c NULL). + * \param [in,out] types - a sequence of types of underlying mesh entities. A type per + * a field part is returned. + * \param [in,out] typesF - a sequence of sequences of types of spatial discretizations. + * A field part can include sub-parts with several different spatial discretizations, + * \ref MEDCoupling::ON_CELLS "ON_CELLS" and + * \ref MEDCoupling::ON_GAUSS_PT "ON_GAUSS_PT" for example. + * This sequence is of the same length as \a types. + * \param [in,out] pfls - a sequence returning a profile name per each type of spatial + * discretization. A profile name can be empty. + * Length of this and of nested sequences is the same as that of \a typesF. + * \param [in,out] locs - a sequence returning a localization name per each type of spatial + * discretization. A localization name can be empty. + * Length of this and of nested sequences is the same as that of \a typesF. + * \return std::vector< std::vector > - a sequence holding arrays of values + * per each type of spatial discretization within one mesh entity type. + * The caller is to delete each DataArrayDouble using decrRef() as it is no more needed. + * Length of this and of nested sequences is the same as that of \a typesF. + * \throw If no field is lying on \a mname. + */ +std::vector< std::vector > MEDFileField1TSWithoutSDA::getFieldSplitedByType2(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const +{ + int meshId=0; + if(!mname.empty()) + meshId=getMeshIdFromMeshName(mname); + else + if(_field_per_mesh.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldSplitedByType : This is empty !"); + std::vector< std::vector< std::pair > > ret0=_field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); + int nbOfRet=ret0.size(); + std::vector< std::vector > ret(nbOfRet); + for(int i=0;i >& p=ret0[i]; + int nbOfRet1=p.size(); + ret[i].resize(nbOfRet1); + for(int j=0;jselectByTupleId2(p[j].first,p[j].second,1); + ret[i][j]=tmp; + } + } + return ret; +} + +/*! + * Returns a pointer to the underground DataArrayDouble instance. So the + * caller should not decrRef() it. This method allows for a direct access to the field + * values. This method is quite unusable if there is more than a nodal field or a cell + * field on single geometric cell type. + * \return DataArrayDouble * - the pointer to the field values array. + */ +DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayDouble() const +{ + const DataArrayDouble *ret=_arr; + if(ret) + return const_cast(ret); + else return 0; - std::string mName2(mName); - int ret=0; - std::vector msg; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++,ret++) - if(mName2==(*it)->getMeshName()) - return ret; - else - msg.push_back((*it)->getMeshName()); - std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getMeshIdFromMeshName : No such mesh \"" << mName2 << "\" as underlying mesh of field \"" << getName() << "\" !\n"; - oss << "Possible meshes are : "; - for(std::vector::const_iterator it2=msg.begin();it2!=msg.end();it2++) - oss << "\"" << (*it2) << "\" "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +const char *MEDFileField1TSWithoutSDA::getTypeStr() const +{ + return TYPE_STR; +} + +MEDFileIntField1TSWithoutSDA *MEDFileField1TSWithoutSDA::convertToInt() const +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TSWithoutSDA); + ret->MEDFileAnyTypeField1TSWithoutSDA::operator =(*this); + ret->deepCpyLeavesFrom(*this); + const DataArrayDouble *arr(_arr); + if(arr) + { + MEDCouplingAutoRefCountObjectPtr arr2(arr->convertToIntArr()); + ret->setArray(arr2); + } + return ret.retn(); } /*! - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. + * Returns a pointer to the underground DataArrayDouble instance. So the + * caller should not decrRef() it. This method allows for a direct access to the field + * values. This method is quite unusable if there is more than a nodal field or a cell + * field on single geometric cell type. + * \return DataArrayDouble * - the pointer to the field values array. */ -MEDFileFieldPerMeshPerTypePerDisc *MEDFileField1TSWithoutSDA::getLeafGivenMeshAndTypeAndLocId(const char *mName, INTERP_KERNEL::NormalizedCellType typ, int locId) throw(INTERP_KERNEL::Exception) +DataArray *MEDFileField1TSWithoutSDA::getUndergroundDataArray() const { - int mid=getMeshIdFromMeshName(mName); - return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); + return getUndergroundDataArrayDouble(); } /*! - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. + * Returns a pointer to the underground DataArrayDouble instance and a + * sequence describing parameters of a support of each part of \a this field. The + * caller should not decrRef() the returned DataArrayDouble. This method allows for a + * direct access to the field values. This method is intended for the field lying on one + * mesh only. + * \param [in,out] entries - the sequence describing parameters of a support of each + * part of \a this field. Each item of this sequence consists of two parts. The + * first part describes a type of mesh entity and an id of discretization of a + * current field part. The second part describes a range of values [begin,end) + * within the returned array relating to the current field part. + * \return DataArrayDouble * - the pointer to the field values array. + * \throw If the number of underlying meshes is not equal to 1. + * \throw If no field values are available. + * \sa getUndergroundDataArray() */ -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileField1TSWithoutSDA::getLeafGivenMeshAndTypeAndLocId(const char *mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const throw(INTERP_KERNEL::Exception) +DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayDoubleExt(std::vector< std::pair,std::pair > >& entries) const { - int mid=getMeshIdFromMeshName(mName); - return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); + if(_field_per_mesh.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !"); + if(_field_per_mesh[0]==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !"); + _field_per_mesh[0]->getUndergroundDataArrayExt(entries); + return getUndergroundDataArrayDouble(); } -std::size_t MEDFileField1TSWithoutSDA::getHeapMemorySize() const +/*! + * Returns a pointer to the underground DataArrayDouble instance and a + * sequence describing parameters of a support of each part of \a this field. The + * caller should not decrRef() the returned DataArrayDouble. This method allows for a + * direct access to the field values. This method is intended for the field lying on one + * mesh only. + * \param [in,out] entries - the sequence describing parameters of a support of each + * part of \a this field. Each item of this sequence consists of two parts. The + * first part describes a type of mesh entity and an id of discretization of a + * current field part. The second part describes a range of values [begin,end) + * within the returned array relating to the current field part. + * \return DataArrayDouble * - the pointer to the field values array. + * \throw If the number of underlying meshes is not equal to 1. + * \throw If no field values are available. + * \sa getUndergroundDataArray() + */ +DataArray *MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const { - std::size_t ret=_dt_unit.capacity()+_field_per_mesh.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh >); - if((const DataArrayDouble *)_arr) - ret+=_arr->getHeapMemorySize(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - ret+=(*it)->getHeapMemorySize(); - return ret; + return getUndergroundDataArrayDoubleExt(entries); +} + +MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos):MEDFileAnyTypeField1TSWithoutSDA(fieldName,csit,iteration,order) +{ + DataArrayDouble *arr(getOrCreateAndGetArrayDouble()); + arr->setInfoAndChangeNbOfCompo(infos); +} + +MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA() +{ +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileField1TSWithoutSDA::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TSWithoutSDA(*this)); + ret->deepCpyLeavesFrom(*this); + return ret.retn(); } -MEDFileField1TSWithoutSDA *MEDFileField1TSWithoutSDA::deepCpy() const throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeField1TSWithoutSDA *MEDFileField1TSWithoutSDA::deepCpy() const { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileField1TSWithoutSDA(*this); + MEDCouplingAutoRefCountObjectPtr ret=static_cast(shallowCpy()); if((const DataArrayDouble *)_arr) ret->_arr=_arr->deepCpy(); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++,i++) + return ret.retn(); +} + +void MEDFileField1TSWithoutSDA::setArray(DataArray *arr) +{ + if(!arr) { - if((const MEDFileFieldPerMesh *)*it) - ret->_field_per_mesh[i]=(*it)->deepCpy((MEDFileField1TSWithoutSDA *)ret); + _nb_of_tuples_to_be_allocated=-1; + _arr=0; + return ; } - return ret.retn(); + DataArrayDouble *arrC=dynamic_cast(arr); + if(!arrC) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::setArray : the input not null array is not of type DataArrayDouble !"); + else + _nb_of_tuples_to_be_allocated=-3; + arrC->incrRef(); + _arr=arrC; +} + +DataArray *MEDFileField1TSWithoutSDA::createNewEmptyDataArrayInstance() const +{ + return DataArrayDouble::New(); } -DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() +DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArrayDouble() { DataArrayDouble *ret=_arr; if(ret) @@ -4359,7 +5208,12 @@ DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() return _arr; } -const DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() const +DataArray *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() +{ + return getOrCreateAndGetArrayDouble(); +} + +const DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArrayDouble() const { const DataArrayDouble *ret=_arr; if(ret) @@ -4369,182 +5223,278 @@ const DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() const return ret2; } -/*! - * Returns a new instance of MEDFileField1TS holding data of the first time step of - * the first field that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - */ -MEDFileField1TS *MEDFileField1TS::New(const char *fileName) throw(INTERP_KERNEL::Exception) +const DataArray *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() const { - return new MEDFileField1TS(fileName); + return getOrCreateAndGetArrayDouble(); } -/*! - * Returns a new instance of MEDFileField1TS holding data of the first time step of - * a given field that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - */ -MEDFileField1TS *MEDFileField1TS::New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) -{ - return new MEDFileField1TS(fileName,fieldName); -} +//= MEDFileIntField1TSWithoutSDA -/*! - * Returns a new instance of MEDFileField1TS holding data of a given time step of - * a given field that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - * \throw If the required time step is missing from the file. - */ -MEDFileField1TS *MEDFileField1TS::New(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) +MEDFileIntField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::New(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos) { - return new MEDFileField1TS(fileName,fieldName,iteration,order); + return new MEDFileIntField1TSWithoutSDA(fieldName,csit,iteration,order,infos); } -/*! - * Returns a new instance of MEDFileField1TS holding either deep or shallow copy - * of a given MEDFileField1TSWithoutSDA. - * \warning this is a shallow copy constructor - * \param [in] other - a MEDFileField1TSWithoutSDA to copy. - * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. - * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) +MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA() { - return new MEDFileField1TS(other,shallowCopyOfContent); } -/*! - * Returns a new empty instance of MEDFileField1TS. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileField1TS *MEDFileField1TS::New() +MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, + const std::vector& infos):MEDFileAnyTypeField1TSWithoutSDA(fieldName,csit,iteration,order) { - return new MEDFileField1TS; + DataArrayInt *arr(getOrCreateAndGetArrayInt()); + arr->setInfoAndChangeNbOfCompo(infos); } -/*! - * Returns a string describing \a this field. This string is outputted - * by \c print Python command. - */ -std::string MEDFileField1TS::simpleRepr() const +const char *MEDFileIntField1TSWithoutSDA::getTypeStr() const { - std::ostringstream oss; - _content->simpleRepr(0,oss,-1); - MEDFileFieldGlobsReal::simpleRepr(oss); - return oss.str(); + return TYPE_STR; } -void MEDFileField1TS::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) +MEDFileField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::convertToDouble() const { - int nbComp=getNumberOfComponents(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - for(int i=0;i ret(new MEDFileField1TSWithoutSDA); + ret->MEDFileAnyTypeField1TSWithoutSDA::operator =(*this); + ret->deepCpyLeavesFrom(*this); + const DataArrayInt *arr(_arr); + if(arr) { - std::string info=getInfo()[i]; - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,_too_long_str); - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,_too_long_str); + MEDCouplingAutoRefCountObjectPtr arr2(arr->convertToDblArr()); + ret->setArray(arr2); } - if(getName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::write : MED file does not accept field with empty name !"); - MEDfieldCr(fid,getName().c_str(),MED_FLOAT64,nbComp,comp,unit,getDtUnit().c_str(),getMeshName().c_str()); - writeGlobals(fid,*this); - _content->writeLL(fid,*this); + return ret.retn(); } /*! - * Writes \a this field into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the field name is not set. - * \throw If no field data is set. - * \throw If \a mode == 1 and the same data is present in an existing file. + * Returns a pointer to the underground DataArrayInt instance. So the + * caller should not decrRef() it. This method allows for a direct access to the field + * values. This method is quite unusable if there is more than a nodal field or a cell + * field on single geometric cell type. + * \return DataArrayInt * - the pointer to the field values array. */ -void MEDFileField1TS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception) +DataArray *MEDFileIntField1TSWithoutSDA::getUndergroundDataArray() const { - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod); - writeLL(fid); + return getUndergroundDataArrayInt(); } -MEDFileField1TS::MEDFileField1TS(const char *fileName) throw(INTERP_KERNEL::Exception) -try:MEDFileFieldGlobsReal(fileName) +/*! + * Returns a pointer to the underground DataArrayInt instance. So the + * caller should not decrRef() it. This method allows for a direct access to the field + * values. This method is quite unusable if there is more than a nodal field or a cell + * field on single geometric cell type. + * \return DataArrayInt * - the pointer to the field values array. + */ +DataArrayInt *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayInt() const { - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_field_type typcha; - // - int nbFields=MEDnField(fid); - if(nbFields<1) - { - std::ostringstream oss; oss << "MEDFileField1TS(fileName) : no field present in file \'" << fileName << "\' !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int ncomp=MEDfieldnComponent(fid,1); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localMesh; - int nbOfStep; - MEDfieldInfo(fid,1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep); - std::string fieldName(nomcha); - if(nbOfStep<1) + const DataArrayInt *ret=_arr; + if(ret) + return const_cast(ret); + else + return 0; +} + +/*! + * Returns a pointer to the underground DataArrayInt instance and a + * sequence describing parameters of a support of each part of \a this field. The + * caller should not decrRef() the returned DataArrayInt. This method allows for a + * direct access to the field values. This method is intended for the field lying on one + * mesh only. + * \param [in,out] entries - the sequence describing parameters of a support of each + * part of \a this field. Each item of this sequence consists of two parts. The + * first part describes a type of mesh entity and an id of discretization of a + * current field part. The second part describes a range of values [begin,end) + * within the returned array relating to the current field part. + * \return DataArrayInt * - the pointer to the field values array. + * \throw If the number of underlying meshes is not equal to 1. + * \throw If no field values are available. + * \sa getUndergroundDataArray() + */ +DataArray *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const +{ + return getUndergroundDataArrayIntExt(entries); +} + +/*! + * Returns a pointer to the underground DataArrayInt instance and a + * sequence describing parameters of a support of each part of \a this field. The + * caller should not decrRef() the returned DataArrayInt. This method allows for a + * direct access to the field values. This method is intended for the field lying on one + * mesh only. + * \param [in,out] entries - the sequence describing parameters of a support of each + * part of \a this field. Each item of this sequence consists of two parts. The + * first part describes a type of mesh entity and an id of discretization of a + * current field part. The second part describes a range of values [begin,end) + * within the returned array relating to the current field part. + * \return DataArrayInt * - the pointer to the field values array. + * \throw If the number of underlying meshes is not equal to 1. + * \throw If no field values are available. + * \sa getUndergroundDataArray() + */ +DataArrayInt *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayIntExt(std::vector< std::pair,std::pair > >& entries) const +{ + if(_field_per_mesh.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !"); + if(_field_per_mesh[0]==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !"); + _field_per_mesh[0]->getUndergroundDataArrayExt(entries); + return getUndergroundDataArrayInt(); +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TSWithoutSDA(*this)); + ret->deepCpyLeavesFrom(*this); + return ret.retn(); +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr ret=static_cast(shallowCpy()); + if((const DataArrayInt *)_arr) + ret->_arr=_arr->deepCpy(); + return ret.retn(); +} + +void MEDFileIntField1TSWithoutSDA::setArray(DataArray *arr) +{ + if(!arr) { - std::ostringstream oss; oss << "MEDFileField1TS(fileName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but there is no time steps on it !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + _nb_of_tuples_to_be_allocated=-1; + _arr=0; + return ; } - std::vector infos(ncomp); - for(int j=0;j()); - _content->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); + DataArrayInt *arrC=dynamic_cast(arr); + if(!arrC) + throw INTERP_KERNEL::Exception("MEDFileIntField1TSWithoutSDA::setArray : the input not null array is not of type DataArrayInt !"); + else + _nb_of_tuples_to_be_allocated=-3; + arrC->incrRef(); + _arr=arrC; +} + +DataArray *MEDFileIntField1TSWithoutSDA::createNewEmptyDataArrayInstance() const +{ + return DataArrayInt::New(); +} + +DataArrayInt *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArrayInt() +{ + DataArrayInt *ret=_arr; + if(ret) + return ret; + _arr=DataArrayInt::New(); + return _arr; +} + +DataArray *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArray() +{ + return getOrCreateAndGetArrayInt(); +} + +const DataArrayInt *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArrayInt() const +{ + const DataArrayInt *ret=_arr; + if(ret) + return ret; + DataArrayInt *ret2=DataArrayInt::New(); + const_cast(this)->_arr=DataArrayInt::New(); + return ret2; +} + +const DataArray *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArray() const +{ + return getOrCreateAndGetArrayInt(); +} + +MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS() +{ +} + +//= MEDFileAnyTypeField1TS + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +{ + med_field_type typcha; + // + std::vector infos; + std::string dtunit,fieldName; + LocateField2(fid,fileName,0,true,fieldName,typcha,infos,dtunit); + MEDCouplingAutoRefCountObjectPtr ret; + switch(typcha) + { + case MED_FLOAT64: + { + ret=MEDFileField1TSWithoutSDA::New(fieldName.c_str(),-1,-1/*iteration*/,-1/*order*/,std::vector()); + break; + } + case MED_INT32: + { + ret=MEDFileIntField1TSWithoutSDA::New(fieldName.c_str(),-1,-1/*iteration*/,-1/*order*/,std::vector()); + break; + } + default: + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of the first field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setDtUnit(dtunit.c_str()); + ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); // med_int numdt,numit; med_float dt; - MEDfieldComputingStepInfo(fid,fieldName.c_str(),1,&numdt,&numit,&dt); - _content->setTime(numdt,numit,dt); - _content->_csit=1; - _content->_field_type=MEDFileUtilities::TraduceFieldType(typcha); - _content->finishLoading(fid); - // + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,fieldName.c_str(),1,&numdt,&numit,&dt)); + ret->setTime(numdt,numit,dt); + ret->_csit=1; + if(loadAll) + ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + else + ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + return ret.retn(); +} + +MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileFieldGlobsReal(fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + _content=BuildContentFrom(fid,fileName,loadAll,ms); loadGlobals(fid); } catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} -MEDFileField1TS::MEDFileField1TS(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) -try:MEDFileFieldGlobsReal(fileName),_content(MEDFileField1TSWithoutSDA::New(fieldName,-1,-1,-1/*iteration*/,-1/*order*/,std::vector())) +MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) { - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); med_field_type typcha; - int nbSteps=locateField(fid,fileName,fieldName,typcha); + std::vector infos; + std::string dtunit; + int iii=-1; + int nbSteps=LocateField(fid,fileName,fieldName,iii,typcha,infos,dtunit); + MEDCouplingAutoRefCountObjectPtr ret; + switch(typcha) + { + case MED_FLOAT64: + { + ret=MEDFileField1TSWithoutSDA::New(fieldName,-1,-1/*iteration*/,-1/*order*/,std::vector()); + break; + } + case MED_INT32: + { + ret=MEDFileIntField1TSWithoutSDA::New(fieldName,-1,-1/*iteration*/,-1/*order*/,std::vector()); + break; + } + default: + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setDtUnit(dtunit.c_str()); + ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); + // if(nbSteps<1) { std::ostringstream oss; oss << "MEDFileField1TS(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but there is no time steps on it !"; @@ -4553,38 +5503,120 @@ try:MEDFileFieldGlobsReal(fileName),_content(MEDFileField1TSWithoutSDA::New(fiel // med_int numdt,numit; med_float dt; - MEDfieldComputingStepInfo(fid,fieldName,1,&numdt,&numit,&dt); - _content->setTime(numdt,numit,dt); - _content->_csit=1; - _content->_field_type=MEDFileUtilities::TraduceFieldType(typcha); - _content->finishLoading(fid); - // + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,fieldName.c_str(),1,&numdt,&numit,&dt)); + ret->setTime(numdt,numit,dt); + ret->_csit=1; + if(loadAll) + ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + else + ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + return ret.retn(); +} + +MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileFieldGlobsReal(fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + _content=BuildContentFrom(fid,fileName,fieldName,loadAll,ms); loadGlobals(fid); } catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::BuildNewInstanceFromContent(MEDFileAnyTypeField1TSWithoutSDA *c, const std::string& fileName) +{ + if(!c) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::BuildNewInstanceFromContent : empty content in input : unable to build a new instance !"); + if(dynamic_cast(c)) + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileField1TS::New(); + ret->setFileName(fileName); + ret->_content=c; c->incrRef(); + return ret.retn(); + } + if(dynamic_cast(c)) + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileIntField1TS::New(); + ret->setFileName(fileName); + ret->_content=c; c->incrRef(); + return ret.retn(); + } + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::BuildNewInstanceFromContent : internal error ! a content of type different from FLOAT64 and INT32 has been built but not intercepted !"); +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, bool loadAll) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,loadAll,0); + MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); + ret->loadGlobals(fid); + return ret.retn(); +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,fieldName,loadAll,0); + MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); + ret->loadGlobals(fid); + return ret.retn(); +} -MEDFileField1TS::MEDFileField1TS(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) -try:MEDFileFieldGlobsReal(fileName),_content(MEDFileField1TSWithoutSDA::New(fieldName,-1,-1,iteration,order,std::vector())) +MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) { MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,fieldName,iteration,order,loadAll,0); + MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); + ret->loadGlobals(fid); + return ret.retn(); +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) +{ med_field_type typcha; - int nbOfStep2=locateField(fid,fileName,fieldName,typcha); + std::vector infos; + std::string dtunit; + int iii=-1; + int nbOfStep2=LocateField(fid,fileName,fieldName,iii,typcha,infos,dtunit); + MEDCouplingAutoRefCountObjectPtr ret; + switch(typcha) + { + case MED_FLOAT64: + { + ret=MEDFileField1TSWithoutSDA::New(fieldName,-1,iteration,order,std::vector()); + break; + } + case MED_INT32: + { + ret=MEDFileIntField1TSWithoutSDA::New(fieldName,-1,iteration,order,std::vector()); + break; + } + default: + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName,fieldName,iteration,order) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setDtUnit(dtunit.c_str()); + ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); + // bool found=false; std::vector< std::pair > dtits(nbOfStep2); for(int i=0;i_csit=i+1; - _content->_field_type=MEDFileUtilities::TraduceFieldType(typcha); + ret->_csit=i+1; } else dtits[i]=std::pair(numdt,numit); @@ -4596,34 +5628,72 @@ try:MEDFileFieldGlobsReal(fileName),_content(MEDFileField1TSWithoutSDA::New(fiel oss << "(" << (*iter).first << "," << (*iter).second << "), "; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - _content->finishLoading(fid); - // + if(loadAll) + ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + else + ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + return ret.retn(); +} + +MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileFieldGlobsReal(fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + _content=BuildContentFrom(fid,fileName.c_str(),fieldName.c_str(),iteration,order,loadAll,ms); loadGlobals(fid); } catch(INTERP_KERNEL::Exception& e) - { +{ throw e; - } +} /*! + * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * * \warning this is a shallow copy constructor */ -MEDFileField1TS::MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) +MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const MEDFileAnyTypeField1TSWithoutSDA& other, bool shallowCopyOfContent) { if(!shallowCopyOfContent) { - const MEDFileField1TSWithoutSDA *otherPtr(&other); + const MEDFileAnyTypeField1TSWithoutSDA *otherPtr(&other); otherPtr->incrRef(); - _content=const_cast(otherPtr); + _content=const_cast(otherPtr); } else { - _content=new MEDFileField1TSWithoutSDA(other); + _content=other.shallowCpy(); } } -MEDFileField1TS::MEDFileField1TS():_content(new MEDFileField1TSWithoutSDA) +int MEDFileAnyTypeField1TS::LocateField2(med_idt fid, const std::string& fileName, int fieldIdCFormat, bool checkFieldId, std::string& fieldName, med_field_type& typcha, std::vector& infos, std::string& dtunitOut) { + if(checkFieldId) + { + int nbFields=MEDnField(fid); + if(fieldIdCFormat>=nbFields) + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::LocateField2(fileName) : in file \'" << fileName << "\' number of fields is " << nbFields << " ! Trying to request for id " << fieldIdCFormat << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + int ncomp(MEDfieldnComponent(fid,fieldIdCFormat+1)); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localMesh; + int nbOfStep; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,fieldIdCFormat+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep)); + fieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE); + dtunitOut=MEDLoaderBase::buildStringFromFortran(dtunit,MED_LNAME_SIZE); + infos.clear(); infos.resize(ncomp); + for(int j=0;j& infos, std::string& dtunitOut) { int nbFields=MEDnField(fid); bool found=false; @@ -4640,27 +5710,12 @@ int MEDFileField1TS::locateField(med_idt fid, const char *fileName, const char * int nbOfStep2=-1; for(int i=0;i comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localMesh; - int nbOfStep; - MEDfieldInfo(fid,i+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep); - std::string tmp(nomcha); + std::string tmp; + nbOfStep2=LocateField2(fid,fileName,i,false,tmp,typcha,infos,dtunitOut); fns[i]=tmp; found=(tmp==fieldName); if(found) - { - nbOfStep2=nbOfStep; - std::string mname=MEDLoaderBase::buildStringFromFortran(nomMaa,MED_NAME_SIZE); - std::vector infos(ncomp); - for(int j=0;jgetOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); - } + posCFormat=i; } if(!found) { @@ -4673,1096 +5728,3196 @@ int MEDFileField1TS::locateField(med_idt fid, const char *fileName, const char * } /*! - * This method returns all profiles whose name is non empty used. - * \b WARNING If profile is used several times it will be reported \b only \b once. - * To get non empty name profiles as time as they appear in \b this call MEDFileField1TS::getPflsReallyUsedMulti instead. + * This method as MEDFileField1TSW::setLocNameOnLeaf, is dedicated for advanced user that a want a very fine control on their data structure + * without overhead. This method can be called only regarding information returned by MEDFileField1TSWithoutSDA::getFieldSplitedByType or MEDFileField1TSWithoutSDA::getFieldSplitedByType2. + * This method changes the attribute (here it's profile name) of the leaf datastructure (MEDFileFieldPerMeshPerTypePerDisc instance). + * It is the responsability of the caller to invoke MEDFileFieldGlobs::appendProfile or MEDFileFieldGlobs::getProfile + * to keep a valid instance. + * If \b this do not have any leaf that correspond to the request of the input parameter (\b mName, \b typ, \b locId) an INTERP_KERNEL::Exception will be thrown. + * If \b newPflName profile name does not already exist the profile with old name will be renamed with name \b newPflName. + * If \b newPflName already exists and that \b forceRenameOnGlob is false (the default) an INTERP_KERNEL::Exception will be thrown to avoid big confusion. In this case the called should rename before the profile name with name \b newPflName. + * + * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. + * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. + * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of + * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. + * \param [in] newLocName is the new localization name. + * \param [in] forceRenameOnGlob specifies the behaviour in case of profile \b newPflName already exists. If true, the renaming is done without check. It can lead to major bug. + * If false, an exception will be thrown to force user to change previously the name of the profile with name \b newPflName */ -std::vector MEDFileField1TS::getPflsReallyUsed() const +void MEDFileAnyTypeField1TS::setProfileNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob) { - return _content->getPflsReallyUsed2(); + MEDFileFieldPerMeshPerTypePerDisc *disc=getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); + std::string oldPflName=disc->getProfile(); + std::vector vv=getPflsReallyUsedMulti(); + int nbOfOcc=std::count(vv.begin(),vv.end(),oldPflName); + if(forceRenameOnGlob || (!existsPfl(newPflName) && nbOfOcc==1)) + { + disc->setProfile(newPflName); + DataArrayInt *pfl=getProfile(oldPflName.c_str()); + pfl->setName(newPflName); + } + else + { + std::ostringstream oss; oss << "MEDFileField1TS::setProfileNameOnLeaf : Profile \"" << newPflName << "\" already exists or referenced more than one !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } } /*! - * This method returns all localizations whose name is non empty used. - * \b WARNING If localization is used several times it will be reported \b only \b once. - */ -std::vector MEDFileField1TS::getLocsReallyUsed() const -{ - return _content->getLocsReallyUsed2(); + * This method as MEDFileField1TSW::setProfileNameOnLeaf, is dedicated for advanced user that a want a very fine control on their data structure + * without overhead. This method can be called only regarding information returned by MEDFileField1TSWithoutSDA::getFieldSplitedByType or MEDFileField1TSWithoutSDA::getFieldSplitedByType2. + * This method changes the attribute (here it's localization name) of the leaf datastructure (MEDFileFieldPerMeshPerTypePerDisc instance). + * It is the responsability of the caller to invoke MEDFileFieldGlobs::appendProfile or MEDFileFieldGlobs::getProfile + * to keep a valid instance. + * If \b this do not have any leaf that correspond to the request of the input parameter (\b mName, \b typ, \b locId) an INTERP_KERNEL::Exception will be thrown. + * This method is an extension of MEDFileField1TSWithoutSDA::setProfileNameOnLeafExt method because it performs a modification of global info. + * If \b newLocName profile name does not already exist the localization with old name will be renamed with name \b newLocName. + * If \b newLocName already exists an INTERP_KERNEL::Exception will be thrown to avoid big confusion. In this case the called should rename before the profile name with name \b newLocName. + * + * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. + * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. + * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of + * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. + * \param [in] newLocName is the new localization name. + * \param [in] forceRenameOnGlob specifies the behaviour in case of profile \b newLocName already exists. If true, the renaming is done without check. It can lead to major bug. + * If false, an exception will be thrown to force user to change previously the name of the profile with name \b newLocName + */ +void MEDFileAnyTypeField1TS::setLocNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob) +{ + MEDFileFieldPerMeshPerTypePerDisc *disc=getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); + std::string oldLocName=disc->getLocalization(); + std::vector vv=getLocsReallyUsedMulti(); + int nbOfOcc=std::count(vv.begin(),vv.end(),oldLocName); + if(forceRenameOnGlob || (!existsLoc(newLocName) && nbOfOcc==1)) + { + disc->setLocalization(newLocName); + MEDFileFieldLoc& loc=getLocalization(oldLocName.c_str()); + loc.setName(newLocName); + } + else + { + std::ostringstream oss; oss << "MEDFileField1TS::setLocNameOnLeaf : Localization \"" << newLocName << "\" already exists or referenced more than one !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::contentNotNullBase() +{ + MEDFileAnyTypeField1TSWithoutSDA *ret=_content; + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS : content is expected to be not null !"); + return ret; +} + +const MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::contentNotNullBase() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *ret=_content; + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS : const content is expected to be not null !"); + return ret; } /*! - * This method returns all profiles whose name is non empty used. - * \b WARNING contrary to MEDFileField1TS::getPflsReallyUsed, if profile is used several times it will be reported as time as it appears. + * Writes \a this field into a MED file specified by its name. + * \param [in] fileName - the MED file name. + * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. + * - 2 - erase; an existing file is removed. + * - 1 - append; same data should not be present in an existing file. + * - 0 - overwrite; same data present in an existing file is overwritten. + * \throw If the field name is not set. + * \throw If no field data is set. + * \throw If \a mode == 1 and the same data is present in an existing file. */ -std::vector MEDFileField1TS::getPflsReallyUsedMulti() const +void MEDFileAnyTypeField1TS::write(const std::string& fileName, int mode) const { - return _content->getPflsReallyUsedMulti2(); + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + writeLL(fid); } /*! - * This method returns all localizations whose name is non empty used. - * \b WARNING contrary to MEDFileField1TS::getLocsReallyUsed if localization is used several times it will be reported as time as it appears. + * This method alloc the arrays and load potentially huge arrays contained in this field. + * This method should be called when a MEDFileAnyTypeField1TS::New constructor has been with false as the last parameter. + * This method can be also called to refresh or reinit values from a file. + * + * \throw If the fileName is not set or points to a non readable MED file. + * \sa MEDFileAnyTypeField1TS::loadArraysIfNecessary */ -std::vector MEDFileField1TS::getLocsReallyUsedMulti() const +void MEDFileAnyTypeField1TS::loadArrays() { - return _content->getLocsReallyUsedMulti2(); + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::loadArrays : the structure does not come from a file !"); + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + contentNotNullBase()->loadBigArraysRecursively(fid,*contentNotNullBase()); } -void MEDFileField1TS::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +/*! + * This method behaves as MEDFileAnyTypeField1TS::loadArrays does, the first call, if \a this was built using a file without loading big arrays. + * But once data loaded once, this method does nothing. Contrary to MEDFileAnyTypeField1TS::loadArrays and MEDFileAnyTypeField1TS::unloadArrays + * this method does not throw if \a this does not come from file read. + * + * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::unloadArrays + */ +void MEDFileAnyTypeField1TS::loadArraysIfNecessary() { - _content->changePflsRefsNamesGen2(mapOfModif); + if(!getFileName().empty()) + { + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + contentNotNullBase()->loadBigArraysRecursivelyIfNecessary(fid,*contentNotNullBase()); + } } -void MEDFileField1TS::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +/*! + * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. + * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. + * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss instead. + * + * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::loadArraysIfNecessary, MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss + */ +void MEDFileAnyTypeField1TS::unloadArrays() { - _content->changeLocsRefsNamesGen2(mapOfModif); + contentNotNullBase()->unloadArrays(); } /*! - * Returns a new MEDCouplingFieldDouble of a given type lying on - * mesh entities of a given dimension of the first mesh in MED file. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If \a this field has not been constructed via file reading. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldOnMeshAtLevel() + * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. + * This method is the symetrical method of MEDFileAnyTypeField1TS::loadArraysIfNecessary. + * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. + * + * \sa MEDFileAnyTypeField1TS::loadArraysIfNecessary */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss() { - if(getFileName2().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); - return _content->getFieldAtLevel(type,meshDimRelToMax,0,renumPol,this); + if(!getFileName().empty()) + contentNotNullBase()->unloadArrays(); +} + +void MEDFileAnyTypeField1TS::writeLL(med_idt fid) const +{ + int nbComp=getNumberOfComponents(); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); + for(int i=0;iwriteLL(fid,*this,*contentNotNullBase()); +} + +std::size_t MEDFileAnyTypeField1TS::getHeapMemorySizeWithoutChildren() const +{ + return MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren(); +} + +std::vector MEDFileAnyTypeField1TS::getDirectChildrenWithNull() const +{ + std::vector ret(MEDFileFieldGlobsReal::getDirectChildrenWithNull()); + ret.push_back((const MEDFileAnyTypeField1TSWithoutSDA *)_content); + return ret; } + /*! - * Returns a new MEDCouplingFieldDouble of a given type lying on - * the top level cells of the first mesh in MED file. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If \a this field has not been constructed via file reading. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If no field values of the given \a type. - * \throw If no field values lying on the top level support. - * \sa getFieldAtLevel() + * Returns a string describing \a this field. This string is outputted + * by \c print Python command. */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtTopLevel(TypeOfField type, int renumPol) const throw(INTERP_KERNEL::Exception) +std::string MEDFileAnyTypeField1TS::simpleRepr() const { - if(getFileName2().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); - return _content->getFieldAtTopLevel(type,0,renumPol,this); + std::ostringstream oss; + contentNotNullBase()->simpleRepr(0,oss,-1); + simpleReprGlobs(oss); + return oss.str(); } +/*! + * This method returns all profiles whose name is non empty used. + * \b WARNING If profile is used several times it will be reported \b only \b once. + * To get non empty name profiles as time as they appear in \b this call MEDFileField1TS::getPflsReallyUsedMulti instead. + */ +std::vector MEDFileAnyTypeField1TS::getPflsReallyUsed() const +{ + return contentNotNullBase()->getPflsReallyUsed2(); +} /*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given mesh. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the new field. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If no field of \a this is lying on \a mesh. - * \throw If the mesh is empty. - * \throw If no field values of the given \a type are available. - * \sa getFieldAtLevel() - * \sa getFieldOnMeshAtLevel() + * This method returns all localizations whose name is non empty used. + * \b WARNING If localization is used several times it will be reported \b only \b once. + */ +std::vector MEDFileAnyTypeField1TS::getLocsReallyUsed() const +{ + return contentNotNullBase()->getLocsReallyUsed2(); +} + +/*! + * This method returns all profiles whose name is non empty used. + * \b WARNING contrary to MEDFileField1TS::getPflsReallyUsed, if profile is used several times it will be reported as time as it appears. + */ +std::vector MEDFileAnyTypeField1TS::getPflsReallyUsedMulti() const +{ + return contentNotNullBase()->getPflsReallyUsedMulti2(); +} + +/*! + * This method returns all localizations whose name is non empty used. + * \b WARNING contrary to MEDFileField1TS::getLocsReallyUsed if localization is used several times it will be reported as time as it appears. */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol) const throw(INTERP_KERNEL::Exception) +std::vector MEDFileAnyTypeField1TS::getLocsReallyUsedMulti() const +{ + return contentNotNullBase()->getLocsReallyUsedMulti2(); +} + +void MEDFileAnyTypeField1TS::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) +{ + contentNotNullBase()->changePflsRefsNamesGen2(mapOfModif); +} + +void MEDFileAnyTypeField1TS::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) +{ + contentNotNullBase()->changeLocsRefsNamesGen2(mapOfModif); +} + +int MEDFileAnyTypeField1TS::getDimension() const +{ + return contentNotNullBase()->getDimension(); +} + +int MEDFileAnyTypeField1TS::getIteration() const +{ + return contentNotNullBase()->getIteration(); +} + +int MEDFileAnyTypeField1TS::getOrder() const +{ + return contentNotNullBase()->getOrder(); +} + +double MEDFileAnyTypeField1TS::getTime(int& iteration, int& order) const +{ + return contentNotNullBase()->getTime(iteration,order); +} + +void MEDFileAnyTypeField1TS::setTime(int iteration, int order, double val) +{ + contentNotNullBase()->setTime(iteration,order,val); +} + +std::string MEDFileAnyTypeField1TS::getName() const +{ + return contentNotNullBase()->getName(); +} + +void MEDFileAnyTypeField1TS::setName(const std::string& name) +{ + contentNotNullBase()->setName(name); +} + +void MEDFileAnyTypeField1TS::simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const +{ + contentNotNullBase()->simpleRepr(bkOffset,oss,f1tsId); +} + +std::string MEDFileAnyTypeField1TS::getDtUnit() const +{ + return contentNotNullBase()->getDtUnit(); +} + +void MEDFileAnyTypeField1TS::setDtUnit(const std::string& dtUnit) +{ + contentNotNullBase()->setDtUnit(dtUnit); +} + +std::string MEDFileAnyTypeField1TS::getMeshName() const +{ + return contentNotNullBase()->getMeshName(); +} + +void MEDFileAnyTypeField1TS::setMeshName(const std::string& newMeshName) +{ + contentNotNullBase()->setMeshName(newMeshName); +} + +bool MEDFileAnyTypeField1TS::changeMeshNames(const std::vector< std::pair >& modifTab) +{ + return contentNotNullBase()->changeMeshNames(modifTab); +} + +int MEDFileAnyTypeField1TS::getMeshIteration() const +{ + return contentNotNullBase()->getMeshIteration(); +} + +int MEDFileAnyTypeField1TS::getMeshOrder() const +{ + return contentNotNullBase()->getMeshOrder(); +} + +int MEDFileAnyTypeField1TS::getNumberOfComponents() const +{ + return contentNotNullBase()->getNumberOfComponents(); +} + +bool MEDFileAnyTypeField1TS::isDealingTS(int iteration, int order) const +{ + return contentNotNullBase()->isDealingTS(iteration,order); +} + +std::pair MEDFileAnyTypeField1TS::getDtIt() const +{ + return contentNotNullBase()->getDtIt(); +} + +void MEDFileAnyTypeField1TS::fillIteration(std::pair& p) const +{ + contentNotNullBase()->fillIteration(p); +} + +void MEDFileAnyTypeField1TS::fillTypesOfFieldAvailable(std::vector& types) const +{ + contentNotNullBase()->fillTypesOfFieldAvailable(types); +} + +void MEDFileAnyTypeField1TS::setInfo(const std::vector& infos) +{ + contentNotNullBase()->setInfo(infos); +} + +const std::vector& MEDFileAnyTypeField1TS::getInfo() const +{ + return contentNotNullBase()->getInfo(); +} +std::vector& MEDFileAnyTypeField1TS::getInfo() +{ + return contentNotNullBase()->getInfo(); +} + +bool MEDFileAnyTypeField1TS::presenceOfMultiDiscPerGeoType() const +{ + return contentNotNullBase()->presenceOfMultiDiscPerGeoType(); +} + +MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TS::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) +{ + return contentNotNullBase()->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); +} + +const MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TS::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const +{ + return contentNotNullBase()->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); +} + +int MEDFileAnyTypeField1TS::getNonEmptyLevels(const std::string& mname, std::vector& levs) const +{ + return contentNotNullBase()->getNonEmptyLevels(mname,levs); +} + +std::vector MEDFileAnyTypeField1TS::getTypesOfFieldAvailable() const +{ + return contentNotNullBase()->getTypesOfFieldAvailable(); +} + +std::vector< std::vector > > MEDFileAnyTypeField1TS::getFieldSplitedByType(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, + std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const +{ + return contentNotNullBase()->getFieldSplitedByType(mname,types,typesF,pfls,locs); +} + +/*! + * This method returns as MEDFileAnyTypeField1TS new instances as number of components in \a this. + * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this. + * ** WARNING ** do no forget to rename the ouput instances to avoid to write n-times in the same MED file field ! + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitComponents() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitComponents : no content in this ! Unable to split components !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit=content->splitComponents(); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); + for(std::size_t i=0;i_content=contentsSplit[i]; + } + return ret; +} + +/*! + * This method returns as MEDFileAnyTypeField1TS new instances as number of spatial discretizations in \a this. + * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitDiscretizations() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitDiscretizations : no content in this ! Unable to split discretization !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitDiscretizations()); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); + for(std::size_t i=0;i_content=contentsSplit[i]; + } + return ret; +} + +/*! + * This method returns as MEDFileAnyTypeField1TS new instances as number of maximal number of discretization in \a this. + * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretization !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitMultiDiscrPerGeoTypes()); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); + for(std::size_t i=0;i_content=contentsSplit[i]; + } + return ret; +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); + if((const MEDFileAnyTypeField1TSWithoutSDA *)_content) + ret->_content=_content->deepCpy(); + ret->deepCpyGlobs(*this); + return ret.retn(); +} + +int MEDFileAnyTypeField1TS::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) +{ + return contentNotNullBase()->copyTinyInfoFrom(field,arr); +} + +//= MEDFileField1TS + +/*! + * Returns a new instance of MEDFileField1TS holding data of the first time step of + * the first field that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + */ +MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TS(fileName,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileField1TS holding data of the first time step of + * a given field that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \param [in] fieldName - the name of the field to read. + * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + * \throw If there is no field named \a fieldName in the file. + */ +MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TS(fileName,fieldName,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileField1TS holding data of a given time step of + * a given field that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \param [in] fieldName - the name of the field to read. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + * \throw If there is no field named \a fieldName in the file. + * \throw If the required time step is missing from the file. + */ +MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TS(fileName,fieldName,iteration,order,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileField1TS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * Returns a new instance of MEDFileField1TS holding either a shallow copy + * of a given MEDFileField1TSWithoutSDA ( \a other ) or \a other itself. + * \warning this is a shallow copy constructor + * \param [in] other - a MEDFileField1TSWithoutSDA to copy. + * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. + * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ +MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileField1TS(other,shallowCopyOfContent); + ret->contentNotNull(); + return ret.retn(); +} + +/*! + * Returns a new empty instance of MEDFileField1TS. + * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ +MEDFileField1TS *MEDFileField1TS::New() +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileField1TS; + ret->contentNotNull(); + return ret.retn(); +} + +/*! + * This method performs a copy with datatype modification ( float64->int32 ) of \a this. The globals information are copied + * following the given input policy. + * + * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) + * By default (true) the globals are deeply copied. + * \return MEDFileIntField1TS * - a new object that is the result of the conversion of \a this to int32 field. + */ +MEDFileIntField1TS *MEDFileField1TS::convertToInt(bool isDeepCpyGlobs) const +{ + MEDCouplingAutoRefCountObjectPtr ret; + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(content) + { + const MEDFileField1TSWithoutSDA *contc=dynamic_cast(content); + if(!contc) + throw INTERP_KERNEL::Exception("MEDFileField1TS::convertToInt : the content inside this is not FLOAT64 ! This is incoherent !"); + MEDCouplingAutoRefCountObjectPtr newc(contc->convertToInt()); + ret=static_cast(MEDFileAnyTypeField1TS::BuildNewInstanceFromContent((MEDFileIntField1TSWithoutSDA *)newc,getFileName())); + } + else + ret=MEDFileIntField1TS::New(); + if(isDeepCpyGlobs) + ret->deepCpyGlobs(*this); + else + ret->shallowCpyGlobs(*this); + return ret.retn(); +} + +const MEDFileField1TSWithoutSDA *MEDFileField1TS::contentNotNull() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the content pointer is null !"); + const MEDFileField1TSWithoutSDA *ret=dynamic_cast(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); + return ret; +} + +MEDFileField1TSWithoutSDA *MEDFileField1TS::contentNotNull() +{ + MEDFileAnyTypeField1TSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the non const content pointer is null !"); + MEDFileField1TSWithoutSDA *ret=dynamic_cast(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the non const content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); + return ret; +} + +void MEDFileField1TS::SetDataArrayDoubleInField(MEDCouplingFieldDouble *f, MEDCouplingAutoRefCountObjectPtr& arr) +{ + if(!f) + throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : input field is NULL !"); + if(!((DataArray*)arr)) + throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : no array !"); + DataArrayDouble *arrOutC=dynamic_cast((DataArray*)arr); + if(!arrOutC) + throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : mismatch between dataArrays type and MEDFileField1TS ! Expected double !"); + f->setArray(arrOutC); +} + +DataArrayDouble *MEDFileField1TS::ReturnSafelyDataArrayDouble(MEDCouplingAutoRefCountObjectPtr& arr) +{ + if(!((DataArray*)arr)) + throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyDataArrayDouble : no array !"); + DataArrayDouble *arrOutC=dynamic_cast((DataArray*)arr); + if(!arrOutC) + throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyDataArrayDouble : mismatch between dataArrays type and MEDFileField1TS ! Expected double !"); + arrOutC->incrRef(); + return arrOutC; +} + +MEDFileField1TS::MEDFileField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileField1TS::MEDFileField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,fieldName,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileField1TS::MEDFileField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,fieldName,iteration,order,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +/*! + * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * \warning this is a shallow copy constructor + */ +MEDFileField1TS::MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) +try:MEDFileAnyTypeField1TS(other,shallowCopyOfContent) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileField1TS::MEDFileField1TS() +{ + _content=new MEDFileField1TSWithoutSDA; +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on + * mesh entities of a given dimension of the first mesh in MED file. If \a this field + * has not been constructed via file reading, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If \a this field has not been constructed via file reading. + * \throw If the MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + * \sa getFieldOnMeshAtLevel() + */ +MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr arrOut; + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNull()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on + * the top level cells of the first mesh in MED file. If \a this field + * has not been constructed via file reading, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If \a this field has not been constructed via file reading. + * \throw If the MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If no field values of the given \a type. + * \throw If no field values lying on the top level support. + * \sa getFieldAtLevel() + */ +MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtTopLevel(TypeOfField type, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr arrOut; + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNull()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of given type lying on a given mesh. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the new field. + * \param [in] mesh - the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If no field of \a this is lying on \a mesh. + * \throw If the mesh is empty. + * \throw If no field values of the given \a type are available. + * \sa getFieldAtLevel() + * \sa getFieldOnMeshAtLevel() + */ +MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol) const +{ + MEDCouplingAutoRefCountObjectPtr arrOut; + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arrOut,*contentNotNull()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + * \sa getFieldAtLevel() + * \sa getFieldOnMeshAtLevel() + */ +MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const +{ + MEDCouplingAutoRefCountObjectPtr arrOut; + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arrOut,*contentNotNull()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. + * This method is called "Old" because in MED3 norm a field has only one meshName + * attached, so this method is for readers of MED2 files. If \a this field + * has not been constructed via file reading, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] mName - a name of the supporting mesh. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If the MED file is not readable. + * \throw If there is no mesh named \a mName in the MED file. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If \a this field has not been constructed via file reading. + * \throw If no field of \a this is lying on the mesh named \a mName. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + * \sa getFieldAtLevel() + */ +MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr arrOut; + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNull()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns values and a profile of the field of a given type lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the field. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the + * field of interest lies on. If the field lies on all entities of the given + * dimension, all ids in \a pfl are zero. The caller is to delete this array + * using decrRef() as it is no more needed. + * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the + * field. The caller is to delete this array using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + */ +DataArrayDouble *MEDFileField1TS::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const +{ + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNull()); + return MEDFileField1TS::ReturnSafelyDataArrayDouble(ret); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is + * checked if its elements are sorted suitable for writing to MED file ("STB" stands for + * "Sort By Type"), if not, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. + * \throw If the name of \a field is empty. + * \throw If the data array of \a field is not set. + * \throw If the data array is already allocated but has different number of components + * than \a field. + * \throw If the underlying mesh of \a field has no name. + * \throw If elements in the mesh are not in the order suitable for writing to the MED file. + */ +void MEDFileField1TS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field) +{ + setFileName(""); + contentNotNull()->setFieldNoProfileSBT(field,field->getArray(),*this,*contentNotNull()); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this. As described in \ref MEDLoaderMainC a field in MED file sense + * can be an aggregation of several MEDCouplingFieldDouble instances. + * The mesh support of input parameter \a field is ignored here, it can be NULL. + * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, + * and \a profile. + * + * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. + * A new profile is added only if no equal profile is missing. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. The mesh support of field is ignored. + * \param [in] mesh - the supporting mesh of \a field. + * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). + * \param [in] profile - ids of mesh entities on which corresponding field values lie. + * \throw If either \a field or \a mesh or \a profile has an empty name. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If the data array of \a field is not set. + * \throw If the data array of \a this is already allocated but has different number of + * components than \a field. + * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. + * \sa setFieldNoProfileSBT() + */ +void MEDFileField1TS::setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) +{ + setFileName(""); + contentNotNull()->setFieldProfile(field,field->getArray(),mesh,meshDimRelToMax,profile,*this,*contentNotNull()); +} + +MEDFileAnyTypeField1TS *MEDFileField1TS::shallowCpy() const +{ + return new MEDFileField1TS(*this); +} + +DataArrayDouble *MEDFileField1TS::getUndergroundDataArray() const +{ + return contentNotNull()->getUndergroundDataArrayDouble(); +} + +DataArrayDouble *MEDFileField1TS::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const +{ + return contentNotNull()->getUndergroundDataArrayDoubleExt(entries); +} + +std::vector< std::vector > MEDFileField1TS::getFieldSplitedByType2(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, + std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const +{ + return contentNotNull()->getFieldSplitedByType2(mname,types,typesF,pfls,locs); +} + +//= MEDFileIntField1TS + +MEDFileIntField1TS *MEDFileIntField1TS::New() +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntField1TS; + ret->contentNotNull(); + return ret.retn(); +} + +MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TS(fileName,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TS(fileName,fieldName,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TS(fileName,fieldName,iteration,order,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +MEDFileIntField1TS *MEDFileIntField1TS::New(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntField1TS(other,shallowCopyOfContent); + ret->contentNotNull(); + return ret.retn(); +} + +MEDFileIntField1TS::MEDFileIntField1TS() +{ + _content=new MEDFileIntField1TSWithoutSDA; +} + +MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,fieldName,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,fieldName,iteration,order,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +/*! + * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * \warning this is a shallow copy constructor + */ +MEDFileIntField1TS::MEDFileIntField1TS(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeField1TS(other,shallowCopyOfContent) +{ +} + +MEDFileAnyTypeField1TS *MEDFileIntField1TS::shallowCpy() const +{ + return new MEDFileIntField1TS(*this); +} + +/*! + * This method performs a copy with datatype modification ( int32->float64 ) of \a this. The globals information are copied + * following the given input policy. + * + * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) + * By default (true) the globals are deeply copied. + * \return MEDFileField1TS * - a new object that is the result of the conversion of \a this to float64 field. + */ +MEDFileField1TS *MEDFileIntField1TS::convertToDouble(bool isDeepCpyGlobs) const +{ + MEDCouplingAutoRefCountObjectPtr ret; + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(content) + { + const MEDFileIntField1TSWithoutSDA *contc=dynamic_cast(content); + if(!contc) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::convertToInt : the content inside this is not INT32 ! This is incoherent !"); + MEDCouplingAutoRefCountObjectPtr newc(contc->convertToDouble()); + ret=static_cast(MEDFileAnyTypeField1TS::BuildNewInstanceFromContent((MEDFileField1TSWithoutSDA *)newc,getFileName())); + } + else + ret=MEDFileField1TS::New(); + if(isDeepCpyGlobs) + ret->deepCpyGlobs(*this); + else + ret->shallowCpyGlobs(*this); + return ret.retn(); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is + * checked if its elements are sorted suitable for writing to MED file ("STB" stands for + * "Sort By Type"), if not, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. The field double values are ignored. + * \param [in] arrOfVals - the values of the field \a field used. + * \throw If the name of \a field is empty. + * \throw If the data array of \a field is not set. + * \throw If the data array is already allocated but has different number of components + * than \a field. + * \throw If the underlying mesh of \a field has no name. + * \throw If elements in the mesh are not in the order suitable for writing to the MED file. + */ +void MEDFileIntField1TS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) +{ + setFileName(""); + contentNotNull()->setFieldNoProfileSBT(field,arrOfVals,*this,*contentNotNull()); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this. As described in \ref MEDLoaderMainC a field in MED file sense + * can be an aggregation of several MEDCouplingFieldDouble instances. + * The mesh support of input parameter \a field is ignored here, it can be NULL. + * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, + * and \a profile. + * + * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. + * A new profile is added only if no equal profile is missing. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. The field double values and mesh support are ignored. + * \param [in] arrOfVals - the values of the field \a field used. + * \param [in] mesh - the supporting mesh of \a field. + * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). + * \param [in] profile - ids of mesh entities on which corresponding field values lie. + * \throw If either \a field or \a mesh or \a profile has an empty name. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If the data array of \a field is not set. + * \throw If the data array of \a this is already allocated but has different number of + * components than \a field. + * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. + * \sa setFieldNoProfileSBT() + */ +void MEDFileIntField1TS::setFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) +{ + setFileName(""); + contentNotNull()->setFieldProfile(field,arrOfVals,mesh,meshDimRelToMax,profile,*this,*contentNotNull()); +} + +const MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the content pointer is null !"); + const MEDFileIntField1TSWithoutSDA *ret=dynamic_cast(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the content pointer is not null but it is not of type int32 ! Reason is maybe that the read field has not the type INT32 !"); + return ret; +} + +MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr arrOut2; + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut2,*contentNotNull()); + DataArrayInt *arrOutC=dynamic_cast((DataArray *)arrOut2); + if(!arrOutC) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::getFieldAtLevelOld : mismatch between dataArrays type and MEDFileIntField1TS ! Expected int32 !"); + arrOut=arrOutC; + arrOut->incrRef(); // arrOut2 dies at the end of the func + return ret.retn(); +} + +DataArrayInt *MEDFileIntField1TS::ReturnSafelyDataArrayInt(MEDCouplingAutoRefCountObjectPtr& arr) +{ + if(!((DataArray *)arr)) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::ReturnSafelyDataArrayInt : input DataArray is NULL !"); + DataArrayInt *arrC=dynamic_cast((DataArray *)arr); + if(!arrC) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::ReturnSafelyDataArrayInt : input DataArray is not of type INT32 !"); + arrC->incrRef(); + return arrC; +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on + * the top level cells of the first mesh in MED file. If \a this field + * has not been constructed via file reading, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If \a this field has not been constructed via file reading. + * \throw If the MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If no field values of the given \a type. + * \throw If no field values lying on the top level support. + * \sa getFieldAtLevel() + */ +MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtTopLevel(TypeOfField type, DataArrayInt* &arrOut, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr arr; + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arr,*contentNotNull()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of given type lying on a given mesh. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the new field. + * \param [in] mesh - the supporting mesh. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If no field of \a this is lying on \a mesh. + * \throw If the mesh is empty. + * \throw If no field values of the given \a type are available. + * \sa getFieldAtLevel() + * \sa getFieldOnMeshAtLevel() + */ +MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol) const +{ + MEDCouplingAutoRefCountObjectPtr arr; + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arr,*contentNotNull()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] mesh - the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + * \sa getFieldAtLevel() + * \sa getFieldOnMeshAtLevel() + */ +MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol) const +{ + MEDCouplingAutoRefCountObjectPtr arr; + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arr,*contentNotNull()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. + * This method is called "Old" because in MED3 norm a field has only one meshName + * attached, so this method is for readers of MED2 files. If \a this field + * has not been constructed via file reading, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] mName - a name of the supporting mesh. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If the MED file is not readable. + * \throw If there is no mesh named \a mName in the MED file. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If \a this field has not been constructed via file reading. + * \throw If no field of \a this is lying on the mesh named \a mName. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + * \sa getFieldAtLevel() + */ +MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr arr; + MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arr,*contentNotNull()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns values and a profile of the field of a given type lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the field. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the + * field of interest lies on. If the field lies on all entities of the given + * dimension, all ids in \a pfl are zero. The caller is to delete this array + * using decrRef() as it is no more needed. + * \return DataArrayInt * - a new instance of DataArrayInt holding values of the + * field. The caller is to delete this array using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + */ +DataArrayInt *MEDFileIntField1TS::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const +{ + MEDCouplingAutoRefCountObjectPtr arr=contentNotNull()->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNull()); + return MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); +} + +MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull() +{ + MEDFileAnyTypeField1TSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the non const content pointer is null !"); + MEDFileIntField1TSWithoutSDA *ret=dynamic_cast(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the non const content pointer is not null but it is not of type int32 ! Reason is maybe that the read field has not the type INT32 !"); + return ret; +} + +DataArrayInt *MEDFileIntField1TS::getUndergroundDataArray() const +{ + return contentNotNull()->getUndergroundDataArrayInt(); +} + +//= MEDFileAnyTypeFieldMultiTSWithoutSDA + +MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA() +{ +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileFieldNameScope(fieldName) +{ +} + +/*! + * \param [in] fieldId field id in C mode + */ +MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +{ + med_field_type typcha; + std::string dtunitOut; + int nbOfStep=MEDFileAnyTypeField1TS::LocateField2(fid,"",fieldId,false,_name,typcha,_infos,dtunitOut); + setDtUnit(dtunitOut.c_str()); + loadStructureOrStructureAndBigArraysRecursively(fid,nbOfStep,typcha,loadAll,ms,entities); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +try:MEDFileFieldNameScope(fieldName),_infos(infos) +{ + setDtUnit(dtunit.c_str()); + loadStructureOrStructureAndBigArraysRecursively(fid,nbOfStep,fieldTyp,loadAll,ms,entities); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +std::size_t MEDFileAnyTypeFieldMultiTSWithoutSDA::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_name.capacity()+_infos.capacity()*sizeof(std::string)+_time_steps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr)); + for(std::vector::const_iterator it=_infos.begin();it!=_infos.end();it++) + ret+=(*it).capacity(); + return ret; +} + +std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getDirectChildrenWithNull() const +{ + std::vector ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + ret.push_back((const MEDFileAnyTypeField1TSWithoutSDA *)*it); + return ret; +} + +/*! + * If one of the id in [ \a startIds , \a endIds ) points to a null element, there is not throw. Simply, this empty element is added as if it were not + * NULL. + */ +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds(const int *startIds, const int *endIds) const +{ + MEDCouplingAutoRefCountObjectPtr ret=createNew(); + ret->setInfo(_infos); + int sz=(int)_time_steps.size(); + for(const int *id=startIds;id!=endIds;id++) + { + if(*id>=0 && *id tse2; + if(tse) + { + tse->incrRef(); + tse2=(const_cast(tse)); + } + ret->pushBackTimeStep(tse2); + } + else + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds : At pos #" << std::distance(startIds,id) << " value is " << *id; + oss << " ! Should be in [0," << sz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(ret->getNumberOfTS()>0) + ret->synchronizeNameScope(); + ret->copyNameScope(*this); + return ret.retn(); +} + +/*! + * If one of the id in the input range points to a null element, there is not throw. Simply, this empty element is added as if it were not + * NULL. + */ +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds2(int bg, int end, int step) const +{ + static const char msg[]="MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds2"; + int nbOfEntriesToKeep=DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg); + MEDCouplingAutoRefCountObjectPtr ret=createNew(); + ret->setInfo(_infos); + int sz=(int)_time_steps.size(); + int j=bg; + for(int i=0;i=0 && j tse2; + if(tse) + { + tse->incrRef(); + tse2=(const_cast(tse)); + } + ret->pushBackTimeStep(tse2); + } + else + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds : At pos #" << i << " value is " << j; + oss << " ! Should be in [0," << sz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(ret->getNumberOfTS()>0) + ret->synchronizeNameScope(); + ret->copyNameScope(*this); + return ret.retn(); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const +{ + int id=0; + MEDCouplingAutoRefCountObjectPtr ids=DataArrayInt::New(); ids->alloc(0,1); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,id++) + { + const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); + if(!cur) + continue; + std::pair p(cur->getIteration(),cur->getOrder()); + if(std::find(timeSteps.begin(),timeSteps.end(),p)!=timeSteps.end()) + ids->pushBackSilent(id); + } + return buildFromTimeStepIds(ids->begin(),ids->end()); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const +{ + int id=0; + MEDCouplingAutoRefCountObjectPtr ids=DataArrayInt::New(); ids->alloc(0,1); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,id++) + { + const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); + if(!cur) + continue; + std::pair p(cur->getIteration(),cur->getOrder()); + if(std::find(timeSteps.begin(),timeSteps.end(),p)==timeSteps.end()) + ids->pushBackSilent(id); + } + return buildFromTimeStepIds(ids->begin(),ids->end()); +} + +bool MEDFileAnyTypeFieldMultiTSWithoutSDA::presenceOfMultiDiscPerGeoType() const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); + if(!cur) + continue; + if(cur->presenceOfMultiDiscPerGeoType()) + return true; + } + return false; +} + +const std::vector& MEDFileAnyTypeFieldMultiTSWithoutSDA::getInfo() const +{ + return _infos; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::setInfo(const std::vector& info) +{ + _infos=info; +} + +int MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepPos(int iteration, int order) const +{ + int ret=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) + { + const MEDFileAnyTypeField1TSWithoutSDA *pt(*it); + if(pt->isDealingTS(iteration,order)) + return ret; + } + std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepPos : Muli timestep field on time (" << iteration << "," << order << ") does not exist ! Available (iteration,order) are :\n"; + std::vector< std::pair > vp=getIterations(); + for(std::vector< std::pair >::const_iterator it2=vp.begin();it2!=vp.end();it2++) + oss << "(" << (*it2).first << "," << (*it2).second << ") "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +const MEDFileAnyTypeField1TSWithoutSDA& MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepEntry(int iteration, int order) const +{ + return *_time_steps[getTimeStepPos(iteration,order)]; +} + +MEDFileAnyTypeField1TSWithoutSDA& MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepEntry(int iteration, int order) +{ + return *_time_steps[getTimeStepPos(iteration,order)]; +} + +std::string MEDFileAnyTypeFieldMultiTSWithoutSDA::getMeshName() const +{ + if(_time_steps.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getMeshName : not time steps !"); + return _time_steps[0]->getMeshName(); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::setMeshName(const std::string& newMeshName) +{ + std::string oldName(getMeshName()); + std::vector< std::pair > v(1); + v[0].first=oldName; v[0].second=newMeshName; + changeMeshNames(v); +} + +bool MEDFileAnyTypeFieldMultiTSWithoutSDA::changeMeshNames(const std::vector< std::pair >& modifTab) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *cur(*it); + if(cur) + ret=cur->changeMeshNames(modifTab) || ret; + } + return ret; +} + +/*! + * See doc at MEDFileField1TSWithoutSDA::getUndergroundDataArray + */ +DataArray *MEDFileAnyTypeFieldMultiTSWithoutSDA::getUndergroundDataArray(int iteration, int order) const +{ + return getTimeStepEntry(iteration,order).getUndergroundDataArray(); +} + +/*! + * See doc at MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt + */ +DataArray *MEDFileAnyTypeFieldMultiTSWithoutSDA::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const +{ + return getTimeStepEntry(iteration,order).getUndergroundDataArrayExt(entries); +} + +bool MEDFileAnyTypeFieldMultiTSWithoutSDA::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, + MEDFileFieldGlobsReal& glob) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *f1ts(*it); + if(f1ts) + ret=f1ts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,glob) || ret; + } + return ret; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const +{ + std::string startLine(bkOffset,' '); + oss << startLine << "Field multi time steps [Type=" << getTypeStr() << "]"; + if(fmtsId>=0) + oss << " (" << fmtsId << ")"; + oss << " has the following name: \"" << _name << "\"." << std::endl; + oss << startLine << "Field multi time steps has " << _infos.size() << " components with the following infos :" << std::endl; + for(std::vector::const_iterator it=_infos.begin();it!=_infos.end();it++) + { + oss << startLine << " - \"" << *it << "\"" << std::endl; + } + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) + { + std::string chapter(17,'0'+i); + oss << startLine << chapter << std::endl; + const MEDFileAnyTypeField1TSWithoutSDA *cur=(*it); + if(cur) + cur->simpleRepr(bkOffset+2,oss,i); + else + oss << startLine << " Field on one time step #" << i << " is not defined !" << std::endl; + oss << startLine << chapter << std::endl; + } +} + +std::vector< std::pair > MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeSteps(std::vector& ret1) const +{ + std::size_t sz=_time_steps.size(); + std::vector< std::pair > ret(sz); + ret1.resize(sz); + for(std::size_t i=0;igetTime(ret[i].first,ret[i].second); + } + else + { + std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getTimeSteps : At rank #" << i << " time step is not defined. Invoke eraseEmptyTS method !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep(MEDCouplingAutoRefCountObjectPtr& tse) +{ + MEDFileAnyTypeField1TSWithoutSDA *tse2(tse); + if(!tse2) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : input content object is null !"); + checkCoherencyOfType(tse2); + if(_time_steps.empty()) + { + setName(tse2->getName().c_str()); + setInfo(tse2->getInfo()); + } + checkThatComponentsMatch(tse2->getInfo()); + _time_steps.push_back(tse); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::synchronizeNameScope() +{ + std::size_t nbOfCompo=_infos.size(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *cur=(*it); + if(cur) + { + if((cur->getInfo()).size()!=nbOfCompo) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::synchronizeNameScope : Mismatch in the number of components of parts ! Should be " << nbOfCompo; + oss << " ! but the field at iteration=" << cur->getIteration() << " order=" << cur->getOrder() << " has " << (cur->getInfo()).size() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + cur->copyNameScope(*this); + } + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadStructureOrStructureAndBigArraysRecursively(med_idt fid, int nbPdt, med_field_type fieldTyp, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +{ + _time_steps.resize(nbPdt); + for(int i=0;i > ts; + med_int numdt=0,numo=0; + med_int meshIt=0,meshOrder=0; + med_float dt=0.0; + MEDFILESAFECALLERRD0(MEDfieldComputingStepMeshInfo,(fid,_name.c_str(),i+1,&numdt,&numo,&dt,&meshIt,&meshOrder)); + switch(fieldTyp) + { + case MED_FLOAT64: + { + _time_steps[i]=MEDFileField1TSWithoutSDA::New(_name.c_str(),i+1,numdt,numo,_infos); + break; + } + case MED_INT32: + { + _time_steps[i]=MEDFileIntField1TSWithoutSDA::New(_name.c_str(),i+1,numdt,numo,_infos); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::loadStructureOrStructureAndBigArraysRecursively : managed field type are : FLOAT64, INT32 !"); + } + if(loadAll) + _time_steps[i]->loadStructureAndBigArraysRecursively(fid,*this,ms,entities); + else + _time_steps[i]->loadOnlyStructureOfDataRecursively(fid,*this,ms,entities); + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts) const +{ + if(_time_steps.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::writeLL : no time steps set !"); + checkThatNbOfCompoOfTSMatchThis(); + std::vector infos(getInfo()); + int nbComp=infos.size(); + INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); + for(int i=0;iwriteLL(fid,opts,*this); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *elt(*it); + if(elt) + elt->loadBigArraysRecursively(fid,nasc); + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *elt(*it); + if(elt) + elt->loadBigArraysRecursivelyIfNecessary(fid,nasc); + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::unloadArrays() +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *elt(*it); + if(elt) + elt->unloadArrays(); + } +} + +int MEDFileAnyTypeFieldMultiTSWithoutSDA::getNumberOfTS() const +{ + return _time_steps.size(); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::eraseEmptyTS() +{ + std::vector< MEDCouplingAutoRefCountObjectPtr > newTS; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + const MEDFileAnyTypeField1TSWithoutSDA *tmp=(*it); + if(tmp) + newTS.push_back(*it); + } + _time_steps=newTS; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::eraseTimeStepIds(const int *startIds, const int *endIds) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr > newTS; + int maxId=(int)_time_steps.size(); + int ii=0; + std::set idsToDel; + for(const int *id=startIds;id!=endIds;id++,ii++) + { + if(*id>=0 && *id b(sz,true); + int j=bg; + for(int i=0;i > newTS; + for(std::size_t i=0;i >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) + { + const MEDFileAnyTypeField1TSWithoutSDA *tmp(*it); + if(tmp) + { + int it2,ord; + tmp->getTime(it2,ord); + if(it2==iteration && order==ord) + return ret; + else + oss << "(" << it2 << "," << ord << "), "; + } + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +int MEDFileAnyTypeFieldMultiTSWithoutSDA::getPosGivenTime(double time, double eps) const +{ + int ret=0; + std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getPosGivenTime : No such time step " << time << "! \nPossibilities are : "; + oss.precision(15); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) + { + const MEDFileAnyTypeField1TSWithoutSDA *tmp(*it); + if(tmp) + { + int it2,ord; + double ti=tmp->getTime(it2,ord); + if(fabs(time-ti) > MEDFileAnyTypeFieldMultiTSWithoutSDA::getIterations() const +{ + int lgth=_time_steps.size(); + std::vector< std::pair > ret(lgth); + for(int i=0;ifillIteration(ret[i]); + return ret; +} + +/*! + * This method has 3 inputs 'iteration' 'order' 'mname'. 'mname' can be null if the user is the general case where there is only one meshName lying on 'this' + * This method returns two things. + * - The absolute dimension of 'this' in first parameter. + * - The available ext levels relative to the absolute dimension returned in first parameter. These relative levels are relative + * to the first output parameter. The values in 'levs' will be returned in decreasing order. + * + * This method is designed for MEDFileFieldMultiTS instances that have a discritization ON_CELLS, ON_GAUSS_NE and ON_GAUSS. + * Only these 3 discretizations will be taken into account here. + * + * If 'this' is empty this method will throw an INTERP_KERNEL::Exception. + * If there is \b only node fields defined in 'this' -1 is returned and 'levs' output parameter will be empty. In this + * case the caller has to know the underlying mesh it refers to. By defaut it is the level 0 of the corresponding mesh. + * + * This method is usefull to make the link between meshDimension of the underlying mesh in 'this' and the levels on 'this'. + * It is possible (even if it is not common) that the highest level in 'this' were not equal to the meshDimension of the underlying mesh in 'this'. + * + * Let's consider the typical following case : + * - a mesh 'm1' has a meshDimension 3 and has the following non empty levels + * [0,-1,-2] for example 'm1' lies on TETRA4, HEXA8 TRI3 and SEG2 + * - 'f1' lies on 'm1' and is defined on 3D and 1D cells for example + * TETRA4 and SEG2 + * - 'f2' lies on 'm1' too and is defined on 2D and 1D cells for example TRI3 and SEG2 + * + * In this case f1->getNonEmptyLevelsExt will return (3,[0,-2]) and f2->getNonEmptyLevelsExt will return (2,[0,-1]) + * + * To retrieve the highest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+0);//absDim-meshDim+relativeLev + * To retrieve the lowest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+(-2));//absDim-meshDim+relativeLev + * To retrieve the highest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+0);//absDim-meshDim+relativeLev + * To retrieve the lowest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+(-1));//absDim-meshDim+relativeLev + */ +int MEDFileAnyTypeFieldMultiTSWithoutSDA::getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector& levs) const +{ + return getTimeStepEntry(iteration,order).getNonEmptyLevels(mname,levs); +} + +const MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2(int pos) const +{ + if(pos<0 || pos>=(int)_time_steps.size()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << " whereas should be in [0," << _time_steps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileAnyTypeField1TSWithoutSDA *item=_time_steps[pos]; + if(item==0) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << ", this pos id exists but the underlying Field1TS is null !"; + oss << "\nTry to use following method eraseEmptyTS !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return item; +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2(int pos) +{ + if(pos<0 || pos>=(int)_time_steps.size()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << " whereas should be in [0," << _time_steps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileAnyTypeField1TSWithoutSDA *item=_time_steps[pos]; + if(item==0) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << ", this pos id exists but the underlying Field1TS is null !"; + oss << "\nTry to use following method eraseEmptyTS !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return item; +} + +std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getPflsReallyUsed2() const +{ + std::vector ret; + std::set ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + std::vector tmp=(*it)->getPflsReallyUsed2(); + for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; +} + +std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getLocsReallyUsed2() const +{ + std::vector ret; + std::set ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + std::vector tmp=(*it)->getLocsReallyUsed2(); + for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; +} + +std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getPflsReallyUsedMulti2() const +{ + std::vector ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + std::vector tmp=(*it)->getPflsReallyUsedMulti2(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getLocsReallyUsedMulti2() const +{ + std::vector ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + std::vector tmp=(*it)->getLocsReallyUsedMulti2(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + (*it)->changePflsRefsNamesGen2(mapOfModif); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + (*it)->changeLocsRefsNamesGen2(mapOfModif); +} + +std::vector< std::vector > MEDFileAnyTypeFieldMultiTSWithoutSDA::getTypesOfFieldAvailable() const +{ + int lgth=_time_steps.size(); + std::vector< std::vector > ret(lgth); + for(int i=0;ifillTypesOfFieldAvailable(ret[i]); + return ret; +} + +/*! + * entry point for users that want to iterate into MEDFile DataStructure without any overhead. + */ +std::vector< std::vector< std::pair > > MEDFileAnyTypeFieldMultiTSWithoutSDA::getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const +{ + return getTimeStepEntry(iteration,order).getFieldSplitedByType(mname,types,typesF,pfls,locs); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) + { + if((const MEDFileAnyTypeField1TSWithoutSDA *)*it) + ret->_time_steps[i]=(*it)->deepCpy(); + } + return ret.retn(); +} + +std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitComponents() const +{ + std::size_t sz(_infos.size()),sz2(_time_steps.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr > ret(sz); + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > ts(sz2); + for(std::size_t i=0;i_infos.resize(1); ret[i]->_infos[0]=_infos[i]; + } + for(std::size_t i=0;i > ret1=_time_steps[i]->splitComponents(); + if(ret1.size()!=sz) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::splitComponents : At rank #" << i << " number of components is " << ret1.size() << " whereas it should be for all time steps " << sz << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ts[i]=ret1; + } + for(std::size_t i=0;i_time_steps[j]=ts[j][i]; + return ret; +} + +/*! + * This method splits into discretization each time steps in \a this. + * ** WARNING ** the returned instances are not compulsary defined on the same time steps series ! + */ +std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations() const +{ + std::size_t sz(_time_steps.size()); + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > items(sz); + for(std::size_t i=0;isplitDiscretizations(); + } + // + std::vector< MEDCouplingAutoRefCountObjectPtr > ret; + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > ret2; + std::vector< TypeOfField > types; + for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=items.begin();it0!=items.end();it0++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) + { + std::vector ts=(*it1)->getTypesOfFieldAvailable(); + if(ts.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations : it appears that the splitting of MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations has returned invalid result !"); + std::vector< TypeOfField >::iterator it2=std::find(types.begin(),types.end(),ts[0]); + if(it2==types.end()) + types.push_back(ts[0]); + } + ret.resize(types.size()); ret2.resize(types.size()); + for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=items.begin();it0!=items.end();it0++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) + { + TypeOfField typ=(*it1)->getTypesOfFieldAvailable()[0]; + std::size_t pos=std::distance(types.begin(),std::find(types.begin(),types.end(),typ)); + ret2[pos].push_back(*it1); + } + for(std::size_t i=0;i elt(createNew()); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it1=ret2[i].begin();it1!=ret2[i].end();it1++) + elt->pushBackTimeStep(*it1);//also updates infos in elt + ret[i]=elt; + elt->MEDFileFieldNameScope::operator=(*this); + } + return ret; +} + +/*! + * Contrary to splitDiscretizations method this method makes the hypothesis that the times series are **NOT** impacted by the splitting of multi discretization. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes() const +{ + std::size_t sz(_time_steps.size()); + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > items(sz); + std::size_t szOut(std::numeric_limits::max()); + for(std::size_t i=0;isplitMultiDiscrPerGeoTypes(); + if(szOut==std::numeric_limits::max()) + szOut=items[i].size(); + else + if(items[i].size()!=szOut) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : The splitting per discretization is expected to be same among time steps !"); + } + if(szOut==std::numeric_limits::max()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > ret(szOut); + for(std::size_t i=0;i elt(createNew()); + for(std::size_t j=0;jpushBackTimeStep(items[j][i]); + ret[i]=elt; + elt->MEDFileFieldNameScope::operator=(*this); + } + return ret; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) +{ + _name=field->getName(); + if(_name.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom : unsupported fields with no name in MED file !"); + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom : no array set !"); + _infos=arr->getInfoOnComponents(); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo(const MEDCouplingFieldDouble *field, const DataArray *arr) const +{ + static const char MSG[]="MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo : invalid "; + if(_name!=field->getName()) + { + std::ostringstream oss; oss << MSG << "name ! should be \"" << _name; + oss << "\" and it is set in input field to \"" << field->getName() << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo : no array set !"); + checkThatComponentsMatch(arr->getInfoOnComponents()); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatComponentsMatch(const std::vector& compos) const +{ + static const char MSG[]="MEDFileFieldMultiTSWithoutSDA::checkThatComponentsMatch : "; + if(getInfo().size()!=compos.size()) + { + std::ostringstream oss; oss << MSG << "mismatch of number of components between this (" << getInfo().size() << ") and "; + oss << " number of components of element to append (" << compos.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(_infos!=compos) + { + std::ostringstream oss; oss << MSG << "components have same size but are different ! should be \""; + std::copy(_infos.begin(),_infos.end(),std::ostream_iterator(oss,", ")); + oss << " But compo in input fields are : "; + std::copy(compos.begin(),compos.end(),std::ostream_iterator(oss,", ")); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatNbOfCompoOfTSMatchThis() const +{ + std::size_t sz=_infos.size(); + int j=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,j++) + { + const MEDFileAnyTypeField1TSWithoutSDA *elt(*it); + if(elt) + if(elt->getInfo().size()!=sz) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatNbOfCompoOfTSMatchThis : At pos #" << j << " the number of components is equal to "; + oss << elt->getInfo().size() << " whereas it is expected to be equal to " << sz << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldNoProfileSBT : input field is NULL !"); + if(!_time_steps.empty()) + checkCoherencyOfTinyInfo(field,arr); + MEDFileAnyTypeField1TSWithoutSDA *objC=createNew1TSWithoutSDAEmptyInstance(); + MEDCouplingAutoRefCountObjectPtr obj(objC); + objC->setFieldNoProfileSBT(field,arr,glob,*this); + copyTinyInfoFrom(field,arr); + _time_steps.push_back(obj); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::appendFieldNoProfileSBT : input field is NULL !"); + if(!_time_steps.empty()) + checkCoherencyOfTinyInfo(field,arr); + MEDFileField1TSWithoutSDA *objC=new MEDFileField1TSWithoutSDA; + MEDCouplingAutoRefCountObjectPtr obj(objC); + objC->setFieldProfile(field,arr,mesh,meshDimRelToMax,profile,glob,*this); + copyTinyInfoFrom(field,arr); + _time_steps.push_back(obj); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration(int i, MEDCouplingAutoRefCountObjectPtr ts) +{ + int sz=(int)_time_steps.size(); + if(i<0 || i>=sz) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration : trying to set element at place #" << i << " should be in [0," << sz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileAnyTypeField1TSWithoutSDA *tsPtr(ts); + if(tsPtr) + { + if(tsPtr->getNumberOfComponents()!=(int)_infos.size()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration : trying to set element with " << tsPtr->getNumberOfComponents() << " components ! Should be " << _infos.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + _time_steps[i]=ts; +} + +//= MEDFileFieldMultiTSWithoutSDA + +MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) { - return _content->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0); + return new MEDFileFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities); } -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldAtLevel() - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const throw(INTERP_KERNEL::Exception) +MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA() +{ +} + +MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileAnyTypeFieldMultiTSWithoutSDA(fieldName) { - return _content->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh); } /*! - * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. - * This method is called "Old" because in MED3 norm a field has only one meshName - * attached, so this method is for readers of MED2 files. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] mName - a name of the supporting mesh. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If the MED file is not readable. - * \throw If there is no mesh named \a mName in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If \a this field has not been constructed via file reading. - * \throw If no field of \a this is lying on the mesh named \a mName. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldAtLevel() + * \param [in] fieldId field id in C mode */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevelOld(TypeOfField type, const char *mname, int meshDimRelToMax, int renumPol) const throw(INTERP_KERNEL::Exception) +MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldId,loadAll,ms,entities) { - if(getFileName2().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); - return _content->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this); } +catch(INTERP_KERNEL::Exception& e) +{ throw e; } +MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } -/*! - * Returns values and a profile of the field of a given type lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -DataArrayDouble *MEDFileField1TS::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeField1TSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::createNew1TSWithoutSDAEmptyInstance() const { - return _content->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this); + return new MEDFileField1TSWithoutSDA; } -/*! - * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is - * checked if its elements are sorted suitable for writing to MED file ("STB" stands for - * "Sort By Type"), if not, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If the data array is already allocated but has different number of components - * than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileField1TS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) +void MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const { - setFileName(""); - _content->setFieldNoProfileSBT(field,*this); + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); + const MEDFileField1TSWithoutSDA *f1tsC=dynamic_cast(f1ts); + if(!f1tsC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType : the input field1TS is not a FLOAT64 type !"); } -/*! - * Adds a MEDCouplingFieldDouble to \a this. Specified entities of a given dimension - * of a given mesh are used as the support of the given field (a real support is not used). - * Elements of the given mesh must be sorted suitable for writing to MED file. - * Order of underlying mesh entities of the given field specified by \a profile parameter - * is not prescribed; this method permutes field values to have them sorted by element - * type as required for writing to MED file. A new profile is added only if no equal - * profile is missing. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on. - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If the data array of \a this is already allocated but has different number of - * components than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileField1TS::setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception) +const char *MEDFileFieldMultiTSWithoutSDA::getTypeStr() const { - setFileName(""); - _content->setFieldProfile(field,mesh,meshDimRelToMax,profile,*this); + return MEDFileField1TSWithoutSDA::TYPE_STR; } -/*! - * This method as MEDFileField1TSW::setLocNameOnLeaf, is dedicated for advanced user that a want a very fine control on their data structure - * without overhead. This method can be called only regarding information returned by MEDFileField1TSWithoutSDA::getFieldSplitedByType or MEDFileField1TSWithoutSDA::getFieldSplitedByType2. - * This method changes the attribute (here it's profile name) of the leaf datastructure (MEDFileFieldPerMeshPerTypePerDisc instance). - * It is the responsability of the caller to invoke MEDFileFieldGlobs::appendProfile or MEDFileFieldGlobs::getProfile - * to keep a valid instance. - * If \b this do not have any leaf that correspond to the request of the input parameter (\b mName, \b typ, \b locId) an INTERP_KERNEL::Exception will be thrown. - * If \b newPflName profile name does not already exist the profile with old name will be renamed with name \b newPflName. - * If \b newPflName already exists and that \b forceRenameOnGlob is false (the default) an INTERP_KERNEL::Exception will be thrown to avoid big confusion. In this case the called should rename before the profile name with name \b newPflName. - * - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. - * \param [in] newLocName is the new localization name. - * \param [in] forceRenameOnGlob specifies the behaviour in case of profile \b newPflName already exists. If true, the renaming is done without check. It can lead to major bug. - * If false, an exception will be thrown to force user to change previously the name of the profile with name \b newPflName - */ -void MEDFileField1TS::setProfileNameOnLeaf(const char *mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const char *newPflName, bool forceRenameOnGlob) throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::shallowCpy() const { - MEDFileFieldPerMeshPerTypePerDisc *disc=getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); - std::string oldPflName=disc->getProfile(); - std::vector vv=getPflsReallyUsedMulti(); - int nbOfOcc=std::count(vv.begin(),vv.end(),oldPflName); - if(forceRenameOnGlob || (!existsPfl(newPflName) && nbOfOcc==1)) - { - disc->setProfile(newPflName); - DataArrayInt *pfl=getProfile(oldPflName.c_str()); - pfl->setName(newPflName); - } - else - { - std::ostringstream oss; oss << "MEDFileField1TS::setProfileNameOnLeaf : Profile \"" << newPflName << "\" already exists or referenced more than one !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + return new MEDFileFieldMultiTSWithoutSDA(*this); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::createNew() const +{ + return new MEDFileFieldMultiTSWithoutSDA; } /*! - * This method as MEDFileField1TSW::setProfileNameOnLeaf, is dedicated for advanced user that a want a very fine control on their data structure - * without overhead. This method can be called only regarding information returned by MEDFileField1TSWithoutSDA::getFieldSplitedByType or MEDFileField1TSWithoutSDA::getFieldSplitedByType2. - * This method changes the attribute (here it's localization name) of the leaf datastructure (MEDFileFieldPerMeshPerTypePerDisc instance). - * It is the responsability of the caller to invoke MEDFileFieldGlobs::appendProfile or MEDFileFieldGlobs::getProfile - * to keep a valid instance. - * If \b this do not have any leaf that correspond to the request of the input parameter (\b mName, \b typ, \b locId) an INTERP_KERNEL::Exception will be thrown. - * This method is an extension of MEDFileField1TSWithoutSDA::setProfileNameOnLeafExt method because it performs a modification of global info. - * If \b newLocName profile name does not already exist the localization with old name will be renamed with name \b newLocName. - * If \b newLocName already exists an INTERP_KERNEL::Exception will be thrown to avoid big confusion. In this case the called should rename before the profile name with name \b newLocName. - * - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. - * \param [in] newLocName is the new localization name. - * \param [in] forceRenameOnGlob specifies the behaviour in case of profile \b newLocName already exists. If true, the renaming is done without check. It can lead to major bug. - * If false, an exception will be thrown to force user to change previously the name of the profile with name \b newLocName + * entry point for users that want to iterate into MEDFile DataStructure with a reduced overhead because output arrays are extracted (created) specially + * for the call of this method. That's why the DataArrayDouble instance in returned vector of vector should be dealed by the caller. */ -void MEDFileField1TS::setLocNameOnLeaf(const char *mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const char *newLocName, bool forceRenameOnGlob) throw(INTERP_KERNEL::Exception) +std::vector< std::vector > MEDFileFieldMultiTSWithoutSDA::getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const { - MEDFileFieldPerMeshPerTypePerDisc *disc=getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); - std::string oldLocName=disc->getLocalization(); - std::vector vv=getLocsReallyUsedMulti(); - int nbOfOcc=std::count(vv.begin(),vv.end(),oldLocName); - if(forceRenameOnGlob || (!existsLoc(newLocName) && nbOfOcc==1)) - { - disc->setLocalization(newLocName); - MEDFileFieldLoc& loc=getLocalization(oldLocName.c_str()); - loc.setName(newLocName); - } - else + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getFieldSplitedByType2 : mismatch of type of field expecting FLOAT64 !"); + return myF1TSC->getFieldSplitedByType2(mname,types,typesF,pfls,locs); +} + +MEDFileIntFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::convertToInt() const +{ + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntFieldMultiTSWithoutSDA); + ret->MEDFileAnyTypeFieldMultiTSWithoutSDA::operator =(*this); + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) { - std::ostringstream oss; oss << "MEDFileField1TS::setLocNameOnLeaf : Localization \"" << newLocName << "\" already exists or referenced more than one !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + const MEDFileAnyTypeField1TSWithoutSDA *eltToConv(*it); + if(eltToConv) + { + const MEDFileField1TSWithoutSDA *eltToConvC=dynamic_cast(eltToConv); + if(!eltToConvC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::convertToInt : presence of an invalid 1TS type ! Should be of type FLOAT64 !"); + MEDCouplingAutoRefCountObjectPtr elt=eltToConvC->convertToInt(); + ret->setIteration(i,elt); + } } + return ret.retn(); } -std::size_t MEDFileField1TS::getHeapMemorySize() const +//= MEDFileAnyTypeFieldMultiTS + +MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS() { - std::size_t ret=0; - if((const MEDFileField1TSWithoutSDA *)_content) - ret+=_content->getHeapMemorySize(); - return ret+MEDFileFieldGlobsReal::getHeapMemorySize(); } -MEDFileField1TS *MEDFileField1TS::deepCpy() const throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileFieldGlobsReal(fileName) { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileField1TS(*this); - if((const MEDFileField1TSWithoutSDA *)_content) - ret->_content=_content->deepCpy(); - ret->deepCpyGlobs(*this); + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + _content=BuildContentFrom(fid,fileName,loadAll,ms); + loadGlobals(fid); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +{ + med_field_type typcha; + std::vector infos; + std::string dtunit; + int i=-1; + MEDFileAnyTypeField1TS::LocateField(fid,fileName,fieldName,i,typcha,infos,dtunit); + MEDCouplingAutoRefCountObjectPtr ret; + switch(typcha) + { + case MED_FLOAT64: + { + ret=new MEDFileFieldMultiTSWithoutSDA(fid,i,loadAll,ms,entities); + break; + } + case MED_INT32: + { + ret=new MEDFileIntFieldMultiTSWithoutSDA(fid,i,loadAll,ms,entities); + break; + } + default: + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::BuildContentFrom(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setDtUnit(dtunit.c_str()); return ret.retn(); } -int MEDFileField1TS::copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) { - return _content->copyTinyInfoFrom(field); + med_field_type typcha; + // + std::vector infos; + std::string dtunit,fieldName; + MEDFileAnyTypeField1TS::LocateField2(fid,fileName,0,true,fieldName,typcha,infos,dtunit); + MEDCouplingAutoRefCountObjectPtr ret; + switch(typcha) + { + case MED_FLOAT64: + { + ret=new MEDFileFieldMultiTSWithoutSDA(fid,0,loadAll,ms,0); + break; + } + case MED_INT32: + { + ret=new MEDFileIntFieldMultiTSWithoutSDA(fid,0,loadAll,ms,0); + break; + } + default: + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::BuildContentFrom(fileName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of the first field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setDtUnit(dtunit.c_str()); + return ret.retn(); } -int MEDFileField1TS::getDimension() const +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent(MEDFileAnyTypeFieldMultiTSWithoutSDA *c, const std::string& fileName) { - return _content->getDimension(); + if(!c) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent : empty content in input : unable to build a new instance !"); + if(dynamic_cast(c)) + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldMultiTS::New(); + ret->setFileName(fileName); + ret->_content=c; c->incrRef(); + return ret.retn(); + } + if(dynamic_cast(c)) + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileIntFieldMultiTS::New(); + ret->setFileName(fileName); + ret->_content=c; c->incrRef(); + return ret.retn(); + } + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent : internal error ! a content of type different from FLOAT64 and INT32 has been built but not intercepted !"); } -int MEDFileField1TS::getIteration() const +MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +try:MEDFileFieldGlobsReal(fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + _content=BuildContentFrom(fid,fileName,fieldName,loadAll,ms,entities); + loadGlobals(fid); +} +catch(INTERP_KERNEL::Exception& e) { - return _content->getIteration(); + throw e; } -int MEDFileField1TS::getOrder() const +//= MEDFileIntFieldMultiTSWithoutSDA + +MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) { - return _content->getOrder(); + return new MEDFileIntFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities); } -double MEDFileField1TS::getTime(int& iteration, int& order) const +MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA() { - return _content->getTime(iteration,order); } -void MEDFileField1TS::setTime(int iteration, int order, double val) +MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileAnyTypeFieldMultiTSWithoutSDA(fieldName) { - _content->setTime(iteration,order,val); } -std::string MEDFileField1TS::getName() const +MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities) { - return _content->getName(); } +catch(INTERP_KERNEL::Exception& e) +{ throw e; } -void MEDFileField1TS::setName(const char *name) +/*! + * \param [in] fieldId field id in C mode + */ +MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldId,loadAll,ms,entities) { - _content->setName(name); } +catch(INTERP_KERNEL::Exception& e) +{ throw e; } -void MEDFileField1TS::simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const +MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::createNew1TSWithoutSDAEmptyInstance() const { - _content->simpleRepr(bkOffset,oss,f1tsId); + return new MEDFileIntField1TSWithoutSDA; } -const std::string& MEDFileField1TS::getDtUnit() const +void MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const { - return _content->getDtUnit(); + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); + const MEDFileIntField1TSWithoutSDA *f1tsC=dynamic_cast(f1ts); + if(!f1tsC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType : the input field1TS is not a INT32 type !"); } -std::string MEDFileField1TS::getMeshName() const throw(INTERP_KERNEL::Exception) +const char *MEDFileIntFieldMultiTSWithoutSDA::getTypeStr() const { - return _content->getMeshName(); + return MEDFileIntField1TSWithoutSDA::TYPE_STR; } -void MEDFileField1TS::setMeshName(const char *newMeshName) throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::shallowCpy() const { - _content->setMeshName(newMeshName); + return new MEDFileIntFieldMultiTSWithoutSDA(*this); } -bool MEDFileField1TS::changeMeshNames(const std::vector< std::pair >& modifTab) throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::createNew() const { - return _content->changeMeshNames(modifTab); + return new MEDFileIntFieldMultiTSWithoutSDA; } -int MEDFileField1TS::getMeshIteration() const throw(INTERP_KERNEL::Exception) +MEDFileFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::convertToDouble() const { - return _content->getMeshIteration(); + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileFieldMultiTSWithoutSDA); + ret->MEDFileAnyTypeFieldMultiTSWithoutSDA::operator =(*this); + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) + { + const MEDFileAnyTypeField1TSWithoutSDA *eltToConv(*it); + if(eltToConv) + { + const MEDFileIntField1TSWithoutSDA *eltToConvC=dynamic_cast(eltToConv); + if(!eltToConvC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::convertToInt : presence of an invalid 1TS type ! Should be of type INT32 !"); + MEDCouplingAutoRefCountObjectPtr elt=eltToConvC->convertToDouble(); + ret->setIteration(i,elt); + } + } + return ret.retn(); } -int MEDFileField1TS::getMeshOrder() const throw(INTERP_KERNEL::Exception) +//= MEDFileAnyTypeFieldMultiTS + +/*! + * Returns a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS holding data of the first field + * that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + */ +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::New(const std::string& fileName, bool loadAll) { - return _content->getMeshOrder(); + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,loadAll,0); + MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); + ret->loadGlobals(fid); + return ret.retn(); } -int MEDFileField1TS::getNumberOfComponents() const +/*! + * Returns a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS holding data of a given field + * that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \param [in] fieldName - the name of the field to read. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + * \throw If there is no field named \a fieldName in the file. + */ +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) { - return _content->getNumberOfComponents(); + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCouplingAutoRefCountObjectPtr c(BuildContentFrom(fid,fileName,fieldName,loadAll,0,0)); + MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); + ret->loadGlobals(fid); + return ret.retn(); } -bool MEDFileField1TS::isDealingTS(int iteration, int order) const +/*! + * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * \warning this is a shallow copy constructor + */ +MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const MEDFileAnyTypeFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) { - return _content->isDealingTS(iteration,order); + if(!shallowCopyOfContent) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *otherPtr(&other); + otherPtr->incrRef(); + _content=const_cast(otherPtr); + } + else + { + _content=other.shallowCpy(); + } } -std::pair MEDFileField1TS::getDtIt() const +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::contentNotNullBase() { - return _content->getDtIt(); + MEDFileAnyTypeFieldMultiTSWithoutSDA *ret=_content; + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS : content is expected to be not null !"); + return ret; } -void MEDFileField1TS::fillIteration(std::pair& p) const +const MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::contentNotNullBase() const { - _content->fillIteration(p); -} -void MEDFileField1TS::fillTypesOfFieldAvailable(std::vector& types) const throw(INTERP_KERNEL::Exception) -{ - _content->fillTypesOfFieldAvailable(types); + const MEDFileAnyTypeFieldMultiTSWithoutSDA *ret=_content; + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS : const content is expected to be not null !"); + return ret; } -const std::vector& MEDFileField1TS::getInfo() const +std::vector MEDFileAnyTypeFieldMultiTS::getPflsReallyUsed() const { - return _content->getInfo(); -} -std::vector& MEDFileField1TS::getInfo() -{ - return _content->getInfo(); + return contentNotNullBase()->getPflsReallyUsed2(); } -DataArrayDouble *MEDFileField1TS::getUndergroundDataArray() const throw(INTERP_KERNEL::Exception) +std::vector MEDFileAnyTypeFieldMultiTS::getLocsReallyUsed() const { - return _content->getUndergroundDataArray(); + return contentNotNullBase()->getLocsReallyUsed2(); } -DataArrayDouble *MEDFileField1TS::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const throw(INTERP_KERNEL::Exception) +std::vector MEDFileAnyTypeFieldMultiTS::getPflsReallyUsedMulti() const { - return _content->getUndergroundDataArrayExt(entries); + return contentNotNullBase()->getPflsReallyUsedMulti2(); } -MEDFileFieldPerMeshPerTypePerDisc *MEDFileField1TS::getLeafGivenMeshAndTypeAndLocId(const char *mName, INTERP_KERNEL::NormalizedCellType typ, int locId) throw(INTERP_KERNEL::Exception) +std::vector MEDFileAnyTypeFieldMultiTS::getLocsReallyUsedMulti() const { - return _content->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); + return contentNotNullBase()->getLocsReallyUsedMulti2(); } -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileField1TS::getLeafGivenMeshAndTypeAndLocId(const char *mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) { - return _content->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); + contentNotNullBase()->changePflsRefsNamesGen2(mapOfModif); } -int MEDFileField1TS::getNonEmptyLevels(const char *mname, std::vector& levs) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) { - return _content->getNonEmptyLevels(mname,levs); + contentNotNullBase()->changeLocsRefsNamesGen2(mapOfModif); } -std::vector MEDFileField1TS::getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) +int MEDFileAnyTypeFieldMultiTS::getNumberOfTS() const { - return _content->getTypesOfFieldAvailable(); + return contentNotNullBase()->getNumberOfTS(); } -std::vector< std::vector > > MEDFileField1TS::getFieldSplitedByType(const char *mname, std::vector& types, std::vector< std::vector >& typesF, - std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception) -{ - return _content->getFieldSplitedByType(mname,types,typesF,pfls,locs); -} -std::vector< std::vector > MEDFileField1TS::getFieldSplitedByType2(const char *mname, std::vector& types, std::vector< std::vector >& typesF, - std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::eraseEmptyTS() { - return _content->getFieldSplitedByType2(mname,types,typesF,pfls,locs); + contentNotNullBase()->eraseEmptyTS(); } -MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::New(med_idt fid, const char *fieldName, int id, int ft, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds(const int *startIds, const int *endIds) { - return new MEDFileFieldMultiTSWithoutSDA(fid,fieldName,id,ft,infos,nbOfStep); + contentNotNullBase()->eraseTimeStepIds(startIds,endIds); } -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA():_field_type(-1) +void MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds2(int bg, int end, int step) { + contentNotNullBase()->eraseTimeStepIds2(bg,end,step); } -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(const char *fieldName):_name(fieldName),_field_type(-1) +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::buildSubPart(const int *startIds, const int *endIds) const { + MEDCouplingAutoRefCountObjectPtr c=contentNotNullBase()->buildFromTimeStepIds(startIds,endIds); + MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); + ret->_content=c; + return ret.retn(); } -/*! - * \param [in] fieldId field id in C mode - */ -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fieldId) throw(INTERP_KERNEL::Exception) -try:_name("") +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::buildSubPartSlice(int bg, int end, int step) const { - med_field_type typcha; - // - int ncomp=MEDfieldnComponent(fid,fieldId+1); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localMesh; - int nbOfStep; - MEDfieldInfo(fid,fieldId+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep); - _name=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE); - _field_type=MEDFileUtilities::TraduceFieldType(typcha); - _infos.resize(ncomp); - for(int j=0;j c=contentNotNullBase()->buildFromTimeStepIds2(bg,end,step); + MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); + ret->_content=c; + return ret.retn(); } -catch(INTERP_KERNEL::Exception& e) - { - throw e; - } -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, const char *fieldName, int id, int ft, const std::vector& infos, int nbOfStep) throw(INTERP_KERNEL::Exception) -try:_name(fieldName),_infos(infos),_field_type(ft) +std::vector< std::pair > MEDFileAnyTypeFieldMultiTS::getIterations() const { - finishLoading(fid,nbOfStep); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; + return contentNotNullBase()->getIterations(); } -std::size_t MEDFileFieldMultiTSWithoutSDA::getHeapMemorySize() const +void MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps(const std::vector& f1ts) { - std::size_t ret=_name.capacity()+_infos.capacity()*sizeof(std::string)+_time_steps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); - for(std::vector::const_iterator it=_infos.begin();it!=_infos.end();it++) - ret+=(*it).capacity(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - if((const MEDFileField1TSWithoutSDA *)(*it)) - ret+=(*it)->getHeapMemorySize(); - return ret; + for(std::vector::const_iterator it=f1ts.begin();it!=f1ts.end();it++) + pushBackTimeStep(*it); } -MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::deepCpy() const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps(MEDFileAnyTypeFieldMultiTS *fmts) { - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldMultiTSWithoutSDA(*this); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) + if(!fmts) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps : Input fmts is NULL !"); + int nbOfTS(fmts->getNumberOfTS()); + for(int i=0;i_time_steps[i]=(*it)->deepCpy(); + MEDCouplingAutoRefCountObjectPtr elt(fmts->getTimeStepAtPos(i)); + pushBackTimeStep(elt); } - return ret.retn(); -} - -const std::vector& MEDFileFieldMultiTSWithoutSDA::getInfo() const throw(INTERP_KERNEL::Exception) -{ - if(_time_steps.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getInfos : not time steps !"); - return _time_steps[0]->getInfo(); -} - -/*! - * See doc at MEDFileField1TSWithoutSDA::getUndergroundDataArray - */ -DataArrayDouble *MEDFileFieldMultiTSWithoutSDA::getUndergroundDataArray(int iteration, int order) const throw(INTERP_KERNEL::Exception) -{ - return getTimeStepEntry(iteration,order).getUndergroundDataArray(); } -/*! - * See doc at MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt - */ -DataArrayDouble *MEDFileFieldMultiTSWithoutSDA::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::pushBackTimeStep(MEDFileAnyTypeField1TS *f1ts) { - return getTimeStepEntry(iteration,order).getUndergroundDataArrayExt(entries); + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : input pointer is NULL !"); + checkCoherencyOfType(f1ts); + f1ts->incrRef(); + MEDCouplingAutoRefCountObjectPtr f1tsSafe(f1ts); + MEDFileAnyTypeField1TSWithoutSDA *c=f1ts->contentNotNullBase(); + c->incrRef(); + MEDCouplingAutoRefCountObjectPtr cSafe(c); + if(!((MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content)) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : no content in this !"); + _content->pushBackTimeStep(cSafe); + appendGlobs(*f1ts,1e-12); } -std::string MEDFileFieldMultiTSWithoutSDA::getMeshName() const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::synchronizeNameScope() { - if(_time_steps.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getMeshName : not time steps !"); - return _time_steps[0]->getMeshName(); + contentNotNullBase()->synchronizeNameScope(); } -void MEDFileFieldMultiTSWithoutSDA::setMeshName(const char *newMeshName) throw(INTERP_KERNEL::Exception) +int MEDFileAnyTypeFieldMultiTS::getPosOfTimeStep(int iteration, int order) const { - std::string oldName(getMeshName()); - std::vector< std::pair > v(1); - v[0].first=oldName; v[0].second=newMeshName; - changeMeshNames(v); + return contentNotNullBase()->getPosOfTimeStep(iteration,order); } -bool MEDFileFieldMultiTSWithoutSDA::changeMeshNames(const std::vector< std::pair >& modifTab) throw(INTERP_KERNEL::Exception) +int MEDFileAnyTypeFieldMultiTS::getPosGivenTime(double time, double eps) const { - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileField1TSWithoutSDA *cur(*it); - if(cur) - ret=cur->changeMeshNames(modifTab) || ret; - } - return ret; + return contentNotNullBase()->getPosGivenTime(time,eps); } -bool MEDFileFieldMultiTSWithoutSDA::renumberEntitiesLyingOnMesh(const char *meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, - MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +int MEDFileAnyTypeFieldMultiTS::getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector& levs) const { - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileField1TSWithoutSDA *f1ts(*it); - if(f1ts) - ret=f1ts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,glob) || ret; - } - return ret; + return contentNotNullBase()->getNonEmptyLevels(iteration,order,mname,levs); } -void MEDFileFieldMultiTSWithoutSDA::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::getTypesOfFieldAvailable() const { - if(_time_steps.empty()) - { - MEDCouplingAutoRefCountObjectPtr obj=new MEDFileField1TSWithoutSDA; - obj->setFieldNoProfileSBT(field,glob); - copyTinyInfoFrom(field); - _time_steps.push_back(obj); - } - else - { - checkCoherencyOfTinyInfo(field); - MEDCouplingAutoRefCountObjectPtr obj=new MEDFileField1TSWithoutSDA; - obj->setFieldNoProfileSBT(field,glob); - _time_steps.push_back(obj); - } + return contentNotNullBase()->getTypesOfFieldAvailable(); } -void MEDFileFieldMultiTSWithoutSDA::appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception) +std::vector< std::vector< std::pair > > MEDFileAnyTypeFieldMultiTS::getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const { - if(_time_steps.empty()) - { - MEDCouplingAutoRefCountObjectPtr obj=new MEDFileField1TSWithoutSDA; - obj->setFieldProfile(field,mesh,meshDimRelToMax,profile,glob); - copyTinyInfoFrom(field); - _time_steps.push_back(obj); - } - else - { - checkCoherencyOfTinyInfo(field); - MEDCouplingAutoRefCountObjectPtr obj=new MEDFileField1TSWithoutSDA; - obj->setFieldProfile(field,mesh,meshDimRelToMax,profile,glob); - _time_steps.push_back(obj); - } + return contentNotNullBase()->getFieldSplitedByType(iteration,order,mname,types,typesF,pfls,locs); } -std::string MEDFileFieldMultiTSWithoutSDA::getDtUnit() const throw(INTERP_KERNEL::Exception) +std::string MEDFileAnyTypeFieldMultiTS::getName() const { - if(_time_steps.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getMeshName : not time steps !"); - return _time_steps[0]->getDtUnit(); + return contentNotNullBase()->getName(); } -std::string MEDFileFieldMultiTSWithoutSDA::getName() const +void MEDFileAnyTypeFieldMultiTS::setName(const std::string& name) { - return _name; + contentNotNullBase()->setName(name); } -void MEDFileFieldMultiTSWithoutSDA::setName(const char *name) +std::string MEDFileAnyTypeFieldMultiTS::getDtUnit() const { - _name=name; + return contentNotNullBase()->getDtUnit(); } -void MEDFileFieldMultiTSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const +void MEDFileAnyTypeFieldMultiTS::setDtUnit(const std::string& dtUnit) { - std::string startLine(bkOffset,' '); - oss << startLine << "Field multi time steps"; - if(fmtsId>=0) - oss << " (" << fmtsId << ")"; - oss << " has the following name: \"" << _name << "\"." << std::endl; - oss << startLine << "Field multi time steps has " << _infos.size() << " components with the following infos :" << std::endl; - for(std::vector::const_iterator it=_infos.begin();it!=_infos.end();it++) - { - oss << startLine << " - \"" << *it << "\"" << std::endl; - } - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) - { - std::string chapter(17,'0'+i); - oss << startLine << chapter << std::endl; - const MEDFileField1TSWithoutSDA *cur=(*it); - if(cur) - cur->simpleRepr(bkOffset+2,oss,i); - else - oss << startLine << " Field on one time step #" << i << " is not defined !" << std::endl; - oss << startLine << chapter << std::endl; - } + contentNotNullBase()->setDtUnit(dtUnit); } -std::vector< std::pair > MEDFileFieldMultiTSWithoutSDA::getTimeSteps(std::vector& ret1) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const { - std::size_t sz=_time_steps.size(); - std::vector< std::pair > ret(sz); - ret1.resize(sz); - for(std::size_t i=0;igetTime(ret[i].first,ret[i].second); - } - else - { - std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getTimeSteps : At rank #" << i << " time step is not defined. Invoke eraseEmptyTS method !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; + contentNotNullBase()->simpleRepr(bkOffset,oss,fmtsId); } -void MEDFileFieldMultiTSWithoutSDA::finishLoading(med_idt fid, int nbPdt) throw(INTERP_KERNEL::Exception) +std::vector< std::pair > MEDFileAnyTypeFieldMultiTS::getTimeSteps(std::vector& ret1) const { - _time_steps.resize(nbPdt); - for(int i=0;i > ts; - med_int numdt=0,numo=0; - med_int meshIt=0,meshOrder=0; - med_float dt=0.0; - MEDfieldComputingStepMeshInfo(fid,_name.c_str(),i+1,&numdt,&numo,&dt,&meshIt,&meshOrder); - _time_steps[i]=MEDFileField1TSWithoutSDA::New(_name.c_str(),i+1,_field_type,numdt,numo,_infos); - _time_steps[i]->finishLoading(fid); - } + return contentNotNullBase()->getTimeSteps(ret1); } -void MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) +std::string MEDFileAnyTypeFieldMultiTS::getMeshName() const { - _name=field->getName(); - if(_name.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom : unsupported fields with no name in MED file !"); - const DataArrayDouble *arr=field->getArray(); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom : no array set !"); - _infos=arr->getInfoOnComponents(); + return contentNotNullBase()->getMeshName(); } -void MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo(const MEDCouplingFieldDouble *field) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::setMeshName(const std::string& newMeshName) { - static const char MSG[]="MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo : invalid "; - if(_name!=field->getName()) - { - std::ostringstream oss; oss << MSG << "name ! should be \"" << _name; - oss << "\" and it is set in input field to \"" << field->getName() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayDouble *arr=field->getArray(); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo : no array set !"); - if(_infos!=arr->getInfoOnComponents()) - { - std::ostringstream oss; oss << MSG << "components ! should be \""; - std::copy(_infos.begin(),_infos.end(),std::ostream_iterator(oss,", ")); - oss << " But compo in input fields are : "; - std::vector tmp=arr->getInfoOnComponents(); - std::copy(tmp.begin(),tmp.end(),std::ostream_iterator(oss,", ")); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + contentNotNullBase()->setMeshName(newMeshName); } -void MEDFileFieldMultiTSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts) const throw(INTERP_KERNEL::Exception) +bool MEDFileAnyTypeFieldMultiTS::changeMeshNames(const std::vector< std::pair >& modifTab) { - if(_time_steps.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::writeLL : no time steps set !"); - std::vector infos(getInfo()); - int nbComp=infos.size(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - for(int i=0;iwriteLL(fid,opts); + return contentNotNullBase()->changeMeshNames(modifTab); } -int MEDFileFieldMultiTSWithoutSDA::getNumberOfTS() const +const std::vector& MEDFileAnyTypeFieldMultiTS::getInfo() const { - return _time_steps.size(); + return contentNotNullBase()->getInfo(); } -void MEDFileFieldMultiTSWithoutSDA::eraseEmptyTS() throw(INTERP_KERNEL::Exception) +bool MEDFileAnyTypeFieldMultiTS::presenceOfMultiDiscPerGeoType() const { - std::vector< MEDCouplingAutoRefCountObjectPtr > newTS; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - const MEDFileField1TSWithoutSDA *tmp=(*it); - if(tmp) - newTS.push_back(*it); - } - _time_steps=newTS; + return contentNotNullBase()->presenceOfMultiDiscPerGeoType(); } -void MEDFileFieldMultiTSWithoutSDA::eraseTimeStepIds(const int *startIds, const int *endIds) throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::setInfo(const std::vector& info) { - std::vector< MEDCouplingAutoRefCountObjectPtr > newTS; - int maxId=(int)_time_steps.size(); - int ii=0; - std::set idsToDel; - for(const int *id=startIds;id!=endIds;id++,ii++) - { - if(*id>=0 && *idsetInfo(info); } -int MEDFileFieldMultiTSWithoutSDA::getPosOfTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception) +int MEDFileAnyTypeFieldMultiTS::getNumberOfComponents() const { - int ret=0; - std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getPosOfTimeStep : No such time step (" << iteration << "," << order << ") !\nPossibilities are : "; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) - { - const MEDFileField1TSWithoutSDA *tmp(*it); - if(tmp) - { - int it2,ord; - tmp->getTime(it2,ord); - if(it2==iteration && order==ord) - return ret; - else - oss << "(" << it2 << "," << ord << "), "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); + const std::vector ret=getInfo(); + return (int)ret.size(); } -int MEDFileFieldMultiTSWithoutSDA::getPosGivenTime(double time, double eps) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::writeLL(med_idt fid) const { - int ret=0; - std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getPosGivenTime : No such time step " << time << "! \nPossibilities are : "; - oss.precision(15); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) - { - const MEDFileField1TSWithoutSDA *tmp(*it); - if(tmp) - { - int it2,ord; - double ti=tmp->getTime(it2,ord); - if(fabs(time-ti)writeLL(fid,*this); } -std::vector< std::pair > MEDFileFieldMultiTSWithoutSDA::getIterations() const +/*! + * Writes \a this field into a MED file specified by its name. + * \param [in] fileName - the MED file name. + * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. + * - 2 - erase; an existing file is removed. + * - 1 - append; same data should not be present in an existing file. + * - 0 - overwrite; same data present in an existing file is overwritten. + * \throw If the field name is not set. + * \throw If no field data is set. + * \throw If \a mode == 1 and the same data is present in an existing file. + */ +void MEDFileAnyTypeFieldMultiTS::write(const std::string& fileName, int mode) const { - int lgth=_time_steps.size(); - std::vector< std::pair > ret(lgth); - for(int i=0;ifillIteration(ret[i]); - return ret; + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + writeLL(fid); } /*! - * This method has 3 inputs 'iteration' 'order' 'mname'. 'mname' can be null if the user is the general case where there is only one meshName lying on 'this' - * This method returns two things. - * - The absolute dimension of 'this' in first parameter. - * - The available ext levels relative to the absolute dimension returned in first parameter. These relative levels are relative - * to the first output parameter. The values in 'levs' will be returned in decreasing order. - * - * This method is designed for MEDFileFieldMultiTS instances that have a discritization ON_CELLS, ON_GAUSS_NE and ON_GAUSS. - * Only these 3 discretizations will be taken into account here. - * - * If 'this' is empty this method will throw an INTERP_KERNEL::Exception. - * If there is \b only node fields defined in 'this' -1 is returned and 'levs' output parameter will be empty. In this - * case the caller has to know the underlying mesh it refers to. By defaut it is the level 0 of the corresponding mesh. - * - * This method is usefull to make the link between meshDimension of the underlying mesh in 'this' and the levels on 'this'. - * It is possible (even if it is not common) that the highest level in 'this' were not equal to the meshDimension of the underlying mesh in 'this'. - * - * Let's consider the typical following case : - * - a mesh 'm1' has a meshDimension 3 and has the following non empty levels - * [0,-1,-2] for example 'm1' lies on TETRA4, HEXA8 TRI3 and SEG2 - * - 'f1' lies on 'm1' and is defined on 3D and 1D cells for example - * TETRA4 and SEG2 - * - 'f2' lies on 'm1' too and is defined on 2D and 1D cells for example TRI3 and SEG2 - * - * In this case f1->getNonEmptyLevelsExt will return (3,[0,-2]) and f2->getNonEmptyLevelsExt will return (2,[0,-1]) + * This method alloc the arrays and load potentially huge arrays contained in this field. + * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter. + * This method can be also called to refresh or reinit values from a file. * - * To retrieve the highest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+0);//absDim-meshDim+relativeLev - * To retrieve the lowest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+(-2));//absDim-meshDim+relativeLev - * To retrieve the highest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+0);//absDim-meshDim+relativeLev - * To retrieve the lowest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+(-1));//absDim-meshDim+relativeLev + * \throw If the fileName is not set or points to a non readable MED file. */ -int MEDFileFieldMultiTSWithoutSDA::getNonEmptyLevels(int iteration, int order, const char *mname, std::vector& levs) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::loadArrays() { - return getTimeStepEntry(iteration,order).getNonEmptyLevels(mname,levs); + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::loadArrays : the structure does not come from a file !"); + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + contentNotNullBase()->loadBigArraysRecursively(fid,*contentNotNullBase()); } -std::vector< std::vector > MEDFileFieldMultiTSWithoutSDA::getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) +/*! + * This method behaves as MEDFileAnyTypeFieldMultiTS::loadArrays does, the first call, if \a this was built using a file without loading big arrays. + * But once data loaded once, this method does nothing. + * + * \throw If the fileName is not set or points to a non readable MED file. + * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::unloadArrays + */ +void MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary() { - int lgth=_time_steps.size(); - std::vector< std::vector > ret(lgth); - for(int i=0;ifillTypesOfFieldAvailable(ret[i]); - return ret; + if(!getFileName().empty()) + { + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + contentNotNullBase()->loadBigArraysRecursivelyIfNecessary(fid,*contentNotNullBase()); + } } /*! - * entry point for users that want to iterate into MEDFile DataStructure without any overhead. + * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. + * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. + * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss instead. + * + * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary, MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss */ -std::vector< std::vector< std::pair > > MEDFileFieldMultiTSWithoutSDA::getFieldSplitedByType(int iteration, int order, const char *mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::unloadArrays() { - return getTimeStepEntry(iteration,order).getFieldSplitedByType(mname,types,typesF,pfls,locs); + contentNotNullBase()->unloadArrays(); } /*! - * entry point for users that want to iterate into MEDFile DataStructure with a reduced overhead because output arrays are extracted (created) specially - * for the call of this method. That's why the DataArrayDouble instance in returned vector of vector should be dealed by the caller. + * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. + * This method is the symetrical method of MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary. + * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. + * + * \sa MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary */ -std::vector< std::vector > MEDFileFieldMultiTSWithoutSDA::getFieldSplitedByType2(int iteration, int order, const char *mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception) +void MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss() { - return getTimeStepEntry(iteration,order).getFieldSplitedByType2(mname,types,typesF,pfls,locs); + if(!getFileName().empty()) + contentNotNullBase()->unloadArrays(); } -const MEDFileField1TSWithoutSDA& MEDFileFieldMultiTSWithoutSDA::getTimeStepEntry(int iteration, int order) const throw(INTERP_KERNEL::Exception) +std::string MEDFileAnyTypeFieldMultiTS::simpleRepr() const { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - if((*it)->isDealingTS(iteration,order)) - return *(*it); - std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepEntry : Muli timestep field on time (" << iteration << "," << order << ") does not exist ! Available (iteration,order) are :\n"; - std::vector< std::pair > vp=getIterations(); - for(std::vector< std::pair >::const_iterator it2=vp.begin();it2!=vp.end();it2++) - oss << "(" << (*it2).first << "," << (*it2).second << ") "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + std::ostringstream oss; + contentNotNullBase()->simpleRepr(0,oss,-1); + simpleReprGlobs(oss); + return oss.str(); } -MEDFileField1TSWithoutSDA& MEDFileFieldMultiTSWithoutSDA::getTimeStepEntry(int iteration, int order) throw(INTERP_KERNEL::Exception) +std::size_t MEDFileAnyTypeFieldMultiTS::getHeapMemorySizeWithoutChildren() const { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - if((*it)->isDealingTS(iteration,order)) - return *(*it); - std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepEntry : Muli timestep field on time (" << iteration << "," << order << ") does not exist ! Available (iteration,order) are :\n"; - std::vector< std::pair > vp=getIterations(); - for(std::vector< std::pair >::const_iterator it2=vp.begin();it2!=vp.end();it2++) - oss << "(" << (*it2).first << "," << (*it2).second << ") "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + return MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren(); } -const MEDFileField1TSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::getTimeStepAtPos2(int pos) const throw(INTERP_KERNEL::Exception) +std::vector MEDFileAnyTypeFieldMultiTS::getDirectChildrenWithNull() const { - if(pos<0 || pos>=(int)_time_steps.size()) - { - std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << " whereas should be in [0," << _time_steps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileField1TSWithoutSDA *item=_time_steps[pos]; - if(item==0) - { - std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << ", this pos id exists but the underlying Field1TS is null !"; - oss << "\nTry to use following method eraseEmptyTS !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return item; + std::vector ret(MEDFileFieldGlobsReal::getDirectChildrenWithNull()); + ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content); + return ret; } -MEDFileField1TSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::getTimeStepAtPos2(int pos) throw(INTERP_KERNEL::Exception) +/*! + * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of components in \a this. + * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this. + * ** WARNING ** do no forget to rename the ouput instances to avoid to write n-times in the same MED file field ! + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitComponents() const { - if(pos<0 || pos>=(int)_time_steps.size()) - { - std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << " whereas should be in [0," << _time_steps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileField1TSWithoutSDA *item=_time_steps[pos]; - if(item==0) + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitComponents : no content in this ! Unable to split components !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit=content->splitComponents(); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); + for(std::size_t i=0;i_content=contentsSplit[i]; } - return item; + return ret; } -std::vector MEDFileFieldMultiTSWithoutSDA::getPflsReallyUsed2() const +/*! + * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of discretizations over time steps in \a this. + * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitDiscretizations() const { - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitDiscretizations : no content in this ! Unable to split discretizations !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitDiscretizations()); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); + for(std::size_t i=0;i tmp=(*it)->getPflsReallyUsed2(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } + ret[i]=shallowCpy(); + ret[i]->_content=contentsSplit[i]; } return ret; } -std::vector MEDFileFieldMultiTSWithoutSDA::getLocsReallyUsed2() const +/*! + * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of sub-discretizations over time steps in \a this. + * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes() const { - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretizations !"); + std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitMultiDiscrPerGeoTypes()); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); + for(std::size_t i=0;i tmp=(*it)->getLocsReallyUsed2(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } + ret[i]=shallowCpy(); + ret[i]->_content=contentsSplit[i]; } return ret; } -std::vector MEDFileFieldMultiTSWithoutSDA::getPflsReallyUsedMulti2() const +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::deepCpy() const { - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); + if((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content) + ret->_content=_content->deepCpy(); + ret->deepCpyGlobs(*this); + return ret.retn(); +} + +MEDCouplingAutoRefCountObjectPtr MEDFileAnyTypeFieldMultiTS::getContent() +{ + return _content; +} + +/*! + * Returns a new MEDFileField1TS or MEDFileIntField1TS holding data of a given time step of \a this field. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \return MEDFileField1TS * or MEDFileIntField1TS *- a new instance of MEDFileField1TS or MEDFileIntField1TS. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If there is no required time step in \a this field. + */ +MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTS::getTimeStep(int iteration, int order) const +{ + int pos=getPosOfTimeStep(iteration,order); + return getTimeStepAtPos(pos); +} + +/*! + * Returns a new MEDFileField1TS or MEDFileIntField1TS holding data of a given time step of \a this field. + * \param [in] time - the time of the time step of interest. + * \param [in] eps - a precision used to compare time values. + * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If there is no required time step in \a this field. + */ +MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTS::getTimeStepGivenTime(double time, double eps) const +{ + int pos=getPosGivenTime(time,eps); + return getTimeStepAtPos(pos); +} + +/*! + * This method groups not null items in \a vectFMTS per time step series. Two time series are considered equal if the list of their pair of integers iteration,order are equal. + * The float64 value of time attached to the pair of integers are not considered here. + * WARNING the returned pointers are not incremented. The caller is \b not responsible to deallocate them ! This method only reorganizes entries in \a vectFMTS. + * + * \param [in] vectFMTS - vector of not null fields defined on a same global data pointer. + * \throw If there is a null pointer in \a vectFMTS. + */ +std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(const std::vector& vectFMTS) +{ + static const char msg[]="MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries : presence of null instance in input vector !"; + std::vector< std::vector > ret; + std::list lstFMTS(vectFMTS.begin(),vectFMTS.end()); + while(!lstFMTS.empty()) + { + std::list::iterator it(lstFMTS.begin()); + MEDFileAnyTypeFieldMultiTS *curIt(*it); + if(!curIt) + throw INTERP_KERNEL::Exception(msg); + std::vector< std::pair > refIts=curIt->getIterations(); + std::vector elt; + elt.push_back(curIt); it=lstFMTS.erase(it); + while(it!=lstFMTS.end()) + { + curIt=*it; + if(!curIt) + throw INTERP_KERNEL::Exception(msg); + std::vector< std::pair > curIts=curIt->getIterations(); + if(refIts==curIts) + { elt.push_back(curIt); it=lstFMTS.erase(it); } + else + it++; + } + ret.push_back(elt); + } + return ret; +} + +/*! + * This method splits the input list \a vectFMTS considering the aspect of the geometrical support over time. + * All returned instances in a subvector can be safely loaded, rendered along time + * All items must be defined on the same time step ids ( see MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries method ). + * Each item in \a vectFMTS is expected to have one and exactly one spatial discretization along time. + * All items in \a vectFMTS must lie on the mesh (located by meshname and time step) and compatible with the input mesh \a mesh (having the same name than those in items). + * All items in \a vectFMTS whose spatial discretization is not ON_NODES will appear once. + * For items in \a vectFMTS that are ON_NODES it is possible to appear several times (more than once or once) in the returned vector. + * + * \param [in] vectFMTS - list of multi times step part all defined each on a same spatial discretization along time and pointing to a mesh whose name is equal to \c mesh->getName(). + * \param [in] mesh - the mesh shared by all items in \a vectFMTS across time. + * \param [out] fsc - A vector having same size than returned vector. It specifies the support comporator of the corresponding vector of MEDFileAnyTypeFieldMultiTS in returned vector of vector. + * \return - A vector of vector of objects that contains the same pointers (objects) than thoose in \a vectFMTS except that there are organized differently. So pointers included in returned vector of vector should \b not been dealt by the caller. + * + * \throw If an element in \a vectFMTS has not only one spatial discretization set. + * \throw If an element in \a vectFMTS change of spatial discretization along time. + * \throw If an element in \a vectFMTS lies on a mesh with meshname different from those in \a mesh. + * \thorw If some elements in \a vectFMTS do not have the same times steps. + * \throw If mesh is null. + * \throw If an element in \a vectFMTS is null. + * \sa MEDFileAnyTypeFieldMultiTS::AreOnSameSupportAcrossTime + */ +std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(const std::vector& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr >& fsc) +{ + static const char msg[]="MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : presence of a null instance in the input vector !"; + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : input mesh is null !"); + std::vector< std::vector > ret; + if(vectFMTS.empty()) + return ret; + std::vector::const_iterator it(vectFMTS.begin()); + MEDFileAnyTypeFieldMultiTS *frstElt(*it); + if(!frstElt) + throw INTERP_KERNEL::Exception(msg); + std::size_t i=0; + std::vector vectFMTSNotNodes; + std::vector vectFMTSNodes; + for(;it!=vectFMTS.end();it++,i++) + { + if(!(*it)) + throw INTERP_KERNEL::Exception(msg); + TypeOfField tof0,tof1; + if(CheckSupportAcrossTime(frstElt,*it,mesh,tof0,tof1)>0) + { + if(tof1!=ON_NODES) + vectFMTSNotNodes.push_back(*it); + else + vectFMTSNodes.push_back(*it); + } + else + vectFMTSNotNodes.push_back(*it); + } + std::vector< MEDCouplingAutoRefCountObjectPtr > cmps; + std::vector< std::vector > retCell=SplitPerCommonSupportNotNodesAlg(vectFMTSNotNodes,mesh,cmps); + ret=retCell; + for(std::vector::const_iterator it2=vectFMTSNodes.begin();it2!=vectFMTSNodes.end();it2++) { - std::vector tmp=(*it)->getPflsReallyUsedMulti2(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); + i=0; + bool isFetched(false); + for(std::vector< std::vector >::const_iterator it0=retCell.begin();it0!=retCell.end();it0++,i++) + { + if((*it0).empty()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : internal error !"); + if(cmps[i]->isCompatibleWithNodesDiscr(*it2)) + { ret[i].push_back(*it2); isFetched=true; } + } + if(!isFetched) + { + std::vector tmp(1,*it2); + MEDCouplingAutoRefCountObjectPtr tmp2(MEDFileMeshStruct::New(mesh)); + ret.push_back(tmp); retCell.push_back(tmp); cmps.push_back(MEDFileFastCellSupportComparator::New(tmp2,*it2)); + } } + fsc=cmps; return ret; } -std::vector MEDFileFieldMultiTSWithoutSDA::getLocsReallyUsedMulti2() const +/*! + * WARNING no check here. The caller must be sure that all items in vectFMTS are coherent each other in time steps, only one same spatial discretization and not ON_NODES. + * \param [out] cmps - same size than the returned vector. + */ +std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupportNotNodesAlg(const std::vector& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr >& cmps) { - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + std::vector< std::vector > ret; + std::list lstFMTS(vectFMTS.begin(),vectFMTS.end()); + while(!lstFMTS.empty()) { - std::vector tmp=(*it)->getLocsReallyUsedMulti2(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); + std::list::iterator it(lstFMTS.begin()); + MEDFileAnyTypeFieldMultiTS *ref(*it); + std::vector elt; + elt.push_back(ref); it=lstFMTS.erase(it); + MEDCouplingAutoRefCountObjectPtr mst(MEDFileMeshStruct::New(mesh)); + MEDCouplingAutoRefCountObjectPtr cmp(MEDFileFastCellSupportComparator::New(mst,ref)); + while(it!=lstFMTS.end()) + { + MEDFileAnyTypeFieldMultiTS *curIt(*it); + if(cmp->isEqual(curIt)) + { elt.push_back(curIt); it=lstFMTS.erase(it); } + else + it++; + } + ret.push_back(elt); cmps.push_back(cmp); } return ret; } -void MEDFileFieldMultiTSWithoutSDA::changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileField1TSWithoutSDA > >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - (*it)->changePflsRefsNamesGen2(mapOfModif); +/*! + * This method scan the two main structs along time of \a f0 and \a f1 to see if there are all lying on the same mesh along time than those in \a mesh. + * \a f0 and \a f1 must be defined each only on a same spatial discretization even if this can be different each other. + * + * \throw If \a f0 or \a f1 has not only one spatial discretization set. + * \throw If \a f0 or \a f1 change of spatial discretization along time. + * \throw If \a f0 or \a f1 on a mesh with meshname different from those in \a mesh. + * \thorw If \a f0 and \a f1 do not have the same times steps. + * \throw If mesh is null. + * \throw If \a f0 or \a f1 is null. + * \sa MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport + */ +int MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime(MEDFileAnyTypeFieldMultiTS *f0, MEDFileAnyTypeFieldMultiTS *f1, const MEDFileMesh *mesh, TypeOfField& tof0, TypeOfField& tof1) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : input mesh is null !"); + if(!f0 || !f1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : presence of null instance in fields over time !"); + if(f0->getMeshName()!=mesh->getName()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : first field points to mesh \""<< f0->getMeshName() << "\" and input mesh to compare has name \"" << mesh->getName() << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(f1->getMeshName()!=mesh->getName()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : second field points to mesh \""<< f1->getMeshName() << "\" and input mesh to compare has name \"" << mesh->getName() << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nts=f0->getNumberOfTS(); + if(nts!=f1->getNumberOfTS()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : number of time steps are not the same !"); + if(nts==0) + return nts; + for(int i=0;i f0cur=f0->getTimeStepAtPos(i); + MEDCouplingAutoRefCountObjectPtr f1cur=f1->getTimeStepAtPos(i); + std::vector tofs0(f0cur->getTypesOfFieldAvailable()),tofs1(f1cur->getTypesOfFieldAvailable()); + if(tofs0.size()!=1 || tofs1.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : All time steps must be defined on only one spatial discretization !"); + if(i!=0) + { + if(tof0!=tofs0[0] || tof1!=tofs1[0]) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : Across times steps MEDFileAnyTypeFieldMultiTS instances have to keep the same unique spatial discretization !"); + } + else + { tof0=tofs0[0]; tof1=tofs1[0]; } + if(f0cur->getMeshIteration()!=mesh->getIteration() || f0cur->getMeshOrder()!=mesh->getOrder()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : first field points to mesh time step (" << f0cur->getMeshIteration() << ","<< f0cur->getMeshOrder() << ") whereas input mesh points to time step (" << mesh->getIteration() << "," << mesh->getOrder() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(f1cur->getMeshIteration()!=mesh->getIteration() || f1cur->getMeshOrder()!=mesh->getOrder()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : second field points to mesh time step (" << f1cur->getMeshIteration() << ","<< f1cur->getMeshOrder() << ") whereas input mesh points to time step (" << mesh->getIteration() << "," << mesh->getOrder() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(f0cur->getIteration()!=f1cur->getIteration() || f0cur->getOrder()!=f1cur->getOrder()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : all the time steps must be the same ! it is not the case (" << f0cur->getIteration() << "," << f0cur->getOrder() << ")!=(" << f1cur->getIteration() << "," << f1cur->getOrder() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return nts; } -void MEDFileFieldMultiTSWithoutSDA::changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeFieldMultiTSIterator *MEDFileAnyTypeFieldMultiTS::iterator() { - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileField1TSWithoutSDA > >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - (*it)->changeLocsRefsNamesGen2(mapOfModif); + return new MEDFileAnyTypeFieldMultiTSIterator(this); } +//= MEDFileFieldMultiTS + /*! * Returns a new empty instance of MEDFileFieldMultiTS. * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller @@ -5781,9 +8936,11 @@ MEDFileFieldMultiTS *MEDFileFieldMultiTS::New() * is to delete this field using decrRef() as it is no more needed. * \throw If reading the file fails. */ -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception) +MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const std::string& fileName, bool loadAll) { - return new MEDFileFieldMultiTS(fileName); + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldMultiTS(fileName,loadAll,0); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); } /*! @@ -5796,15 +8953,21 @@ MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const char *fileName) throw(INTERP * \throw If reading the file fails. * \throw If there is no field named \a fieldName in the file. */ -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) +MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) { - return new MEDFileFieldMultiTS(fileName,fieldName); + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldMultiTS(fileName,fieldName,loadAll,0); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); } /*! - * Returns a new instance of MEDFileFieldMultiTS holding either deep or shallow copy - * of a given MEDFileFieldMultiTSWithoutSDA. - * \param [in] other - a MEDFileFieldMultiTSWithoutSDA to copy. + * Returns a new instance of MEDFileFieldMultiTS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * Returns a new instance of MEDFileFieldMultiTS holding either a shallow copy + * of a given MEDFileFieldMultiTSWithoutSDA ( \a other ) or \a other itself. + * \warning this is a shallow copy constructor + * \param [in] other - a MEDFileField1TSWithoutSDA to copy. * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller * is to delete this field using decrRef() as it is no more needed. @@ -5812,103 +8975,82 @@ MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const char *fileName, const char * MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) { return new MEDFileFieldMultiTS(other,shallowCopyOfContent); -} - -std::size_t MEDFileFieldMultiTS::getHeapMemorySize() const -{ - std::size_t ret=0; - if((const MEDFileFieldMultiTSWithoutSDA*)_content) - ret+=_content->getHeapMemorySize(); - return ret+MEDFileFieldGlobsReal::getHeapMemorySize(); -} - -MEDFileFieldMultiTS *MEDFileFieldMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldMultiTS(*this); - if((const MEDFileFieldMultiTSWithoutSDA *)_content) - ret->_content=_content->deepCpy(); - ret->deepCpyGlobs(*this); - return ret.retn(); -} - -/*! - * Returns a new MEDFileField1TS holding data of a given time step of \a this field. - * \param [in] pos - a time step id. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If \a pos is not a valid time step id. - */ -MEDFileField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception) -{ - const MEDFileField1TSWithoutSDA *item=_content->getTimeStepAtPos2(pos); - MEDCouplingAutoRefCountObjectPtr ret=MEDFileField1TS::New(*item,false); - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -/*! - * Returns a new MEDFileField1TS holding data of a given time step of \a this field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If there is no required time step in \a this field. - */ -MEDFileField1TS *MEDFileFieldMultiTS::getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception) -{ - int pos=getPosOfTimeStep(iteration,order); - return getTimeStepAtPos(pos); -} - -/*! - * Returns a new MEDFileField1TS holding data of a given time step of \a this field. - * \param [in] time - the time of the time step of interest. - * \param [in] eps - a precision used to compare time values. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If there is no required time step in \a this field. - */ -MEDFileField1TS *MEDFileFieldMultiTS::getTimeStepGivenTime(double time, double eps) const throw(INTERP_KERNEL::Exception) +} + +MEDFileFieldMultiTS *MEDFileFieldMultiTS::LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll) { - int pos=getPosGivenTime(time,eps); - return getTimeStepAtPos(pos); + MEDCouplingAutoRefCountObjectPtr ret(new MEDFileFieldMultiTS(fileName,fieldName,loadAll,0,&entities)); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); } -MEDFileFieldMultiTSIterator *MEDFileFieldMultiTS::iterator() throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeFieldMultiTS *MEDFileFieldMultiTS::shallowCpy() const { - return new MEDFileFieldMultiTSIterator(this); + return new MEDFileFieldMultiTS(*this); } -std::string MEDFileFieldMultiTS::simpleRepr() const +void MEDFileFieldMultiTS::checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const { - std::ostringstream oss; - _content->simpleRepr(0,oss,-1); - MEDFileFieldGlobsReal::simpleRepr(oss); - return oss.str(); + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); + const MEDFileField1TS *f1tsC=dynamic_cast(f1ts); + if(!f1tsC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::checkCoherencyOfType : the input field1TS is not a FLOAT64 type !"); } -void MEDFileFieldMultiTS::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) +/*! + * This method performs a copy with datatype modification ( float64->int32 ) of \a this. The globals information are copied + * following the given input policy. + * + * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) + * By default (true) the globals are deeply copied. + * \return MEDFileIntFieldMultiTS * - a new object that is the result of the conversion of \a this to int32 field. + */ +MEDFileIntFieldMultiTS *MEDFileFieldMultiTS::convertToInt(bool isDeepCpyGlobs) const { - writeGlobals(fid,*this); - _content->writeLL(fid,*this); + MEDCouplingAutoRefCountObjectPtr ret; + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(content) + { + const MEDFileFieldMultiTSWithoutSDA *contc=dynamic_cast(content); + if(!contc) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::convertToInt : the content inside this is not FLOAT64 ! This is incoherent !"); + MEDCouplingAutoRefCountObjectPtr newc(contc->convertToInt()); + ret=static_cast(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent((MEDFileIntFieldMultiTSWithoutSDA *)newc,getFileName())); + } + else + ret=MEDFileIntFieldMultiTS::New(); + if(isDeepCpyGlobs) + ret->deepCpyGlobs(*this); + else + ret->shallowCpyGlobs(*this); + return ret.retn(); } /*! - * Writes \a this field into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the field name is not set. - * \throw If no field data is set. - * \throw If \a mode == 1 and the same data is present in an existing file. + * Returns a new MEDFileField1TS holding data of a given time step of \a this field. + * \param [in] pos - a time step id. + * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If \a pos is not a valid time step id. */ -void MEDFileFieldMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const { - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod); - writeLL(fid); + const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos); + if(!item) + { + std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepAtPos : field at pos #" << pos << " is null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileField1TSWithoutSDA *itemC=dynamic_cast(item); + if(itemC) + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileField1TS::New(*itemC,false); + ret->shallowCpyGlobs(*this); + return ret.retn(); + } + std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepAtPos : type of field at pos #" << pos << " is not FLOAT64 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } /*! @@ -5933,10 +9075,16 @@ void MEDFileFieldMultiTS::write(const char *fileName, int mode) const throw(INTE * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. * \throw If no field values of the required parameters are available. */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol) const { - const MEDFileField1TSWithoutSDA& myF1TS=_content->getTimeStepEntry(iteration,order); - return myF1TS.getFieldAtLevel(type,meshDimRelToMax,0,renumPol,this); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtLevel : mismatch of type of field expecting FLOAT64 !"); + MEDCouplingAutoRefCountObjectPtr arrOut; + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNullBase()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); } /*! @@ -5959,10 +9107,16 @@ MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevel(TypeOfField type, i * \throw If there is no mesh in the MED file. * \throw If no field values of the required parameters are available. */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol) const { - const MEDFileField1TSWithoutSDA& myF1TS=_content->getTimeStepEntry(iteration,order); - return myF1TS.getFieldAtTopLevel(type,0,renumPol,this); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtTopLevel : mismatch of type of field !"); + MEDCouplingAutoRefCountObjectPtr arrOut; + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNullBase()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); } /*! @@ -5987,10 +9141,16 @@ MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtTopLevel(TypeOfField type * \throw If no field of \a this is lying on \a mesh. * \throw If no field values of the required parameters are available. */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const { - const MEDFileField1TSWithoutSDA& myF1TS=_content->getTimeStepEntry(iteration,order); - return myF1TS.getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field !"); + MEDCouplingAutoRefCountObjectPtr arrOut; + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arrOut,*contentNotNullBase()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); } /*! @@ -6013,10 +9173,16 @@ MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField t * \throw If no field of \a this is lying on \a mesh. * \throw If no field values of the required parameters are available. */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol) const { - const MEDFileField1TSWithoutSDA& myF1TS=_content->getTimeStepEntry(iteration,order); - return myF1TS.getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field !"); + MEDCouplingAutoRefCountObjectPtr arrOut; + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arrOut,*contentNotNullBase()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); } /*! @@ -6024,10 +9190,16 @@ MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField t * This method is called 'old' because the user should give the mesh name he wants to use for it's field. * This method is useful for MED2 file format when field on different mesh was autorized. */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevelOld(TypeOfField type, const char *mname, int iteration, int order, int meshDimRelToMax, int renumPol) const throw(INTERP_KERNEL::Exception) +MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int iteration, int order, int meshDimRelToMax, int renumPol) const { - const MEDFileField1TSWithoutSDA& myF1TS=_content->getTimeStepEntry(iteration,order); - return myF1TS.getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtLevelOld : mismatch of type of field !"); + MEDCouplingAutoRefCountObjectPtr arrOut; + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNullBase()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); } /*! @@ -6050,10 +9222,36 @@ MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevelOld(TypeOfField type * \throw If no field of \a this is lying on \a mesh. * \throw If no field values of the required parameters are available. */ -DataArrayDouble *MEDFileFieldMultiTS::getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const throw(INTERP_KERNEL::Exception) +DataArrayDouble *MEDFileFieldMultiTS::getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldWithProfile : mismatch of type of field !"); + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNullBase()); + return MEDFileField1TS::ReturnSafelyDataArrayDouble(ret); +} + +const MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTS::contentNotNull() const +{ + const MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the content pointer is null !"); + const MEDFileFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); + return ret; +} + +MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTS::contentNotNull() { - const MEDFileField1TSWithoutSDA& myF1TS=_content->getTimeStepEntry(iteration,order); - return myF1TS.getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this); + MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the non const content pointer is null !"); + MEDFileFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the non const content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); + return ret; } /*! @@ -6068,306 +9266,613 @@ DataArrayDouble *MEDFileFieldMultiTS::getFieldWithProfile(TypeOfField type, int * \throw If the underlying mesh of \a field has no name. * \throw If elements in the mesh are not in the order suitable for writing to the MED file. */ -void MEDFileFieldMultiTS::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) +void MEDFileFieldMultiTS::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) { - _content->appendFieldNoProfileSBT(field,*this); + const DataArrayDouble *arr=0; + if(field) + arr=field->getArray(); + contentNotNull()->appendFieldNoProfileSBT(field,arr,*this); } /*! - * Adds a MEDCouplingFieldDouble to \a this as another time step. Specified entities of - * a given dimension of a given mesh are used as the support of the given field. - * Elements of the given mesh must be sorted suitable for writing to MED file. - * Order of underlying mesh entities of the given field specified by \a profile parameter - * is not prescribed; this method permutes field values to have them sorted by element - * type as required for writing to MED file. + * Adds a MEDCouplingFieldDouble to \a this as another time step. + * The mesh support of input parameter \a field is ignored here, it can be NULL. + * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, + * and \a profile. + * + * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. + * A new profile is added only if no equal profile is missing. * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. + * \param [in] field - the field to add to \a this. The mesh support of field is ignored. * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on. + * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). * \param [in] profile - ids of mesh entities on which corresponding field values lie. * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If existing time steps have different name or number of components than \a field. * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. * \throw If the data array of \a field is not set. + * \throw If the data array of \a this is already allocated but has different number of + * components than \a field. * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. + * \sa setFieldNoProfileSBT() */ -void MEDFileFieldMultiTS::appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception) +void MEDFileFieldMultiTS::appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) { - _content->appendFieldProfile(field,mesh,meshDimRelToMax,profile,*this); + const DataArrayDouble *arr=0; + if(field) + arr=field->getArray(); + contentNotNull()->appendFieldProfile(field,arr,mesh,meshDimRelToMax,profile,*this); } -MEDCouplingAutoRefCountObjectPtr MEDFileFieldMultiTS::getContent() +MEDFileFieldMultiTS::MEDFileFieldMultiTS() { - return _content; + _content=new MEDFileFieldMultiTSWithoutSDA; } -MEDFileFieldMultiTS::MEDFileFieldMultiTS():_content(new MEDFileFieldMultiTSWithoutSDA) +MEDFileFieldMultiTS::MEDFileFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeFieldMultiTS(fileName,loadAll,ms) { } +catch(INTERP_KERNEL::Exception& e) +{ throw e; } +MEDFileFieldMultiTS::MEDFileFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +try:MEDFileAnyTypeFieldMultiTS(fileName,fieldName,loadAll,ms,entities) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } +MEDFileFieldMultiTS::MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeFieldMultiTS(other,shallowCopyOfContent) +{ +} -MEDFileFieldMultiTS::MEDFileFieldMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception) -try:MEDFileFieldGlobsReal(fileName) +std::vector< std::vector > MEDFileFieldMultiTS::getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const { - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - int nbFields=MEDnField(fid); - if(nbFields<1) - { - std::ostringstream oss; oss << "MEDFileFieldMultiTS(const char *fileName) constructor : no fields in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _content=new MEDFileFieldMultiTSWithoutSDA(fid,0); - // - loadGlobals(fid); + return contentNotNull()->getFieldSplitedByType2(iteration,order,mname,types,typesF,pfls,locs); } -catch(INTERP_KERNEL::Exception& e) - { - throw e; - } -MEDFileFieldMultiTS::MEDFileFieldMultiTS(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) -try:MEDFileFieldGlobsReal(fileName) +DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArray(int iteration, int order) const { - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - int nbFields=MEDnField(fid); - med_field_type typcha; - bool found=false; - std::vector fns(nbFields); - for(int i=0;i comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localMesh; - int nbOfStep; - MEDfieldInfo(fid,i+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep); - std::string tmp(nomcha); - fns[i]=tmp; - found=(tmp==fieldName); - if(found) - _content=new MEDFileFieldMultiTSWithoutSDA(fid,i); - } - if(!found) + return static_cast(contentNotNull()->getUndergroundDataArray(iteration,order)); +} + +DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const +{ + return static_cast(contentNotNull()->getUndergroundDataArrayExt(iteration,order,entries)); +} + +//= MEDFileAnyTypeFieldMultiTSIterator + +MEDFileAnyTypeFieldMultiTSIterator::MEDFileAnyTypeFieldMultiTSIterator(MEDFileAnyTypeFieldMultiTS *fmts):_fmts(fmts),_iter_id(0),_nb_iter(0) +{ + if(fmts) { - std::ostringstream oss; oss << "No such field '" << fieldName << "' in file '" << fileName << "' ! Available fields are : "; - std::copy(fns.begin(),fns.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); + fmts->incrRef(); + _nb_iter=fmts->getNumberOfTS(); } - // - loadGlobals(fid); } -catch(INTERP_KERNEL::Exception& e) - { - throw e; - } -MEDFileFieldMultiTS::MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) +MEDFileAnyTypeFieldMultiTSIterator::~MEDFileAnyTypeFieldMultiTSIterator() { - if(!shallowCopyOfContent) +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTSIterator::nextt() +{ + if(_iter_id<_nb_iter) { - const MEDFileFieldMultiTSWithoutSDA *otherPtr(&other); - otherPtr->incrRef(); - _content=const_cast(otherPtr); + MEDFileAnyTypeFieldMultiTS *fmts(_fmts); + if(fmts) + return fmts->getTimeStepAtPos(_iter_id++); + else + return 0; } else - { - _content=new MEDFileFieldMultiTSWithoutSDA(other); - } + return 0; +} + +//= MEDFileIntFieldMultiTS + +/*! + * Returns a new empty instance of MEDFileFieldMultiTS. + * \return MEDFileIntFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New() +{ + return new MEDFileIntFieldMultiTS; +} + +/*! + * Returns a new instance of MEDFileIntFieldMultiTS holding data of the first field + * that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + */ +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const std::string& fileName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntFieldMultiTS(fileName,loadAll,0); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileIntFieldMultiTS holding data of a given field + * that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \param [in] fieldName - the name of the field to read. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + * \throw If there is no field named \a fieldName in the file. + */ +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntFieldMultiTS(fileName,fieldName,loadAll,0); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileIntFieldMultiTS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * Returns a new instance of MEDFileIntFieldMultiTS holding either a shallow copy + * of a given MEDFileIntFieldMultiTSWithoutSDA ( \a other ) or \a other itself. + * \warning this is a shallow copy constructor + * \param [in] other - a MEDFileIntField1TSWithoutSDA to copy. + * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. + * \return MEDFileIntFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) +{ + return new MEDFileIntFieldMultiTS(other,shallowCopyOfContent); +} + +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntFieldMultiTS(fileName,fieldName,loadAll,0,&entities); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); } -std::vector MEDFileFieldMultiTS::getPflsReallyUsed() const +/*! + * This method performs a copy with datatype modification ( int32->float64 ) of \a this. The globals information are copied + * following the given input policy. + * + * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) + * By default (true) the globals are deeply copied. + * \return MEDFileFieldMultiTS * - a new object that is the result of the conversion of \a this to float64 field. + */ +MEDFileFieldMultiTS *MEDFileIntFieldMultiTS::convertToDouble(bool isDeepCpyGlobs) const { - return _content->getPflsReallyUsed2(); + MEDCouplingAutoRefCountObjectPtr ret; + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(content) + { + const MEDFileIntFieldMultiTSWithoutSDA *contc=dynamic_cast(content); + if(!contc) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::convertToInt : the content inside this is not INT32 ! This is incoherent !"); + MEDCouplingAutoRefCountObjectPtr newc(contc->convertToDouble()); + ret=static_cast(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent((MEDFileFieldMultiTSWithoutSDA *)newc,getFileName())); + } + else + ret=MEDFileFieldMultiTS::New(); + if(isDeepCpyGlobs) + ret->deepCpyGlobs(*this); + else + ret->shallowCpyGlobs(*this); + return ret.retn(); } -std::vector MEDFileFieldMultiTS::getLocsReallyUsed() const +MEDFileAnyTypeFieldMultiTS *MEDFileIntFieldMultiTS::shallowCpy() const { - return _content->getLocsReallyUsed2(); + return new MEDFileIntFieldMultiTS(*this); } -std::vector MEDFileFieldMultiTS::getPflsReallyUsedMulti() const +void MEDFileIntFieldMultiTS::checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const { - return _content->getPflsReallyUsedMulti2(); + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); + const MEDFileIntField1TS *f1tsC=dynamic_cast(f1ts); + if(!f1tsC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::checkCoherencyOfType : the input field1TS is not a INT32 type !"); } -std::vector MEDFileFieldMultiTS::getLocsReallyUsedMulti() const +/*! + * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on + * mesh entities of a given dimension of the first mesh in MED file. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If the MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const { - return _content->getLocsReallyUsedMulti2(); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldAtLevel : mismatch of type of field expecting INT32 !"); + MEDCouplingAutoRefCountObjectPtr arr; + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arr,*contentNotNullBase()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); } -void MEDFileFieldMultiTS::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +/*! + * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on + * the top level cells of the first mesh in MED file. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If the MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtTopLevel(TypeOfField type, int iteration, int order, DataArrayInt* &arrOut, int renumPol) const { - _content->changePflsRefsNamesGen2(mapOfModif); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldAtTopLevel : mismatch of type of field ! INT32 expected !"); + MEDCouplingAutoRefCountObjectPtr arr; + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtTopLevel(type,std::string(),renumPol,this,arr,*contentNotNullBase()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); } -void MEDFileFieldMultiTS::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +/*! + * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on + * a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol) const { - _content->changeLocsRefsNamesGen2(mapOfModif); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); + MEDCouplingAutoRefCountObjectPtr arr; + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arr,*contentNotNullBase()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); } -int MEDFileFieldMultiTS::getNumberOfTS() const +/*! + * Returns a new MEDCouplingFieldDouble of given type, of a given time step, lying on a + * given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the new field. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] mesh - the supporting mesh. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol) const { - return _content->getNumberOfTS(); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldIntMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); + MEDCouplingAutoRefCountObjectPtr arr; + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arr,*contentNotNullBase()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); } -void MEDFileFieldMultiTS::eraseEmptyTS() throw(INTERP_KERNEL::Exception) +/*! + * This method has a close behaviour than MEDFileIntFieldMultiTS::getFieldAtLevel. + * This method is called 'old' because the user should give the mesh name he wants to use for it's field. + * This method is useful for MED2 file format when field on different mesh was autorized. + */ +MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const { - _content->eraseEmptyTS(); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); + MEDCouplingAutoRefCountObjectPtr arr; + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arr,*contentNotNullBase()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); } -void MEDFileFieldMultiTS::eraseTimeStepIds(const int *startIds, const int *endIds) throw(INTERP_KERNEL::Exception) +/*! + * Returns values and a profile of the field of a given type, of a given time step, + * lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the field. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the + * field of interest lies on. If the field lies on all entities of the given + * dimension, all ids in \a pfl are zero. The caller is to delete this array + * using decrRef() as it is no more needed. + * \param [in] glob - the global data storing profiles and localization. + * \return DataArrayInt * - a new instance of DataArrayInt holding values of the + * field. The caller is to delete this array using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the required parameters are available. + */ +DataArrayInt *MEDFileIntFieldMultiTS::getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const { - _content->eraseTimeStepIds(startIds,endIds); + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldWithProfile : mismatch of type of field ! INT32 expected !"); + MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNullBase()); + return MEDFileIntField1TS::ReturnSafelyDataArrayInt(ret); } -std::vector< std::pair > MEDFileFieldMultiTS::getIterations() const +/*! + * Returns a new MEDFileIntField1TS holding data of a given time step of \a this field. + * \param [in] pos - a time step id. + * \return MEDFileIntField1TS * - a new instance of MEDFileIntField1TS. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If \a pos is not a valid time step id. + */ +MEDFileAnyTypeField1TS *MEDFileIntFieldMultiTS::getTimeStepAtPos(int pos) const { - return _content->getIterations(); + const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos); + if(!item) + { + std::ostringstream oss; oss << "MEDFileIntFieldMultiTS::getTimeStepAtPos : field at pos #" << pos << " is null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileIntField1TSWithoutSDA *itemC=dynamic_cast(item); + if(itemC) + { + MEDCouplingAutoRefCountObjectPtr ret=MEDFileIntField1TS::New(*itemC,false); + ret->shallowCpyGlobs(*this); + return ret.retn(); + } + std::ostringstream oss; oss << "MEDFileIntFieldMultiTS::getTimeStepAtPos : type of field at pos #" << pos << " is not INT32 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } -int MEDFileFieldMultiTS::getPosOfTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception) +/*! + * Adds a MEDCouplingFieldDouble to \a this as another time step. The underlying mesh of + * the given field is checked if its elements are sorted suitable for writing to MED file + * ("STB" stands for "Sort By Type"), if not, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. + * \throw If the name of \a field is empty. + * \throw If the data array of \a field is not set. + * \throw If existing time steps have different name or number of components than \a field. + * \throw If the underlying mesh of \a field has no name. + * \throw If elements in the mesh are not in the order suitable for writing to the MED file. + */ +void MEDFileIntFieldMultiTS::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) { - return _content->getPosOfTimeStep(iteration,order); + contentNotNull()->appendFieldNoProfileSBT(field,arrOfVals,*this); } -int MEDFileFieldMultiTS::getPosGivenTime(double time, double eps) const throw(INTERP_KERNEL::Exception) +/*! + * Adds a MEDCouplingFieldDouble to \a this as another time step. + * The mesh support of input parameter \a field is ignored here, it can be NULL. + * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, + * and \a profile. + * + * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. + * A new profile is added only if no equal profile is missing. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. The field double values and mesh support are ignored. + * \param [in] arrOfVals - the values of the field \a field used. + * \param [in] mesh - the supporting mesh of \a field. + * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). + * \param [in] profile - ids of mesh entities on which corresponding field values lie. + * \throw If either \a field or \a mesh or \a profile has an empty name. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If the data array of \a field is not set. + * \throw If the data array of \a this is already allocated but has different number of + * components than \a field. + * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. + * \sa setFieldNoProfileSBT() + */ +void MEDFileIntFieldMultiTS::appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) { - return _content->getPosGivenTime(time,eps); + contentNotNull()->appendFieldProfile(field,arrOfVals,mesh,meshDimRelToMax,profile,*this); } -int MEDFileFieldMultiTS::getNonEmptyLevels(int iteration, int order, const char *mname, std::vector& levs) const throw(INTERP_KERNEL::Exception) +const MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTS::contentNotNull() const { - return _content->getNonEmptyLevels(iteration,order,mname,levs); + const MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the content pointer is null !"); + const MEDFileIntFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the content pointer is not null but it is not of type int ! Reason is maybe that the read field has not the type INT32 !"); + return ret; } -std::vector< std::vector > MEDFileFieldMultiTS::getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) +MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTS::contentNotNull() { - return _content->getTypesOfFieldAvailable(); + MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the non const content pointer is null !"); + MEDFileIntFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the non const content pointer is not null but it is not of type int ! Reason is maybe that the read field has not the type INT32 !"); + return ret; } -std::vector< std::vector< std::pair > > MEDFileFieldMultiTS::getFieldSplitedByType(int iteration, int order, const char *mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception) +MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS() { - return _content->getFieldSplitedByType(iteration,order,mname,types,typesF,pfls,locs); + _content=new MEDFileIntFieldMultiTSWithoutSDA; } -std::vector< std::vector > MEDFileFieldMultiTS::getFieldSplitedByType2(int iteration, int order, const char *mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const throw(INTERP_KERNEL::Exception) +MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeFieldMultiTS(other,shallowCopyOfContent) { - return _content->getFieldSplitedByType2(iteration,order,mname,types,typesF,pfls,locs); } -std::string MEDFileFieldMultiTS::getName() const +MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeFieldMultiTS(fileName,loadAll,ms) { - return _content->getName(); } +catch(INTERP_KERNEL::Exception& e) +{ throw e; } -void MEDFileFieldMultiTS::setName(const char *name) +MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) +try:MEDFileAnyTypeFieldMultiTS(fileName,fieldName,loadAll,ms,entities) { - _content->setName(name); } +catch(INTERP_KERNEL::Exception& e) +{ throw e; } -void MEDFileFieldMultiTS::simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const +DataArrayInt *MEDFileIntFieldMultiTS::getUndergroundDataArray(int iteration, int order) const { - _content->simpleRepr(bkOffset,oss,fmtsId); + return static_cast(contentNotNull()->getUndergroundDataArray(iteration,order)); } -std::vector< std::pair > MEDFileFieldMultiTS::getTimeSteps(std::vector& ret1) const throw(INTERP_KERNEL::Exception) -{ - return _content->getTimeSteps(ret1); -} +//= MEDFileFields -std::string MEDFileFieldMultiTS::getMeshName() const throw(INTERP_KERNEL::Exception) +MEDFileFields *MEDFileFields::New() { - return _content->getMeshName(); + return new MEDFileFields; } -void MEDFileFieldMultiTS::setMeshName(const char *newMeshName) throw(INTERP_KERNEL::Exception) +MEDFileFields *MEDFileFields::New(const std::string& fileName, bool loadAll) { - _content->setMeshName(newMeshName); + return new MEDFileFields(fileName,loadAll,0,0); } -bool MEDFileFieldMultiTS::changeMeshNames(const std::vector< std::pair >& modifTab) throw(INTERP_KERNEL::Exception) +MEDFileFields *MEDFileFields::LoadPartOf(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) { - return _content->changeMeshNames(modifTab); + return new MEDFileFields(fileName,loadAll,ms,0); } -const std::vector& MEDFileFieldMultiTS::getInfo() const throw(INTERP_KERNEL::Exception) +MEDFileFields *MEDFileFields::LoadSpecificEntities(const std::string& fileName, const std::vector< std::pair >& entities, bool loadAll) { - return _content->getInfo(); + return new MEDFileFields(fileName,loadAll,0,&entities); } -DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArray(int iteration, int order) const throw(INTERP_KERNEL::Exception) +std::size_t MEDFileFields::getHeapMemorySizeWithoutChildren() const { - return _content->getUndergroundDataArray(iteration,order); + std::size_t ret(MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren()); + ret+=_fields.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); + return ret; } -DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const throw(INTERP_KERNEL::Exception) +std::vector MEDFileFields::getDirectChildrenWithNull() const { - return _content->getUndergroundDataArrayExt(iteration,order,entries); + std::vector ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) + ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)*it); + return ret; } -MEDFileFieldMultiTSIterator::MEDFileFieldMultiTSIterator(MEDFileFieldMultiTS *fmts):_fmts(fmts),_iter_id(0),_nb_iter(0) +MEDFileFields *MEDFileFields::deepCpy() const { - if(fmts) + MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) { - fmts->incrRef(); - _nb_iter=fmts->getNumberOfTS(); + if((const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it) + ret->_fields[i]=(*it)->deepCpy(); } + ret->deepCpyGlobs(*this); + return ret.retn(); } -MEDFileFieldMultiTSIterator::~MEDFileFieldMultiTSIterator() +MEDFileFields *MEDFileFields::shallowCpy() const { + return new MEDFileFields(*this); } -MEDFileField1TS *MEDFileFieldMultiTSIterator::nextt() +/*! + * This method scans for all fields in \a this which time steps ids are common. Time step are discriminated by the pair of integer (iteration,order) whatever + * the double time value. If all returned time steps are \b exactly those for all fields in \a this output parameter \a areThereSomeForgottenTS will be set to false. + * If \a areThereSomeForgottenTS is set to true, only the sorted intersection of time steps present for all fields in \a this will be returned. + * + * \param [out] areThereSomeForgottenTS - indicates to the caller if there is some time steps in \a this that are not present for all fields in \a this. + * \return the sorted list of time steps (specified with a pair of integer iteration first and order second) present for all fields in \a this. + * + * \sa MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps + */ +std::vector< std::pair > MEDFileFields::getCommonIterations(bool& areThereSomeForgottenTS) const { - if(_iter_id<_nb_iter) + std::set< std::pair > s; + bool firstShot=true; + areThereSomeForgottenTS=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) { - MEDFileFieldMultiTS *fmts(_fmts); - if(fmts) - return fmts->getTimeStepAtPos(_iter_id++); + if(!(const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it) + continue; + std::vector< std::pair > v=(*it)->getIterations(); + std::set< std::pair > s1; std::copy(v.begin(),v.end(),std::inserter(s1,s1.end())); + if(firstShot) + { s=s1; firstShot=false; } else - return 0; - } - else - return 0; -} - -MEDFileFields *MEDFileFields::New() -{ - return new MEDFileFields; -} - -MEDFileFields *MEDFileFields::New(const char *fileName) throw(INTERP_KERNEL::Exception) -{ - return new MEDFileFields(fileName); -} - -std::size_t MEDFileFields::getHeapMemorySize() const -{ - std::size_t ret=_fields.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - if((const MEDFileFieldMultiTSWithoutSDA *)*it) - ret+=(*it)->getHeapMemorySize(); - return ret+MEDFileFieldGlobsReal::getHeapMemorySize(); -} - -MEDFileFields *MEDFileFields::deepCpy() const throw(INTERP_KERNEL::Exception) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFields(*this); - std::size_t i=0; - for( std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - if((const MEDFileFieldMultiTSWithoutSDA*)*it) - ret->_fields[i]=(*it)->deepCpy(); + { + std::set< std::pair > s2; std::set_intersection(s.begin(),s.end(),s1.begin(),s1.end(),std::inserter(s2,s2.end())); + if(s!=s2) + areThereSomeForgottenTS=true; + s=s2; + } } - ret->deepCpyGlobs(*this); - return ret.retn(); + std::vector< std::pair > ret; + std::copy(s.begin(),s.end(),std::back_insert_iterator< std::vector< std::pair > >(ret)); + return ret; } int MEDFileFields::getNumberOfFields() const @@ -6375,13 +9880,13 @@ int MEDFileFields::getNumberOfFields() const return _fields.size(); } -std::vector MEDFileFields::getFieldsNames() const throw(INTERP_KERNEL::Exception) +std::vector MEDFileFields::getFieldsNames() const { std::vector ret(_fields.size()); int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) { - const MEDFileFieldMultiTSWithoutSDA *f=(*it); + const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=(*it); if(f) { ret[i]=f->getName(); @@ -6395,12 +9900,12 @@ std::vector MEDFileFields::getFieldsNames() const throw(INTERP_KERN return ret; } -std::vector MEDFileFields::getMeshesNames() const throw(INTERP_KERNEL::Exception) +std::vector MEDFileFields::getMeshesNames() const { std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) { - const MEDFileFieldMultiTSWithoutSDA *cur(*it); + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it); if(cur) ret.push_back(cur->getMeshName()); } @@ -6421,9 +9926,9 @@ void MEDFileFields::simpleRepr(int bkOffset, std::ostream& oss) const std::string startLine(bkOffset,' '); oss << startLine << "There are " << nbOfFields << " fields in this :" << std::endl; int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) { - const MEDFileFieldMultiTSWithoutSDA *cur=(*it); + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); if(cur) { oss << startLine << " - # "<< i << " has the following name : \"" << cur->getName() << "\"." << std::endl; @@ -6434,9 +9939,9 @@ void MEDFileFields::simpleRepr(int bkOffset, std::ostream& oss) const } } i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) { - const MEDFileFieldMultiTSWithoutSDA *cur=(*it); + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); std::string chapter(17,'0'+i); oss << startLine << chapter << std::endl; if(cur) @@ -6449,52 +9954,59 @@ void MEDFileFields::simpleRepr(int bkOffset, std::ostream& oss) const } oss << startLine << chapter << std::endl; } - MEDFileFieldGlobsReal::simpleRepr(oss); + simpleReprGlobs(oss); } MEDFileFields::MEDFileFields() { } -MEDFileFields::MEDFileFields(const char *fileName) throw(INTERP_KERNEL::Exception) +MEDFileFields::MEDFileFields(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) try:MEDFileFieldGlobsReal(fileName) - { - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - int nbFields=MEDnField(fid); - _fields.resize(nbFields); - med_field_type typcha; - for(int i=0;i infos; + std::string fieldName,dtunit; + int nbOfStep(MEDFileAnyTypeField1TS::LocateField2(fid,fileName,i,false,fieldName,typcha,infos,dtunit)); + switch(typcha) { - int ncomp=MEDfieldnComponent(fid,i+1); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localMesh; - int nbOfStep; - MEDfieldInfo(fid,i+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep); - int ft=MEDFileUtilities::TraduceFieldType(typcha); - std::vector infos(ncomp); - for(int j=0;j >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) { - const MEDFileFieldMultiTSWithoutSDA *elt=*it; + const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt=*it; if(!elt) { std::ostringstream oss; oss << "MEDFileFields::write : at rank #" << i << "/" << _fields.size() << " field is empty !"; @@ -6504,18 +10016,89 @@ void MEDFileFields::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception) } } -void MEDFileFields::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception) +void MEDFileFields::write(const std::string& fileName, int mode) const { med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod); + MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),medmod)); writeLL(fid); } +/*! + * This method alloc the arrays and load potentially huge arrays contained in this field. + * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter. + * This method can be also called to refresh or reinit values from a file. + * + * \throw If the fileName is not set or points to a non readable MED file. + */ +void MEDFileFields::loadArrays() +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileFields::loadArrays : the structure does not come from a file !"); + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) + { + MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); + if(elt) + elt->loadBigArraysRecursively(fid,*elt); + } +} + +/*! + * This method behaves as MEDFileFields::loadArrays does, the first call, if \a this was built using a file without loading big arrays. + * But once data loaded once, this method does nothing. + * + * \throw If the fileName is not set or points to a non readable MED file. + * \sa MEDFileFields::loadArrays, MEDFileFields::unloadArrays + */ +void MEDFileFields::loadArraysIfNecessary() +{ + if(!getFileName().empty()) + { + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) + { + MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); + if(elt) + elt->loadBigArraysRecursivelyIfNecessary(fid,*elt); + } + } +} + +/*! + * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. + * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. + * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileFields::unloadArraysWithoutDataLoss instead. + * + * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary, MEDFileFields::unloadArraysWithoutDataLoss + */ +void MEDFileFields::unloadArrays() +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) + { + MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); + if(elt) + elt->unloadArrays(); + } +} + +/*! + * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. + * This method is the symetrical method of MEDFileFields::loadArraysIfNecessary. + * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. + * + * \sa MEDFileFields::loadArraysIfNecessary + */ +void MEDFileFields::unloadArraysWithoutDataLoss() +{ + if(!getFileName().empty()) + unloadArrays(); +} + std::vector MEDFileFields::getPflsReallyUsed() const { std::vector ret; std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) { std::vector tmp=(*it)->getPflsReallyUsed2(); for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) @@ -6532,7 +10115,7 @@ std::vector MEDFileFields::getLocsReallyUsed() const { std::vector ret; std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) { std::vector tmp=(*it)->getLocsReallyUsed2(); for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) @@ -6548,7 +10131,7 @@ std::vector MEDFileFields::getLocsReallyUsed() const std::vector MEDFileFields::getPflsReallyUsedMulti() const { std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) { std::vector tmp=(*it)->getPflsReallyUsedMulti2(); ret.insert(ret.end(),tmp.begin(),tmp.end()); @@ -6559,7 +10142,7 @@ std::vector MEDFileFields::getPflsReallyUsedMulti() const std::vector MEDFileFields::getLocsReallyUsedMulti() const { std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) { std::vector tmp=(*it)->getLocsReallyUsed2(); ret.insert(ret.end(),tmp.begin(),tmp.end()); @@ -6567,24 +10150,30 @@ std::vector MEDFileFields::getLocsReallyUsedMulti() const return ret; } -void MEDFileFields::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFields::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) { - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++) (*it)->changePflsRefsNamesGen2(mapOfModif); } -void MEDFileFields::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) throw(INTERP_KERNEL::Exception) +void MEDFileFields::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) { - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++) (*it)->changeLocsRefsNamesGen2(mapOfModif); } -void MEDFileFields::resize(int newSize) throw(INTERP_KERNEL::Exception) +void MEDFileFields::resize(int newSize) { _fields.resize(newSize); } -void MEDFileFields::pushField(MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception) +void MEDFileFields::pushFields(const std::vector& fields) +{ + for(std::vector::const_iterator it=fields.begin();it!=fields.end();it++) + pushField(*it); +} + +void MEDFileFields::pushField(MEDFileAnyTypeFieldMultiTS *field) { if(!field) throw INTERP_KERNEL::Exception("MEDFileFields::pushMesh : invalid input pointer ! should be different from 0 !"); @@ -6592,7 +10181,7 @@ void MEDFileFields::pushField(MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::E appendGlobs(*field,1e-12); } -void MEDFileFields::setFieldAtPos(int i, MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception) +void MEDFileFields::setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field) { if(!field) throw INTERP_KERNEL::Exception("MEDFileFields::setFieldAtPos : invalid input pointer ! should be different from 0 !"); @@ -6602,22 +10191,60 @@ void MEDFileFields::setFieldAtPos(int i, MEDFileFieldMultiTS *field) throw(INTER appendGlobs(*field,1e-12); } -void MEDFileFields::destroyFieldAtPos(int i) throw(INTERP_KERNEL::Exception) +void MEDFileFields::destroyFieldAtPos(int i) { - if(i<0 || i>=(int)_fields.size()) + destroyFieldsAtPos(&i,&i+1); +} + +void MEDFileFields::destroyFieldsAtPos(const int *startIds, const int *endIds) +{ + std::vector b(_fields.size(),true); + for(const int *i=startIds;i!=endIds;i++) { - std::ostringstream oss; oss << "MEDFileFields::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _fields.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + if(*i<0 || *i>=(int)_fields.size()) + { + std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + b[*i]=false; + } + std::vector< MEDCouplingAutoRefCountObjectPtr > fields(std::count(b.begin(),b.end(),true)); + std::size_t j=0; + for(std::size_t i=0;i<_fields.size();i++) + if(b[i]) + fields[j++]=_fields[i]; + _fields=fields; +} + +void MEDFileFields::destroyFieldsAtPos2(int bg, int end, int step) +{ + static const char msg[]="MEDFileFields::destroyFieldsAtPos2"; + int nbOfEntriesToKill=DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg); + std::vector b(_fields.size(),true); + int k=bg; + for(int i=0;i=(int)_fields.size()) + { + std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos2 : Invalid given id in input (" << k << ") should be in [0," << _fields.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + b[k]=false; } - _fields.erase(_fields.begin()+i); + std::vector< MEDCouplingAutoRefCountObjectPtr > fields(std::count(b.begin(),b.end(),true)); + std::size_t j=0; + for(std::size_t i=0;i<_fields.size();i++) + if(b[i]) + fields[j++]=_fields[i]; + _fields=fields; } -bool MEDFileFields::changeMeshNames(const std::vector< std::pair >& modifTab) throw(INTERP_KERNEL::Exception) +bool MEDFileFields::changeMeshNames(const std::vector< std::pair >& modifTab) { bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) { - MEDFileFieldMultiTSWithoutSDA *cur(*it); + MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it); if(cur) ret=cur->changeMeshNames(modifTab) || ret; } @@ -6633,12 +10260,12 @@ bool MEDFileFields::changeMeshNames(const std::vector< std::pair& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N) throw(INTERP_KERNEL::Exception) +bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N) { bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) { - MEDFileFieldMultiTSWithoutSDA *fmts(*it); + MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts(*it); if(fmts) { ret=fmts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,*this) || ret; @@ -6647,36 +10274,172 @@ bool MEDFileFields::renumberEntitiesLyingOnMesh(const char *meshName, const std: return ret; } -MEDFileFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const throw(INTERP_KERNEL::Exception) +MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const { if(i<0 || i>=(int)_fields.size()) { std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : Invalid given id in input (" << i << ") should be in [0," << _fields.size() << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - const MEDFileFieldMultiTSWithoutSDA *fmts=_fields[i]; - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldMultiTS::New(*fmts,false); + const MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts=_fields[i]; + if(!fmts) + return 0; + MEDCouplingAutoRefCountObjectPtr ret; + const MEDFileFieldMultiTSWithoutSDA *fmtsC=dynamic_cast(fmts); + const MEDFileIntFieldMultiTSWithoutSDA *fmtsC2=dynamic_cast(fmts); + if(fmtsC) + ret=MEDFileFieldMultiTS::New(*fmtsC,false); + else if(fmtsC2) + ret=MEDFileIntFieldMultiTS::New(*fmtsC2,false); + else + { + std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : At pos #" << i << " field is neither double (FLOAT64) nor integer (INT32) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } ret->shallowCpyGlobs(*this); return ret.retn(); } -MEDFileFieldMultiTS *MEDFileFields::getFieldWithName(const char *fieldName) const throw(INTERP_KERNEL::Exception) +/*! + * Return a shallow copy of \a this reduced to the fields ids defined in [ \a startIds , endIds ). + * This method is accessible in python using __getitem__ with a list in input. + * \return a new object that the caller should deal with. + */ +MEDFileFields *MEDFileFields::buildSubPart(const int *startIds, const int *endIds) const +{ + MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); + std::size_t sz=std::distance(startIds,endIds); + std::vector< MEDCouplingAutoRefCountObjectPtr > fields(sz); + int j=0; + for(const int *i=startIds;i!=endIds;i++,j++) + { + if(*i<0 || *i>=(int)_fields.size()) + { + std::ostringstream oss; oss << "MEDFileFields::buildSubPart : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + fields[j]=_fields[*i]; + } + ret->_fields=fields; + return ret.retn(); +} + +MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldWithName(const std::string& fieldName) const { return getFieldAtPos(getPosFromFieldName(fieldName)); } -MEDFileFieldsIterator *MEDFileFields::iterator() throw(INTERP_KERNEL::Exception) +/*! + * This method removes, if any, fields in \a this having no time steps. + * If there is one or more than one such field in \a this true is returned and those fields will not be referenced anymore in \a this. + * + * If false is returned \a this does not contain such fields. If false is returned this method can be considered as const. + */ +bool MEDFileFields::removeFieldsWithoutAnyTimeStep() +{ + std::vector > newFields; + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); + if(elt) + { + if(elt->getNumberOfTS()>0) + newFields.push_back(*it); + } + } + if(_fields.size()==newFields.size()) + return false; + _fields=newFields; + return true; +} + +/*! + * This method returns a new object containing part of \a this fields lying on mesh name specified by the input parameter \a meshName. + * This method can be seen as a filter applied on \a this, that returns an object containing + * reduced the list of fields compared to those in \a this. The returned object is a new object but the object on which it lies are only + * shallow copied from \a this. + * + * \param [in] meshName - the name of the mesh on w + * \return a new object that the caller should deal with. + */ +MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const +{ + MEDCouplingAutoRefCountObjectPtr ret=MEDFileFields::New(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); + if(!cur) + continue; + if(cur->getMeshName()==meshName) + { + cur->incrRef(); + MEDCouplingAutoRefCountObjectPtr cur2(const_cast(cur)); + ret->_fields.push_back(cur2); + } + } + ret->shallowCpyOnlyUsedGlobs(*this); + return ret.retn(); +} + +/*! + * This method returns a new object containing part of \a this fields lying ** exactly ** on the time steps specified by input parameter \a timeSteps. + * Input time steps are specified using a pair of integer (iteration, order). + * This method can be seen as a filter applied on \a this, that returns an object containing the same number of fields than those in \a this, + * but for each multitimestep only the time steps in \a timeSteps are kept. + * Typically the input parameter \a timeSteps comes from the call of MEDFileFields::getCommonIterations. + * + * The returned object points to shallow copy of elements in \a this. + * + * \param [in] timeSteps - the time steps given by a vector of pair of integers (iteration,order) + * \throw If there is a field in \a this that is \b not defined on a time step in the input \a timeSteps. + * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps + */ +MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const +{ + MEDCouplingAutoRefCountObjectPtr ret=MEDFileFields::New(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); + if(!cur) + continue; + MEDCouplingAutoRefCountObjectPtr elt=cur->partOfThisLyingOnSpecifiedTimeSteps(timeSteps); + ret->_fields.push_back(elt); + } + ret->shallowCpyOnlyUsedGlobs(*this); + return ret.retn(); +} + +/*! + * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps + */ +MEDFileFields *MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const +{ + MEDCouplingAutoRefCountObjectPtr ret=MEDFileFields::New(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); + if(!cur) + continue; + MEDCouplingAutoRefCountObjectPtr elt=cur->partOfThisNotLyingOnSpecifiedTimeSteps(timeSteps); + if(elt->getNumberOfTS()!=0) + ret->_fields.push_back(elt); + } + ret->shallowCpyOnlyUsedGlobs(*this); + return ret.retn(); +} + +MEDFileFieldsIterator *MEDFileFields::iterator() { return new MEDFileFieldsIterator(this); } -int MEDFileFields::getPosFromFieldName(const char *fieldName) const throw(INTERP_KERNEL::Exception) +int MEDFileFields::getPosFromFieldName(const std::string& fieldName) const { std::string tmp(fieldName); std::vector poss; for(std::size_t i=0;i<_fields.size();i++) { - const MEDFileFieldMultiTSWithoutSDA *f=_fields[i]; + const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=_fields[i]; if(f) { std::string fname(f->getName()); @@ -6705,7 +10468,7 @@ MEDFileFieldsIterator::~MEDFileFieldsIterator() { } -MEDFileFieldMultiTS *MEDFileFieldsIterator::nextt() +MEDFileAnyTypeFieldMultiTS *MEDFileFieldsIterator::nextt() { if(_iter_id<_nb_iter) {