X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDLoader%2FMEDFileField.txx;h=5c34ec86d4aa2bf065f3a3522dc20e9f1b5118de;hb=e95ee11e7df126315ffd11c2518b648a6915ad51;hp=639bc1ab98f861919110126985714bee6e6562d2;hpb=9132631b57f12deb523f6e2e0cfc98bdbe9424c8;p=tools%2Fmedcoupling.git diff --git a/src/MEDLoader/MEDFileField.txx b/src/MEDLoader/MEDFileField.txx index 639bc1ab9..5c34ec86d 100644 --- a/src/MEDLoader/MEDFileField.txx +++ b/src/MEDLoader/MEDFileField.txx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D +// Copyright (C) 2007-2021 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 @@ -18,11 +18,15 @@ // // Author : Anthony Geay (EDF R&D) -#ifndef __MEDFILEFIELD_TXX__ -#define __MEDFILEFIELD_TXX__ +#pragma once #include "MEDFileField.hxx" #include "MEDCouplingTraits.hxx" +#include "MEDCouplingFieldInt32.hxx" +#include "MEDCouplingFieldInt64.hxx" +#include "MEDCouplingFieldFloat.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldTemplate.hxx" namespace MEDCoupling { @@ -106,6 +110,33 @@ namespace MEDCoupling return 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 getUndergroundDataArrayTemplate() + */ + template + typename Traits::ArrayType *MEDFileField1TSTemplateWithoutSDA::getUndergroundDataArrayTemplateExt(std::vector< std::pair,std::pair > >& entries) const + { + if(this->_field_per_mesh.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !"); + if(this->_field_per_mesh[0]==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !"); + this->_field_per_mesh[0]->getUndergroundDataArrayExt(entries); + return getUndergroundDataArrayTemplate(); + } + /*! * 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 @@ -120,7 +151,7 @@ namespace MEDCoupling } template - void MEDFileField1TSTemplateWithoutSDA::aggregate(const std::vector::F1TSWSDAType const *>& f1tss, const std::vector< std::vector< std::pair > >& dts) + void MEDFileField1TSTemplateWithoutSDA::aggregate(const std::vector::F1TSWSDAType const *>& f1tss, const std::vector< std::vector< std::pair > >& dts) { if(f1tss.empty()) throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : empty vector !"); @@ -143,15 +174,15 @@ namespace MEDCoupling setName(refPt->getName()); const DataArray *arr(refPt->getUndergroundDataArray()); - int nbCompo(arr->getNumberOfComponents()); + std::size_t nbCompo(arr->getNumberOfComponents()); for(typename std::vector::F1TSWSDAType const *>::const_iterator it=f1tss.begin();it!=f1tss.end();it++) { const typename Traits::ArrayType *myArr((*it)->getUndergroundDataArrayTemplate()); if(myArr->getNumberOfComponents()!=nbCompo) throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : arrays must have same number of components !"); } - std::vector > > extractInfo; - int start(0); + std::vector > > extractInfo; + mcIdType start(0); MCAuto fpm(MEDFileFieldPerMesh::Aggregate(start,pms,dts,this,extractInfo)); _field_per_mesh.push_back(fpm); int iteration,order; @@ -160,13 +191,43 @@ namespace MEDCoupling _arr=Traits::ArrayType::New(); _arr->alloc(start,nbCompo); _arr->copyStringInfoFrom(*arr); start=0; - for(std::vector > >::const_iterator it=extractInfo.begin();it!=extractInfo.end();it++) + for(std::vector > >::const_iterator it=extractInfo.begin();it!=extractInfo.end();it++) { const DataArray *zeArr(das[(*it).first]); _arr->setContigPartOfSelectedValuesSlice(start,zeArr,(*it).second.first,(*it).second.second,1); start+=(*it).second.second-(*it).second.first; } + // see definition of _nb_of_tuples_to_be_allocated. array is built from scratch and allocated. + _nb_of_tuples_to_be_allocated=-3; + } + + template + void MEDFileField1TSTemplateWithoutSDA::copyTimeInfoFrom(const typename Traits::FieldType *mcf) + { + if(!mcf) + throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::copyTimeInfoFrom : input field is nullptr !"); + int b(0),c(0); + double a(mcf->getTime(b,c)); + setTime(b,c,a); + } + + /////////////////////////////////////////////////////// + + template + MEDFileField1TSWithoutSDA *MEDFileField1TSNDTemplateWithoutSDA::convertToDouble() const + { + MCAuto ret(new MEDFileField1TSWithoutSDA); + ret->MEDFileAnyTypeField1TSWithoutSDA::operator =(*this); + ret->deepCpyLeavesFrom(*this); + if(this->_arr.isNotNull()) + { + MCAuto arr2(this->_arr->convertToDblArr()); + ret->setArray(arr2); + } + return ret.retn(); } + + /////////////////////////////////////////////////////// template MEDFileTemplateField1TS::MEDFileTemplateField1TS() @@ -291,7 +352,10 @@ namespace MEDCoupling throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS::contentNotNull : the content pointer is null !"); const typename MLFieldTraits::F1TSWSDAType *ret(dynamic_cast::F1TSWSDAType *>(pt)); if(!ret) - throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS::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 !"); + { + std::ostringstream oss; oss << "MEDFileTemplateField1TS::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 " << MLFieldTraits::F1TSWSDAType::TYPE_STR; + throw INTERP_KERNEL::Exception(oss.str()); + } return ret; } @@ -303,9 +367,1034 @@ namespace MEDCoupling throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS::contentNotNull : the non const content pointer is null !"); typename MLFieldTraits::F1TSWSDAType *ret(dynamic_cast::F1TSWSDAType *>(pt)); if(!ret) - throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS::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 !"); + { + std::ostringstream oss; oss << "MEDFileTemplateField1TS::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 " << MLFieldTraits::F1TSWSDAType::TYPE_STR; + throw INTERP_KERNEL::Exception(oss.str()); + } return ret; } -} + + template + typename Traits::ArrayType *MEDFileTemplateField1TS::ReturnSafelyTypedDataArray(MCAuto& arr) + { + if(arr.isNull()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyTypedDataArray : no array !"); + typename Traits::ArrayType *arrOutC(dynamic_cast::ArrayType *>((DataArray*)arr)); + if(!arrOutC) + throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyTypedDataArray : mismatch between dataArrays type and MEDFileField1TS ! Expected double !"); + arrOutC->incrRef(); + return arrOutC; + } + + /*! + * 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. + */ + template + typename Traits::ArrayType *MEDFileTemplateField1TS::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayIdType *&pfl) const + { + MCAuto arr(contentNotNull()->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNull())); + return ReturnSafelyTypedDataArray(arr); + } + + template + void MEDFileTemplateField1TS::setArray(DataArray *arr) + { + return contentNotNull()->setArray(arr); + } + + template + typename Traits::ArrayType *MEDFileTemplateField1TS::getUndergroundDataArray() const + { + return contentNotNull()->getUndergroundDataArrayTemplate(); + } + + template + typename Traits::ArrayType *MEDFileTemplateField1TS::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const + { + return contentNotNull()->getUndergroundDataArrayTemplateExt(entries); + } + + template + MCAuto::FieldType> MEDFileTemplateField1TS::SetDataArrayInField(MEDCouplingFieldDouble *f, MCAuto& arr) + { + if(!f) + throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS::SetDataArrayInField : input field is NULL !"); + if(arr.isNull()) + throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS::SetDataArrayInField : no array !"); + int t1,t2; + double t0(f->getTime(t1,t2)); + std::string tu(f->getTimeUnit()); + MCAuto::ArrayType> arr2(DynamicCastSafe::ArrayType>(arr)); + MCAuto ft(MEDCouplingFieldTemplate::New(*f)); + MCAuto::FieldType> ret(Traits::FieldType::New(*ft)); + ret->setTime(t0,t1,t2); ret->setArray(arr2); ret->setTimeUnit(tu); + return ret.retn(); + } + + template + MCAuto MEDFileTemplateField1TS::ToFieldTemplateWithTime(const typename Traits::FieldType *f) + { + int t1,t2; + double t0(f->getTime(t1,t2)); + std::string tu(f->getTimeUnit()); + MCAuto ft(MEDCouplingFieldTemplate::NewWithoutCheck(*f)); + MCAuto ret(MEDCouplingFieldDouble::New(*ft)); + ret->setTime(t0,t1,t2); ret->setTimeUnit(tu); + return ret.retn(); + } + + template + void MEDFileTemplateField1TS::copyTimeInfoFrom(const typename Traits::FieldType *mcf) + { + contentNotNull()->copyTimeInfoFrom(mcf); + } + + /*! + * This is the simplest version to fetch a field for MED structure. One drawback : if \a this is a complex field (multi spatial discretization inside a same field) this method will throw exception and more advance + * method should be called (getFieldOnMeshAtLevel for example). + * But for normal usage of field in MED file world this method is the most efficient to fetch data. + * + * \param [in] mesh - the mesh the field is lying on + * \return typename Traits::FieldType * - a new instance of typename Traits::FieldType. The + * caller is to delete this field using decrRef() as it is no more needed. + */ + template + typename Traits::FieldType *MEDFileTemplateField1TS::field(const MEDFileMesh *mesh) const + { + MCAuto arrOut; + MCAuto ret(contentNotNull()->fieldOnMesh(this,mesh,arrOut,*contentNotNull())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * Returns a new typename Traits::FieldType 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 typename Traits::FieldType * - a new instance of typename Traits::FieldType. 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() + */ + template + typename Traits::FieldType *MEDFileTemplateField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol) const + { + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); + MCAuto arrOut; + MCAuto ret(contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNull())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * Returns a new typename Traits::FieldType 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 typename Traits::FieldType * - a new instance of typename Traits::FieldType. 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() + */ + template + typename Traits::FieldType *MEDFileTemplateField1TS::getFieldAtTopLevel(TypeOfField type, int renumPol) const + { + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); + MCAuto arrOut; + MCAuto ret(contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNull())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * Returns a new typename Traits::FieldType 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 typename Traits::FieldType * - a new instance of typename Traits::FieldType. 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() + */ + template + typename Traits::FieldType *MEDFileTemplateField1TS::getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol) const + { + MCAuto arrOut; + MCAuto ret(contentNotNull()->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arrOut,*contentNotNull())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * Returns a new typename Traits::FieldType 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 typename Traits::FieldType * - a new instance of typename Traits::FieldType. 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() + */ + template + typename Traits::FieldType *MEDFileTemplateField1TS::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const + { + MCAuto arrOut; + MCAuto ret(contentNotNull()->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arrOut,*contentNotNull())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * Returns a new typename Traits::FieldType 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 typename Traits::FieldType * - a new instance of typename Traits::FieldType. 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() + */ + template + typename Traits::FieldType *MEDFileTemplateField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol) const + { + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileTemplateField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); + MCAuto arrOut; + MCAuto ret(contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNull())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.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. + * \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. + */ + template + void MEDFileTemplateField1TS::setFieldNoProfileSBT(const typename Traits::FieldType *field) + { + setFileName(""); + MCAuto ft(MEDCouplingFieldTemplate::New(*field)); + contentNotNull()->setFieldNoProfileSBT(field->timeDiscrSafe(),ft,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, setFieldProfileFlatly + */ + template + void MEDFileTemplateField1TS::setFieldProfile(const typename Traits::FieldType *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayIdType *profile) + { + setFieldProfileGeneral(field,mesh,meshDimRelToMax,profile,true); + } + + /*! + * Same as setFieldProfile except that here profile will be created unconditionally + * \sa setFieldProfile + */ + template + void MEDFileTemplateField1TS::setFieldProfileFlatly(const typename Traits::FieldType *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayIdType *profile) + { + setFieldProfileGeneral(field,mesh,meshDimRelToMax,profile,false); + } + + template + void MEDFileTemplateField1TS::setFieldProfileGeneral(const typename Traits::FieldType *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayIdType *profile, bool smartPflKiller) + { + setFileName(""); + MCAuto ft(MEDCouplingFieldTemplate::NewWithoutCheck(*field)); + contentNotNull()->setFieldProfile(field->timeDiscrSafe(),ft,field->getArray(),mesh,meshDimRelToMax,profile,*this,*contentNotNull(),smartPflKiller); + } + + /*! + * Return an extraction of \a this using \a extractDef map to specify the extraction. + * The keys of \a extractDef is level relative to max ext of \a mm mesh. + * + * \return A new object that the caller is responsible to deallocate. + * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart , MEDFileUMesh::extractPart + */ + template + typename MLFieldTraits::F1TSType *MEDFileTemplateField1TS::extractPartImpl(const std::map >& extractDef, MEDFileMesh *mm) const + { + if(!mm) + throw INTERP_KERNEL::Exception("MEDFileField1TS::extractPart : input mesh is NULL !"); + MCAuto::F1TSType> ret(MLFieldTraits::F1TSType::New()); + std::vector tof(getTypesOfFieldAvailable()); + for(std::vector::const_iterator it0=tof.begin();it0!=tof.end();it0++) + { + if((*it0)!=ON_NODES) + { + std::vector levs; + getNonEmptyLevels(mm->getName(),levs); + for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) + { + std::map >::const_iterator it2(extractDef.find(*lev)); + if(it2!=extractDef.end()) + { + MCAuto t((*it2).second); + if(t.isNull()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::extractPart : presence of a value with null pointer 1 !"); + MCAuto::FieldType> f(getFieldOnMeshAtLevel(ON_CELLS,(*lev),mm)); + MCAuto::FieldType> fOut(f->buildSubPart(t)); + ret->setFieldNoProfileSBT(fOut); + } + } + } + else + { + std::map >::const_iterator it2(extractDef.find(1)); + if(it2==extractDef.end()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::extractPart : presence of a NODE field and no extract array available for NODE !"); + MCAuto t((*it2).second); + if(t.isNull()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::extractPart : presence of a value with null pointer 1 !"); + MCAuto::FieldType> f(getFieldOnMeshAtLevel(ON_NODES,0,mm)); + MCAuto::FieldType> fOut(f->deepCopy()); + typename Traits::ArrayType *arr(f->getArray()); + MCAuto::ArrayType> newArr(arr->selectByTupleIdSafe(t->begin(),t->end())); + fOut->setArray(newArr); + ret->setFieldNoProfileSBT(fOut); + } + } + return ret.retn(); + } + + ////////////////////////// + + /*! + * 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. + */ + template + MEDFileField1TS *MEDFileNDTemplateField1TS::convertToDouble(bool isDeepCpyGlobs) const + { + MCAuto ret; + const MEDFileAnyTypeField1TSWithoutSDA *content(this->_content); + if(content) + { + const typename MLFieldTraits::F1TSWSDAType *contc(dynamic_cast::F1TSWSDAType *>(content)); + if(!contc) + { + std::ostringstream oss; oss << "MEDFileNDTemplateField1TS::convertToDouble : the content inside this is not " << MLFieldTraits::F1TSWSDAType::TYPE_STR << " ! This is incoherent !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + MCAuto newc(contc->convertToDouble()); + ret=static_cast(MEDFileAnyTypeField1TS::BuildNewInstanceFromContent((MEDFileField1TSWithoutSDA *)newc)); + } + else + ret=MEDFileField1TS::New(); + if(isDeepCpyGlobs) + ret->deepCpyGlobs(*this); + else + ret->shallowCpyGlobs(*this); + return ret.retn(); + } + + ////////////////////////// + + template + typename MLFieldTraits::FMTSWSDAType *MEDFileTemplateFieldMultiTSWithoutSDA::New(med_idt fid, const std::string& fieldName, const std::string& meshName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const MEDFileEntities *entities) + { + return new typename MLFieldTraits::FMTSWSDAType(fid,fieldName,meshName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities); + } + + template + void MEDFileTemplateFieldMultiTSWithoutSDA::checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const + { + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); + const typename MLFieldTraits::F1TSWSDAType *f1tsC(dynamic_cast::F1TSWSDAType *>(f1ts)); + if(!f1tsC) + { + std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType : the input field1TS is not a " << MLFieldTraits::F1TSWSDAType::TYPE_STR << " type !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + } + + template + const char *MEDFileTemplateFieldMultiTSWithoutSDA::getTypeStr() const + { + return MLFieldTraits::F1TSWSDAType::TYPE_STR; + } + + template + MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileTemplateFieldMultiTSWithoutSDA::createNew() const + { + return new typename MLFieldTraits::FMTSWSDAType; + } + + template + MEDFileAnyTypeField1TSWithoutSDA *MEDFileTemplateFieldMultiTSWithoutSDA::createNew1TSWithoutSDAEmptyInstance() const + { + return new typename MLFieldTraits::F1TSWSDAType; + } + + ////////////////////////// -#endif + template + MEDFileFieldMultiTSWithoutSDA *MEDFileNDTemplateFieldMultiTSWithoutSDA::convertToDouble() const + { + MCAuto ret(new MEDFileFieldMultiTSWithoutSDA); + ret->MEDFileAnyTypeFieldMultiTSWithoutSDA::operator =(*this); + int i=0; + for(std::vector< MCAuto >::const_iterator it=this->_time_steps.begin();it!=this->_time_steps.end();it++,i++) + { + const MEDFileAnyTypeField1TSWithoutSDA *eltToConv(*it); + if(eltToConv) + { + const typename MLFieldTraits::F1TSWSDAType *eltToConvC(dynamic_cast::F1TSWSDAType *>(eltToConv)); + if(!eltToConvC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::convertToInt : presence of an invalid 1TS type ! Should be of type INT32 !"); + MCAuto elt(eltToConvC->convertToDouble()); + ret->setIteration(i,elt); + } + } + return ret.retn(); + } + + ////////////////////////// + + template + MEDFileTemplateFieldMultiTS::MEDFileTemplateFieldMultiTS() + { + _content=new typename MLFieldTraits::FMTSWSDAType; + } + + template + MEDFileTemplateFieldMultiTS::MEDFileTemplateFieldMultiTS(med_idt fid, bool loadAll, const MEDFileMeshes *ms):MEDFileAnyTypeFieldMultiTS(fid,loadAll,ms) + { + } + + template + MEDFileTemplateFieldMultiTS::MEDFileTemplateFieldMultiTS(med_idt fid, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const MEDFileEntities *entities):MEDFileAnyTypeFieldMultiTS(fid,fieldName,loadAll,ms,entities) + { + } + + template + MEDFileTemplateFieldMultiTS::MEDFileTemplateFieldMultiTS(const typename MLFieldTraits::FMTSWSDAType& other, bool shallowCopyOfContent):MEDFileAnyTypeFieldMultiTS(other,shallowCopyOfContent) + { + } + + /*! + * Return an extraction of \a this using \a extractDef map to specify the extraction. + * The keys of \a extractDef is level relative to max ext of \a mm mesh. + * + * \return A new object that the caller is responsible to deallocate. + */ + template + typename MLFieldTraits::FMTSType *MEDFileTemplateFieldMultiTS::extractPartImpl(const std::map >& extractDef, MEDFileMesh *mm) const + { + if(!mm) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::extractPart : mesh is null !"); + MCAuto::FMTSType> fmtsOut(MLFieldTraits::FMTSType::New()); + int nbTS(getNumberOfTS()); + for(int i=0;i f1ts(getTimeStepAtPos(i)); + MCAuto::F1TSType> f1ts2(DynamicCastSafe::F1TSType>(f1ts)); + MCAuto::F1TSType> f1tsOut(f1ts2->extractPartImpl(extractDef,mm)); + fmtsOut->pushBackTimeStep(f1tsOut); + } + return fmtsOut.retn(); + } + + /*! + * Returns a new empty instance of MEDFileFieldMultiTS. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ + template + typename MLFieldTraits::FMTSType *MEDFileTemplateFieldMultiTS::New() + { + return new typename MLFieldTraits::FMTSType; + } + + /*! + * Returns a new instance of MEDFileTemplateFieldMultiTS 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 MEDFileTemplateFieldMultiTS * - a new instance of MEDFileTemplateFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + */ + template + typename MLFieldTraits::FMTSType *MEDFileTemplateFieldMultiTS::New(const std::string& fileName, bool loadAll) + { + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,loadAll); + } + + template + typename MLFieldTraits::FMTSType *MEDFileTemplateFieldMultiTS::New(med_idt fid, bool loadAll) + { + MCAuto::FMTSType> ret(new typename MLFieldTraits::FMTSType(fid,loadAll,0)); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); + } + + /*! + * Returns a new instance of MEDFileFieldMultiTS 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 MEDFileTemplateFieldMultiTS * - a new instance of MEDFileTemplateFieldMultiTS. 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. + */ + template + typename MLFieldTraits::FMTSType *MEDFileTemplateFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) + { + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + return New(fid,fieldName,loadAll); + } + + template + typename MLFieldTraits::FMTSType *MEDFileTemplateFieldMultiTS::New(med_idt fid, const std::string& fieldName, bool loadAll) + { + MCAuto::FMTSType> ret(new typename MLFieldTraits::FMTSType(fid,fieldName,loadAll,0)); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); + } + + /*! + * 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 MEDFileTemplateFieldMultiTS holding either a shallow copy + * of a given MEDFileTemplateFieldMultiTSWithoutSDA ( \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 MEDFileTemplateFieldMultiTS * - a new instance of MEDFileTemplateFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ + template + typename MLFieldTraits::FMTSType *MEDFileTemplateFieldMultiTS::New(const typename MLFieldTraits::FMTSWSDAType& other, bool shallowCopyOfContent) + { + return new typename MLFieldTraits::FMTSType(other,shallowCopyOfContent); + } + + template + typename MLFieldTraits::FMTSType *MEDFileTemplateFieldMultiTS::LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll) + { + MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName)); + INTERP_KERNEL::AutoCppPtr ent(new MEDFileStaticEntities(entities)); + MCAuto::FMTSType> ret(new typename MLFieldTraits::FMTSType(fid,fieldName,loadAll,0,ent)); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); + } + + /*! + * This is the simplest version to fetch a field for MED structure. One drawback : if \a this is a complex field (multi spatial discretization inside a same field) this method will throw exception and more advance + * method should be called (getFieldOnMeshAtLevel for example). + * But for normal usage of field in MED file world this method is the most efficient to fetch data. + * + * \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 mesh the field is lying on + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + */ + template + typename Traits::FieldType *MEDFileTemplateFieldMultiTS::field(int iteration, int order, const MEDFileMesh *mesh) const + { + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS(contentNotNullBase()->getTimeStepEntry(iteration,order)); + MCAuto arrOut; + MCAuto ret(myF1TS.fieldOnMesh(this,mesh,arrOut,*contentNotNullBase())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * 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 [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. + */ + template + typename Traits::FieldType *MEDFileTemplateFieldMultiTS::getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol) const + { + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS(contentNotNullBase()->getTimeStepEntry(iteration,order)); + const typename MLFieldTraits::F1TSWSDAType *myF1TSC(dynamic_cast::F1TSWSDAType *>(&myF1TS)); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::getFieldAtLevel : mismatch of type of field expecting FLOAT64 !"); + MCAuto arrOut; + MCAuto ret(myF1TSC->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNullBase())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * 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 [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. + */ + template + typename Traits::FieldType *MEDFileTemplateFieldMultiTS::getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol) const + { + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS(contentNotNullBase()->getTimeStepEntry(iteration,order)); + const typename MLFieldTraits::F1TSWSDAType *myF1TSC(dynamic_cast::F1TSWSDAType *>(&myF1TS)); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::getFieldAtTopLevel : mismatch of type of field !"); + MCAuto arrOut; + MCAuto ret(myF1TSC->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNullBase())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * 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 [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. + */ + template + typename Traits::FieldType *MEDFileTemplateFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const + { + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS(contentNotNullBase()->getTimeStepEntry(iteration,order)); + const typename MLFieldTraits::F1TSWSDAType *myF1TSC(dynamic_cast::F1TSWSDAType *>(&myF1TS)); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field !"); + MCAuto arrOut; + MCAuto ret(myF1TSC->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arrOut,*contentNotNullBase())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * 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 [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. + */ + template + typename Traits::FieldType *MEDFileTemplateFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol) const + { + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS(contentNotNullBase()->getTimeStepEntry(iteration,order)); + const typename MLFieldTraits::F1TSWSDAType *myF1TSC(dynamic_cast::F1TSWSDAType *>(&myF1TS)); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field !"); + MCAuto arrOut; + MCAuto ret(myF1TSC->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arrOut,*contentNotNullBase())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * This method has a close behaviour than MEDFileFieldMultiTS::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. + */ + template + typename Traits::FieldType *MEDFileTemplateFieldMultiTS::getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, int renumPol) const + { + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS(contentNotNullBase()->getTimeStepEntry(iteration,order)); + const typename MLFieldTraits::F1TSWSDAType *myF1TSC(dynamic_cast::F1TSWSDAType *>(&myF1TS)); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::getFieldAtLevelOld : mismatch of type of field !"); + MCAuto arrOut; + MCAuto ret(myF1TSC->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNullBase())); + MCAuto::FieldType> ret2(MEDFileTemplateField1TS::SetDataArrayInField(ret,arrOut)); + return ret2.retn(); + } + + /*! + * 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 DataArrayIdType 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 required parameters are available. + */ + template + typename Traits::ArrayType *MEDFileTemplateFieldMultiTS::getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayIdType *&pfl) const + { + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS(contentNotNullBase()->getTimeStepEntry(iteration,order)); + const typename MLFieldTraits::F1TSWSDAType *myF1TSC(dynamic_cast::F1TSWSDAType *>(&myF1TS)); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::getFieldWithProfile : mismatch of type of field !"); + MCAuto ret(myF1TSC->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNullBase())); + return MEDFileTemplateField1TS::ReturnSafelyTypedDataArray(ret); + } + + /*! + * 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. + */ + template + void MEDFileTemplateFieldMultiTS::appendFieldNoProfileSBT(const typename Traits::FieldType *field) + { + const typename Traits::ArrayType *arr(NULL); + if(field) + arr=field->getArray(); + MCAuto field2(MEDFileTemplateField1TS::ToFieldTemplateWithTime(field)); + contentNotNull()->appendFieldNoProfileSBT(field2,arr,*this); + } + + /*! + * 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 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, appendFieldProfileFlatly + */ + template + void MEDFileTemplateFieldMultiTS::appendFieldProfile(const typename Traits::FieldType *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayIdType *profile) + { + appendFieldProfileGeneral(field,mesh,meshDimRelToMax,profile,true); + } + + /*! + * same as appendFieldProfile except that here profile is created unconditionaly + */ + template + void MEDFileTemplateFieldMultiTS::appendFieldProfileFlatly(const typename Traits::FieldType *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayIdType *profile) + { + appendFieldProfileGeneral(field,mesh,meshDimRelToMax,profile,false); + } + + template + void MEDFileTemplateFieldMultiTS::appendFieldProfileGeneral(const typename Traits::FieldType *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayIdType *profile, bool smartPflKiller) + { + const typename Traits::ArrayType *arr(NULL); + if(field) + arr=field->getArray(); + MCAuto field2(MEDFileTemplateField1TS::ToFieldTemplateWithTime(field)); + contentNotNull()->appendFieldProfile(field2,arr,mesh,meshDimRelToMax,profile,*this,smartPflKiller); + } + + template + const typename MLFieldTraits::FMTSWSDAType *MEDFileTemplateFieldMultiTS::contentNotNull() const + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::contentNotNull : the content pointer is null !"); + const typename MLFieldTraits::FMTSWSDAType *ret=dynamic_cast::FMTSWSDAType *>(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::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; + } + + template + typename MLFieldTraits::FMTSWSDAType *MEDFileTemplateFieldMultiTS::contentNotNull() + { + MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::contentNotNull : the non const content pointer is null !"); + typename MLFieldTraits::FMTSWSDAType *ret(dynamic_cast::FMTSWSDAType *>(pt)); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::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; + } + + /*! + * 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. + */ + template + typename MLFieldTraits::F1TSType *MEDFileTemplateFieldMultiTS::getTimeStepAtPos(int pos) const + { + 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()); + } + const typename MLFieldTraits::F1TSWSDAType *itemC=dynamic_cast::F1TSWSDAType *>(item); + if(itemC) + { + MCAuto::F1TSType> ret(MLFieldTraits::F1TSType::New(*itemC,false)); + ret->shallowCpyGlobs(*this); + return ret.retn(); + } + std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepAtPos : type of field at pos #" << pos << " is not " << MLFieldTraits::F1TSWSDAType::TYPE_STR << " !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + + template + typename Traits::ArrayType *MEDFileTemplateFieldMultiTS::getUndergroundDataArray(int iteration, int order) const + { + DataArray *ret(contentNotNull()->getUndergroundDataArray(iteration,order)); + if(!ret) + return NULL; + typename Traits::ArrayType *ret2(dynamic_cast::ArrayType *>(ret)); + if(!ret2) + { + std::ostringstream oss; oss << "MEDFileTemplateFieldMultiTS::getUndergroundDataArray : invalid type of data detected ! Expecting " << MLFieldTraits::F1TSWSDAType::TYPE_STR; + throw INTERP_KERNEL::Exception(oss.str()); + } + return ret2; + } + + template + typename Traits::ArrayType *MEDFileTemplateFieldMultiTS::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const + { + DataArray *ret(contentNotNull()->getUndergroundDataArrayExt(iteration,order,entries)); + if(!ret) + return NULL; + typename Traits::ArrayType *ret2(dynamic_cast::ArrayType *>(ret)); + if(!ret2) + { + std::ostringstream oss; oss << "MEDFileTemplateFieldMultiTS::getUndergroundDataArrayExt : invalid type of data detected ! Expecting " << MLFieldTraits::F1TSWSDAType::TYPE_STR; + throw INTERP_KERNEL::Exception(oss.str()); + } + return ret2; + } + + template + typename MLFieldTraits::FMTSType *MEDFileTemplateFieldMultiTS::buildNewEmptyImpl() const + { + return MLFieldTraits::FMTSType::New(); + } + + template + void MEDFileTemplateFieldMultiTS::checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const + { + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileTemplateFieldMultiTS::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); + const typename MLFieldTraits::F1TSType *f1tsC=dynamic_cast::F1TSType *>(f1ts); + if(!f1tsC) + { + std::ostringstream oss; oss << "MEDFileTemplateFieldMultiTS::checkCoherencyOfType : the input field1TS is not a " << MLFieldTraits::F1TSWSDAType::TYPE_STR << " type !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + } + + ////////////////////////// + + /*! + * 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. + */ + template + MEDFileFieldMultiTS *MEDFileNDTemplateFieldMultiTS::convertToDouble(bool isDeepCpyGlobs) const + { + MCAuto ret; + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(this->_content); + if(content) + { + const typename MLFieldTraits::FMTSWSDAType *contc=dynamic_cast::FMTSWSDAType *>(content); + if(!contc) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::convertToInt : the content inside this is not INT32 ! This is incoherent !"); + MCAuto newc(contc->convertToDouble()); + ret=static_cast(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent((MEDFileFieldMultiTSWithoutSDA *)newc)); + } + else + ret=MEDFileFieldMultiTS::New(); + if(isDeepCpyGlobs) + ret->deepCpyGlobs(*this); + else + ret->shallowCpyGlobs(*this); + return ret.retn(); + } +}