X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingField.cxx;h=bf5c05ac63ad8dfa3ce2fb600fe3cb906824ed99;hb=378cb2ebe08f8f4543ef632b2bd5f77fe180f978;hp=4d75b20ebdf208b838169bdd64b626225b19faf7;hpb=afaa18a980c8c9bd0e48b95c6aa7acf7a6161e1a;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingField.cxx b/src/MEDCoupling/MEDCouplingField.cxx old mode 100644 new mode 100755 index 4d75b20eb..bf5c05ac6 --- a/src/MEDCoupling/MEDCouplingField.cxx +++ b/src/MEDCoupling/MEDCouplingField.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2014 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 @@ -26,7 +26,7 @@ using namespace ParaMEDMEM; -bool MEDCouplingField::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const throw(INTERP_KERNEL::Exception) +bool MEDCouplingField::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const { if(!other) throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualIfNotWhy : other instance is NULL !"); @@ -69,14 +69,36 @@ bool MEDCouplingField::isEqualIfNotWhy(const MEDCouplingField *other, double mes return ret; } +/*! + * Checks if \a this and another MEDCouplingField are fully equal. + * \param [in] other - the field to compare with \a this one. + * \param [in] meshPrec - precision used to compare node coordinates of the underlying mesh. + * \param [in] valsPrec - precision used to compare field values. + * \return bool - \c true if the two fields are equal, \c false else. + * \throw If \a other is NULL. + */ bool MEDCouplingField::isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const { std::string tmp; return isEqualIfNotWhy(other,meshPrec,valsPrec,tmp); } +/*! + * Checks if \a this and another MEDCouplingField are equal. The textual + * information like names etc. is not considered. + * \param [in] other - the field to compare with \a this one. + * \param [in] meshPrec - precision used to compare node coordinates of the underlying mesh. + * \param [in] valsPrec - precision used to compare field values. + * \return bool - \c true if the two fields are equal, \c false else. + * \throw If \a other is NULL. + * \throw If the spatial discretization of \a this field is NULL. + */ bool MEDCouplingField::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualWithoutConsideringStr : input field is NULL !"); + if(!_type) + throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualWithoutConsideringStr : spatial discretization of this is NULL !"); if(!_type->isEqualWithoutConsideringStr(other->_type,valsPrec)) return false; if(_nature!=other->_nature) @@ -97,6 +119,8 @@ bool MEDCouplingField::isEqualWithoutConsideringStr(const MEDCouplingField *othe */ bool MEDCouplingField::areCompatibleForMerge(const MEDCouplingField *other) const { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingField::areCompatibleForMerge : input field is NULL !"); if(!_type->isEqual(other->_type,1.)) return false; if(_nature!=other->_nature) @@ -112,6 +136,8 @@ bool MEDCouplingField::areCompatibleForMerge(const MEDCouplingField *other) cons */ bool MEDCouplingField::areStrictlyCompatible(const MEDCouplingField *other) const { + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingField::areStrictlyCompatible : input field is NULL !"); if(!_type->isEqual(other->_type,1.e-12)) return false; if(_nature!=other->_nature) @@ -127,27 +153,44 @@ void MEDCouplingField::updateTime() const updateTimeWith(*_type); } -std::size_t MEDCouplingField::getHeapMemorySize() const +std::size_t MEDCouplingField::getHeapMemorySizeWithoutChildren() const { std::size_t ret=0; ret+=_name.capacity(); ret+=_desc.capacity(); - if(_mesh) - ret+=_mesh->getHeapMemorySize(); - if((const MEDCouplingFieldDiscretization *)_type) - ret+=_type->getHeapMemorySize(); return ret; } +std::vector MEDCouplingField::getDirectChildrenWithNull() const +{ + std::vector ret; + ret.push_back(_mesh); + ret.push_back((const MEDCouplingFieldDiscretization *)_type); + return ret; +} + +/*! + * Returns a type of \ref MEDCouplingSpatialDisc "spatial discretization" of \a this + * field in terms of enum ParaMEDMEM::TypeOfField. + * \return ParaMEDMEM::TypeOfField - the type of \a this field. + * \throw If the geometric type is empty. + */ TypeOfField MEDCouplingField::getTypeOfField() const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingField::getTypeOfField : spatial discretization is null !"); return _type->getEnum(); } /*! - * This method returns the nature of field. This information is very important during interpolation process using ParaMEDMEM::MEDCouplingRemapper or ParaMEDMEM::InterpKernelDEC. - * In other context than the two mentioned before this attribute of the field is not sensitive. This attribute is not store in MED file in MEDLoader. - * More information of the semantic, and the consequence of this attribute in the result of the interpolation, is available \ref NatureOfField "here". + * Returns the nature of \a this field. This information is very important during + * interpolation process using ParaMEDMEM::MEDCouplingRemapper or ParaMEDMEM::InterpKernelDEC. + * In other context than the two mentioned above, this attribute is unimportant. This + * attribute is not stored in the MED file. + * For more information of the semantics and the influence of this attribute to the + * result of interpolation, see + * - \ref NatureOfField + * - \ref TableNatureOfField "How interpolation coefficients depend on Field Nature" */ NatureOfField MEDCouplingField::getNature() const { @@ -155,39 +198,76 @@ NatureOfField MEDCouplingField::getNature() const } /*! - * This method set the nature of field in \b this.This information is very important during interpolation process using ParaMEDMEM::MEDCouplingRemapper or ParaMEDMEM::InterpKernelDEC. - * In other context than the two mentioned before this attribute of the field is not sensitive. This attribute is not store in MED file in MEDLoader. - * More information of the semantic, and the consequence of this attribute in the result of the interpolation, is available \ref TableNatureOfField "here". + * Sets the nature of \a this field. This information is very important during + * interpolation process using ParaMEDMEM::MEDCouplingRemapper or ParaMEDMEM::InterpKernelDEC. + * In other context than the two mentioned above, this attribute is unimportant. This + * attribute is not stored in the MED file. + * For more information of the semantics and the influence of this attribute to the + * result of interpolation, see + * - \ref NatureOfField + * - \ref TableNatureOfField "How interpolation coefficients depend on Field Nature" + * + * \param [in] nat - the nature of \a this field. + * \throw If \a nat has an invalid value. */ -void MEDCouplingField::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception) +void MEDCouplingField::setNature(NatureOfField nat) { + MEDCouplingNatureOfField::GetRepr(nat);//generate a throw if nat not recognized _nature=nat; } /*! - * This method returns is case of success an instance of DataArrayDouble the user is in reponsability to deal with. - * If 'this->_mesh' is not set an exception will be thrown. - * For a field on node the array of coords will be returned. For a field on cell a ParaMEDMEM::DataArrayDouble instance - * containing the barycenter of cells will be returned. And for a field on gauss point the explicit position of gauss points. + * Returns coordinates of field location points that depend on + * \ref MEDCouplingSpatialDisc "spatial discretization" of \a this field. + * - For a field on nodes, returns coordinates of nodes. + * - For a field on cells, returns barycenters of cells. + * - For a field on gauss points, returns coordinates of gauss points. + * + * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ -DataArrayDouble *MEDCouplingField::getLocalizationOfDiscr() const throw(INTERP_KERNEL::Exception) +DataArrayDouble *MEDCouplingField::getLocalizationOfDiscr() const { if(!_mesh) throw INTERP_KERNEL::Exception("MEDCouplingField::getLocalizationOfDiscr : No mesh set !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingField::getLocalizationOfDiscr : No spatial discretization set !"); return _type->getLocalizationOfDiscValues(_mesh); } /*! - * This method retrieves the measure field of 'this'. If no '_mesh' is defined an exception will be thrown. - * Warning the retrieved field life cycle is the responsability of caller. + * Returns a new MEDCouplingFieldDouble containing volumes of cells of a dual mesh whose + * cells are constructed around field location points (getLocalizationOfDiscr()) of \a this + * field. (In case of a field on cells, the dual mesh coincides with the underlying mesh).
+ * For 1D cells, the returned field contains lengths.
+ * For 2D cells, the returned field contains areas.
+ * For 3D cells, the returned field contains volumes. + * \param [in] isAbs - if \c true, the computed cell volume does not reflect cell + * orientation, i.e. the volume is always positive. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. + * The caller is to delete this array using decrRef() as + * it is no more needed. + * \throw If the mesh is not set. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the spatial discretization of \a this field is not well defined. */ -MEDCouplingFieldDouble *MEDCouplingField::buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception) + +MEDCouplingFieldDouble *MEDCouplingField::buildMeasureField(bool isAbs) const { - if(_mesh==0) - throw INTERP_KERNEL::Exception("MEDCouplingField::getMeasureField : no mesh defined !!!"); + if(!_mesh) + throw INTERP_KERNEL::Exception("MEDCouplingField::buildMeasureField : no mesh defined !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingField::buildMeasureField : No spatial discretization set !"); return _type->getMeasureField(_mesh,isAbs); } +/*! + * Sets the underlying mesh of \a this field. + * For examples of field construction, see \ref MEDCouplingFirstSteps3. + * \param [in] mesh - the new underlying mesh. + */ void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh) { if(mesh!=_mesh) @@ -195,6 +275,7 @@ void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh) if(_mesh) _mesh->decrRef(); _mesh=mesh; + declareAsNew(); if(_mesh) { _mesh->incrRef(); @@ -204,129 +285,175 @@ void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh) } /*! - * This method sets gauss localization by geometric type. - * @param type geometric type on which the gauss localization will be set. - * @param refCoo is the reference coordinates of the specified element. Its size has to be equal to nbOfNodesPerCell*dimOfType - * @param gsCoo are the coordinates of Gauss points in reference element specified by 'refCoo'. Its size must be equal to wg.size()*dimOfType - * @param wg are the weights on Gauss points. The size of this array is used to determine the number of Gauss point in the element. - * @throw when size of 'RefCoo' is not valid regarding 'type' parameter, it throws too when the mesh is not set before or if it is not a field on Gauss points. + * Sets localization of Gauss points for a given geometric type of cell. + * \param [in] type - the geometric type of cell for which the Gauss localization is set. + * \param [in] refCoo - coordinates of points of the reference cell. Size of this vector + * must be \c nbOfNodesPerCell * \c dimOfType. + * \param [in] gsCoo - coordinates of Gauss points on the reference cell. Size of this vector + * must be _wg_.size() * \c dimOfType. + * \param [in] wg - the weights of Gauss points. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \throw If size of any vector do not match the \a type. */ void MEDCouplingField::setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) + const std::vector& gsCoo, const std::vector& wg) { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnType method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call setGaussLocalizationOnType method !"); _type->setGaussLocalizationOnType(_mesh,type,refCoo,gsCoo,wg); } /*! - * This method sets on ids defined by [begin;end) their gauss localization. This method checks the coherency of cells ids in [begin;end) and 'refCoo' size. - * If an incoherence appears an exception will be thrown and no seting will be performed. - * An exception is thrown too if [begin,end) has a size lesser than 1. - * - * @param refCoo is the reference coordinates of the specified element. Its size has to be equal to nbOfNodesPerCell*dimOfType - * @param gsCoo are the coordinates of Gauss points in reference element specified by 'refCoo'. Its size must be equal to wg.size()*dimOfType - * @param wg are the weights on Gauss points. The size of this array is used to determine the number of Gauss point in the element. - * @throw when size of 'RefCoo' is not valid regarding cells in [begin,end) parameters, it throws too when the mesh is not set before or if it is not a field on Gauss points. + * Sets localization of Gauss points for given cells specified by their ids. + * \param [in] begin - an array of cell ids of interest. + * \param [in] end - the end of \a begin, i.e. a pointer to its (last+1)-th element. + * \param [in] refCoo - coordinates of points of the reference cell. Size of this vector + * must be \c nbOfNodesPerCell * \c dimOfType. + * \param [in] gsCoo - coordinates of Gauss points on the reference cell. Size of this vector + * must be _wg_.size() * \c dimOfType. + * \param [in] wg - the weights of Gauss points. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \throw If size of any vector do not match the type of cell # \a begin[0]. + * \throw If type of any cell in \a begin differs from that of cell # \a begin[0]. + * \throw If the range [_begin_,_end_) is empty. */ void MEDCouplingField::setGaussLocalizationOnCells(const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) + const std::vector& gsCoo, const std::vector& wg) { if(!_mesh) throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnCells method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call setGaussLocalizationOnCells method !"); _type->setGaussLocalizationOnCells(_mesh,begin,end,refCoo,gsCoo,wg); } /*! - * This method resets all Gauss loalizations if any. + * Clears data on Gauss points localization. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. */ void MEDCouplingField::clearGaussLocalizations() { - if(!_mesh) - throw INTERP_KERNEL::Exception("Mesh has to be set before calling clearGaussLocalizations method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call clearGaussLocalizations method !"); _type->clearGaussLocalizations(); } /*! - * This method returns reference to the Gauss localization object corresponding to 'locId' id. - * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if 'locId' is invalid because out of range given by - * MEDCouplingField::getNbOfGaussLocalization method. - * Warning this method is not const, so the returned object could be modified without any problem. + * Returns a reference to the Gauss localization object by its id. + * \warning This method is not const, so the returned object can be modified without any + * problem. + * \param [in] locId - the id of the Gauss localization object of interest. + * It must be in range 0 <= locId < getNbOfGaussLocalization() . + * \return \ref MEDCouplingGaussLocalization & - the Gauss localization object. + * \throw If \a this field is not on Gauss points. + * \throw If \a locId is not within the valid range. + * \throw If the spatial discretization of \a this field is NULL. */ -MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception) +MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) { - if(!_mesh) - throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalization method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !"); return _type->getGaussLocalization(locId); } /*! - * This method returns reference to the Gauss localization object corresponding to 'locId' id. - * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if several localization ids have been found - * for a type. + * Returns an id of the Gauss localization object corresponding to a given cell type. + * \param [in] type - the cell type of interest. + * \return int - the id of the Gauss localization object. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If no Gauss localization object found for the given cell \a type. + * \throw If more than one Gauss localization object found for the given cell \a type. */ -int MEDCouplingField::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) +int MEDCouplingField::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const { - if(!_mesh) - throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneType method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneType method !"); return _type->getGaussLocalizationIdOfOneType(type); } -std::set MEDCouplingField::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) +/*! + * Returns ids of Gauss localization objects corresponding to a given cell type. + * \param [in] type - the cell type of interest. + * \return std::set - ids of the Gauss localization object. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL + */ +std::set MEDCouplingField::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const { - if(!_mesh) - throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdsOfOneType method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdsOfOneType method !"); return _type->getGaussLocalizationIdsOfOneType(type); } /*! - * This method returns number of Gauss localization available. Implicitely all ids in [0,getNbOfGaussLocalization()) is a valid Gauss localisation id. - * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) + * Returns number of Gauss localization objects available. Implicitly all ids in + * [0,getNbOfGaussLocalization()) are valid Gauss localization ids. + * \return int - the number of available Gauss localization objects. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. */ -int MEDCouplingField::getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception) +int MEDCouplingField::getNbOfGaussLocalization() const { - if(!_mesh) - throw INTERP_KERNEL::Exception("Mesh has to be set before calling getNbOfGaussLocalization method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNbOfGaussLocalization method !"); return _type->getNbOfGaussLocalization(); } /*! - * This method returns an id of Gauss localization in [0,getNbOfGaussLocalization()) that corresponds to the localization of the cell specified by its cellId. - * This methods throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) or if at the cell with id 'cellId' in this->_mesh no - * Gauss localization has been set. + * Returns an id of the Gauss localization object corresponding to a type of a given cell. + * \param [in] cellId - an id of the cell of interest. + * \return int - the id of the Gauss localization object. + * \throw If \a this field is not on Gauss points. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If no Gauss localization object found for the given cell. */ -int MEDCouplingField::getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception) +int MEDCouplingField::getGaussLocalizationIdOfOneCell(int cellId) const { - if(!_mesh) - throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneCell method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneCell method !"); return _type->getGaussLocalizationIdOfOneCell(cellId); } /*! - * This method returns all cellIds that share the same Gauss localization given by 'locId' parameter (in range [0,getNbOfGaussLocalization()) ). - * If no cells fit the Gauss localization given by 'locId' cellIds will be returned empty. - * @param locId input that specifies the id of Gauss localization. - * @param cellIds output parameter, that will contain the result if this method succeds. This parameter is systematically cleared when called. - * @throw if there is no mesh, invalid FieldDescription (different from Gauss) or if locId not in [0,getNbOfGaussLocalization()) + * Returns ids of cells that share the same Gauss localization given by its id. + * \param [in] locId - the id of the Gauss localization object of interest. + * It must be in range 0 <= locId < getNbOfGaussLocalization() . + * \param [in,out] cellIds - a vector returning ids of found cells. It is cleared before + * filling in. It remains empty if no cells found. + * \throw If \a this field is not on Gauss points. + * \throw If \a locId is not within the valid range. + * \throw If the spatial discretization of \a this field is NULL. */ -void MEDCouplingField::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception) +void MEDCouplingField::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const { cellIds.clear(); - if(!_mesh) - throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneCell method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getCellIdsHavingGaussLocalization method !"); _type->getCellIdsHavingGaussLocalization(locId,cellIds); } /*! - * This method returns reference to the Gauss localization object corresponding to 'locId' id. - * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if 'locId' is invalid because out of range given by - * MEDCouplingField::getNbOfGaussLocalization method. - * Warning this method is const. + * Returns a reference to the Gauss localization object by its id. + * \warning This method is const, so the returned object is not apt for modification. + * \param [in] locId - the id of the Gauss localization object of interest. + * It must be in range 0 <= locId < getNbOfGaussLocalization() . + * \return \ref const MEDCouplingGaussLocalization & - the Gauss localization object. + * \throw If \a this field is not on Gauss points. + * \throw If \a locId is not within the valid range. + * \throw If the spatial discretization of \a this field is NULL. */ -const MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) +const MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) const { - if(!_mesh) - throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalization method !"); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !"); return _type->getGaussLocalization(locId); } @@ -345,7 +472,7 @@ MEDCouplingField::MEDCouplingField(TypeOfField type):_nature(NoNature),_mesh(0), } MEDCouplingField::MEDCouplingField(const MEDCouplingField& other, bool deepCopy):RefCountObject(other),_name(other._name),_desc(other._desc),_nature(other._nature), - _mesh(0),_type(0) + _mesh(0),_type(0) { if(other._mesh) { @@ -359,41 +486,95 @@ MEDCouplingField::MEDCouplingField(const MEDCouplingField& other, bool deepCopy) } /*! - * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end). - * @param di is an array returned that specifies entity ids (nodes, cells ids...) in mesh 'mesh' of entity in returned submesh. + * Returns a new MEDCouplingMesh constituted by some cells of the underlying mesh of \a + * this filed, and returns ids of entities (nodes, cells, Gauss points) lying on the + * specified cells. The cells to include to the result mesh are specified by an array of + * cell ids. The new mesh shares the coordinates array with the underlying mesh. + * \param [in] start - an array of cell ids to include to the result mesh. + * \param [in] end - specifies the end of the array \a start, so that + * the last value of \a start is \a end[ -1 ]. + * \param [out] di - a new instance of DataArrayInt holding the ids of entities (nodes, + * cells, Gauss points). The caller is to delete this array using decrRef() as it + * is no more needed. + * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. + * \sa buildSubMeshDataRange() */ MEDCouplingMesh *MEDCouplingField::buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshData method !"); return _type->buildSubMeshData(_mesh,start,end,di); } +/*! + * This method returns a submesh of 'mesh' instance constituting cell ids defined by a range given by the 3 following inputs \a begin, \a end and \a step. + * + * \param [out] beginOut Valid only if \a di is NULL + * \param [out] endOut Valid only if \a di is NULL + * \param [out] stepOut Valid only if \a di is NULL + * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable. + * + * \sa MEDCouplingField::buildSubMeshData + */ +MEDCouplingMesh *MEDCouplingField::buildSubMeshDataRange(int begin, int end, int step, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshDataRange method !"); + return _type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,di); +} + /*! * This method returns tuples ids implied by the mesh selection of the cell ids contained in array defined as an interval [start;end). * \return a newly allocated DataArrayInt instance containing tuples ids. */ DataArrayInt *MEDCouplingField::computeTupleIdsToSelectFromCellIds(const int *startCellIds, const int *endCellIds) const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call computeTupleIdsToSelectFromCellIds method !"); return _type->computeTupleIdsToSelectFromCellIds(_mesh,startCellIds,endCellIds); } /*! - * This method returns number of tuples expected regarding its discretization and its _mesh attribute. - * This method expected a not null _mesh instance. If null, an exception will be thrown. + * Returns number of tuples expected regarding the spatial discretization of \a this + * field and number of entities in the underlying mesh. This method behaves exactly as MEDCouplingFieldDouble::getNumberOfTuples. + * \return int - the number of expected tuples. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ -int MEDCouplingField::getNumberOfTuplesExpected() const throw(INTERP_KERNEL::Exception) +int MEDCouplingField::getNumberOfTuplesExpected() const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNumberOfTuplesExpected method !"); if(_mesh) return _type->getNumberOfTuples(_mesh); else throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfTuplesExpected : Empty mesh !"); } +void MEDCouplingField::setDiscretization(MEDCouplingFieldDiscretization *newDisc) +{ + bool needUpdate=(const MEDCouplingFieldDiscretization *)_type!=newDisc; + _type=newDisc; + if(newDisc) + newDisc->incrRef(); + if(needUpdate) + declareAsNew(); +} + /*! - * This method returns number of mesh placed expected regarding its discretization and its _mesh attribute. - * This method expected a not null _mesh instance. If null, an exception will be thrown. + * Returns number of mesh entities in the underlying mesh of \a this field regarding the + * spatial discretization. + * \return int - the number of mesh entities porting the field values. + * \throw If the spatial discretization of \a this field is NULL. + * \throw If the mesh is not set. */ -int MEDCouplingField::getNumberOfMeshPlacesExpected() const throw(INTERP_KERNEL::Exception) +int MEDCouplingField::getNumberOfMeshPlacesExpected() const { + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNumberOfMeshPlacesExpected method !"); if(_mesh) return _type->getNumberOfMeshPlaces(_mesh); else @@ -403,11 +584,36 @@ int MEDCouplingField::getNumberOfMeshPlacesExpected() const throw(INTERP_KERNEL: /*! * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason). */ -void MEDCouplingField::copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception) +void MEDCouplingField::copyTinyStringsFrom(const MEDCouplingField *other) { if(other) { - setName(other->_name.c_str()); - setDescription(other->_desc.c_str()); + setName(other->_name); + setDescription(other->_desc); } } + +/*! + * This method computes the number of tuples a DataArrayDouble instance should have to build a correct MEDCouplingFieldDouble instance starting from a + * submesh of a virtual mesh on which a substraction per type had been applied regarding the spatial discretization in \a this. + * + * For spatial discretization \b not equal to ON_GAUSS_NE this method will make the hypothesis that any positive entity id in \a code \a idsPerType is valid. + * So in those cases attribute \a _mesh of \a this is ignored. + * + * For spatial discretization equal to ON_GAUSS_NE \a _mesh attribute will be taken into account. + * + * The input code is those implemented in MEDCouplingUMesh::splitProfilePerType. + * + * \param [in] code - a code with format described above. + * \param [in] idsPerType - a list of subparts + * \throw If \a this has no spatial discretization set. + * \throw If input code point to invalid zones in spatial discretization. + * \throw If spatial discretization in \a this requires a mesh and those mesh is invalid (null,...) + */ +int MEDCouplingField::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const +{ + const MEDCouplingFieldDiscretization *t(_type); + if(!t) + throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfTuplesExpectedRegardingCode : no spatial discretization set !"); + return t->getNumberOfTuplesExpectedRegardingCode(code,idsPerType); +}