-// Copyright (C) 2007-2013 CEA/DEN, EDF R&D
+// Copyright (C) 2007-2024 CEA, EDF
//
// 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
#include "MEDCouplingMesh.hxx"
#include "MEDCouplingUMesh.hxx"
-#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingMemArray.txx"
#include "MEDCouplingFieldDouble.hxx"
#include "MEDCouplingFieldDiscretization.hxx"
-#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include "MCAuto.hxx"
#include <set>
#include <cmath>
#include <fstream>
#include <iterator>
-using namespace ParaMEDMEM;
+using namespace MEDCoupling;
MEDCouplingMesh::MEDCouplingMesh():_time(0.),_iteration(-1),_order(-1)
{
}
-MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other):_name(other._name),_description(other._description),
+MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other):RefCountObject(other),_name(other._name),_description(other._description),
_time(other._time),_iteration(other._iteration),
_order(other._order),_time_unit(other._time_unit)
{
}
-std::size_t MEDCouplingMesh::getHeapMemorySize() const
+std::size_t MEDCouplingMesh::getHeapMemorySizeWithoutChildren() const
{
return _name.capacity()+_description.capacity()+_time_unit.capacity();
}
return getType()==CARTESIAN;
}
-bool MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
+bool MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
{
if(!other)
throw INTERP_KERNEL::Exception("MEDCouplingMesh::isEqualIfNotWhy : other instance is NULL !");
* \param [in] prec - precision value used to compare node coordinates.
* \return bool - \c true if the two meshes are equal, \c false else.
*/
-bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
+bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const
{
std::string tmp;
return isEqualIfNotWhy(other,prec,tmp);
* to be compared. An interpolation using MEDCouplingRemapper class should be then used.
*/
void MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec,
- DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
+ DataArrayIdType *&cellCor, DataArrayIdType *&nodeCor) const
{
cellCor=0;
nodeCor=0;
* \param [in] partBg - the array of node ids.
* \param [in] partEnd - end of \a partBg, i.e. a pointer to a (last+1)-th element
* of \a partBg.
- * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found
+ * \return DataArrayIdType * - a new instance of DataArrayIdType holding ids of found
* cells. The caller is to delete this array using decrRef() as it is no
* more needed.
*/
-DataArrayInt *MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const
+DataArrayIdType *MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const mcIdType *partBg, const mcIdType *partEnd) const
{
- std::vector<int> crest;
- std::set<int> p(partBg,partEnd);
- int nbOfCells=getNumberOfCells();
- for(int i=0;i<nbOfCells;i++)
+ std::vector<mcIdType> crest;
+ std::set<mcIdType> p(partBg,partEnd);
+ mcIdType nbOfCells=getNumberOfCells();
+ for(mcIdType i=0;i<nbOfCells;i++)
{
- std::vector<int> conn;
+ std::vector<mcIdType> conn;
getNodeIdsOfCell(i,conn);
bool cont=true;
- for(std::vector<int>::const_iterator iter=conn.begin();iter!=conn.end() && cont;iter++)
+ for(std::vector<mcIdType>::const_iterator iter=conn.begin();iter!=conn.end() && cont;iter++)
if(p.find(*iter)==p.end())
cont=false;
if(cont)
crest.push_back(i);
}
- DataArrayInt *ret=DataArrayInt::New();
- ret->alloc((int)crest.size(),1);
+ DataArrayIdType *ret=DataArrayIdType::New();
+ ret->alloc(crest.size(),1);
std::copy(crest.begin(),crest.end(),ret->getPointer());
return ret;
}
/*!
* This method checks fastly that \a this and \a other are equal. All common checks are done here.
*/
-void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const
{
if(!other)
throw INTERP_KERNEL::Exception("MEDCouplingMesh::checkFastEquivalWith : input mesh is null !");
}
/*!
- * This method is very poor and looks only if \a this and \a other are candidate for merge of fields lying repectively on them.
+ * This method is very poor and looks only if \a this and \a other are candidate for merge of fields lying respectively on them.
*/
bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const
{
/*!
* This method is equivalent to MEDCouplingMesh::buildPart method except that here the cell ids are specified using slice \a beginCellIds \a endCellIds and \a stepCellIds.
+ * \b WARNING , there is a big difference compared to MEDCouplingMesh::buildPart method.
+ * If the input range is equal all cells in \a this, \a this is returned !
+ *
+ * \return a new ref to be managed by the caller. Warning this ref can be equal to \a this if input slice is exactly equal to the whole cells in the same order.
*
* \sa MEDCouplingMesh::buildPart
*/
-MEDCouplingMesh *MEDCouplingMesh::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception)
+MEDCouplingMesh *MEDCouplingMesh::buildPartRange(mcIdType beginCellIds, mcIdType endCellIds, mcIdType stepCellIds) const
{
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds);
- return buildPart(cellIds->begin(),cellIds->end());
+ if(beginCellIds==0 && endCellIds==getNumberOfCells() && stepCellIds==1)
+ {
+ MEDCouplingMesh *ret(const_cast<MEDCouplingMesh *>(this));
+ ret->incrRef();
+ return ret;
+ }
+ else
+ {
+ MCAuto<DataArrayIdType> cellIds=DataArrayIdType::Range(beginCellIds,endCellIds,stepCellIds);
+ return buildPart(cellIds->begin(),cellIds->end());
+ }
}
/*!
*
* \sa MEDCouplingMesh::buildPartAndReduceNodes
*/
-MEDCouplingMesh *MEDCouplingMesh::buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const throw(INTERP_KERNEL::Exception)
+MEDCouplingMesh *MEDCouplingMesh::buildPartRangeAndReduceNodes(mcIdType beginCellIds, mcIdType endCellIds, mcIdType stepCellIds, mcIdType& beginOut, mcIdType& endOut, mcIdType& stepOut, DataArrayIdType*& arr) const
{
- MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds);
+ MCAuto<DataArrayIdType> cellIds=DataArrayIdType::Range(beginCellIds,endCellIds,stepCellIds);
return buildPartAndReduceNodes(cellIds->begin(),cellIds->end(),arr);
}
*/
MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const
{
- MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
+ MCAuto<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
ret->setMesh(this);
ret->fillFromAnalytic(nbOfComp,func);
ret->synchronizeTimeWithSupport();
* This method copyies all tiny strings from other (name and components name).
* @throw if other and this have not same mesh type.
*/
-void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
+void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
{
if(!other)
throw INTERP_KERNEL::Exception("MEDCouplingMesh::copyTinyStringsFrom : input mesh is null !");
* This method copies all attributes that are \b NOT arrays in this.
* All tiny attributes not usefully for state of \a this are ignored.
*/
-void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
+void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other)
{
- copyTinyStringsFrom(other);
_time=other->_time;
_iteration=other->_iteration;
_order=other->_order;
+ copyTinyStringsFrom(other);
}
/*!
* Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of
* components, lying on \a this mesh, with contents got by applying a specified
* function to coordinates of field location points (defined by the given field type).
- * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell
+ * For example, if \a t == MEDCoupling::ON_CELLS, the function is applied to cell
* barycenters.<br>
* For more info on supported expressions that can be used in the function, see \ref
* MEDCouplingArrayApplyFuncExpr. The function can include arbitrary named variables
* \throw If the nodal connectivity of cells is not defined.
* \throw If computing \a func fails.
*
+ * \if ENABLE_EXAMPLES
* \ref cpp_mcmesh_fillFromAnalytic "Here is a C++ example".<br>
* \ref py_mcmesh_fillFromAnalytic "Here is a Python example".
+ * \endif
*/
-MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const
+MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const
{
- MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
+ MCAuto<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
ret->setMesh(this);
ret->fillFromAnalytic(nbOfComp,func);
ret->synchronizeTimeWithSupport();
* Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of
* components, lying on \a this mesh, with contents got by applying a specified
* function to coordinates of field location points (defined by the given field type).
- * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell
+ * For example, if \a t == MEDCoupling::ON_CELLS, the function is applied to cell
* barycenters. This method differs from
- * \ref MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const "fillFromAnalytic()"
+ * \ref MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const "fillFromAnalytic()"
* by the way how variable
* names, used in the function, are associated with components of coordinates of field
* location points; here, a variable name corresponding to a component is retrieved from
* \throw If the nodal connectivity of cells is not defined.
* \throw If computing \a func fails.
*
+ * \if ENABLE_EXAMPLES
* \ref cpp_mcmesh_fillFromAnalytic2 "Here is a C++ example".<br>
* \ref py_mcmesh_fillFromAnalytic2 "Here is a Python example".
+ * \endif
*/
-MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const char *func) const
+MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalyticCompo(TypeOfField t, int nbOfComp, const std::string& func) const
{
- MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
+ MCAuto<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
ret->setMesh(this);
- ret->fillFromAnalytic2(nbOfComp,func);
+ ret->fillFromAnalyticCompo(nbOfComp,func);
ret->synchronizeTimeWithSupport();
return ret.retn();
}
* Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of
* components, lying on \a this mesh, with contents got by applying a specified
* function to coordinates of field location points (defined by the given field type).
- * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell
+ * For example, if \a t == MEDCoupling::ON_CELLS, the function is applied to cell
* barycenters. This method differs from \ref \ref mcmesh_fillFromAnalytic
* "fillFromAnalytic()" by the way how variable
* names, used in the function, are associated with components of coordinates of field
* \throw If the nodal connectivity of cells is not defined.
* \throw If computing \a func fails.
*
+ * \if ENABLE_EXAMPLES
* \ref cpp_mcmesh_fillFromAnalytic3 "Here is a C++ example".<br>
* \ref py_mcmesh_fillFromAnalytic3 "Here is a Python example".
+ * \endif
*/
-MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
+MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalyticNamedCompo(TypeOfField t, int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) const
{
- MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
+ MCAuto<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME);
ret->setMesh(this);
- ret->fillFromAnalytic3(nbOfComp,varsOrder,func);
+ ret->fillFromAnalyticNamedCompo(nbOfComp,varsOrder,func);
ret->synchronizeTimeWithSupport();
return ret.retn();
}
* is no more needed.
* \throw If the meshes are of different mesh type.
*/
-MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) throw(INTERP_KERNEL::Exception)
+MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2)
{
if(!mesh1)
throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : first parameter is an empty mesh !");
* \throw If \a meshes[ *i* ]->getMeshDimension() < 0.
* \throw If the \a meshes are of different dimension (getMeshDimension()).
*/
-MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(std::vector<const MEDCouplingMesh *>& meshes) throw(INTERP_KERNEL::Exception)
+MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(std::vector<const MEDCouplingMesh *>& meshes)
{
- std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms1(meshes.size());
+ std::vector< MCAuto<MEDCouplingUMesh> > ms1(meshes.size());
std::vector< const MEDCouplingUMesh * > ms2(meshes.size());
for(std::size_t i=0;i<meshes.size();i++)
{
*
* \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
*/
-INTERP_KERNEL::NormalizedCellType MEDCouplingMesh::GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
+INTERP_KERNEL::NormalizedCellType MEDCouplingMesh::GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type)
{
const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
return cm.getCorrespondingPolyType();
* \throw if type is dynamic as \c INTERP_KERNEL::NORM_POLYHED , \c INTERP_KERNEL::NORM_POLYGON , \c INTERP_KERNEL::NORM_QPOLYG
* \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
*/
-int MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
+mcIdType MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type)
{
const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
if(cm.isDynamic())
throw INTERP_KERNEL::Exception("MEDCouplingMesh::GetNumberOfNodesOfGeometricType : the input geometric type is dynamic ! Impossible to return a fixed number of nodes constituting it !");
- return (int) cm.getNumberOfNodes();
+ return ToIdType( cm.getNumberOfNodes());
}
/*!
*
* \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
*/
-bool MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
+bool MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type)
{
const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
return !cm.isDynamic();
}
-bool MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
+bool MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type)
{
const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
return !cm.isQuadratic();
*
* \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
*/
-int MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
+int MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type)
{
const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
return (int) cm.getDimension();
*
* \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
*/
-const char *MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
+const char *MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type)
{
const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
return cm.getRepr();
}
-/*!
- * Finds cells in contact with a ball (i.e. a point with precision).
- * \warning This method is suitable if the caller intends to evaluate only one
- * point, for more points getCellsContainingPoints() is recommended as it is
- * faster.
- * \param [in] pos - array of coordinates of the ball central point.
- * \param [in] eps - ball radius.
- * \param [in,out] elts - vector returning ids of the found cells. It is cleared
- * before inserting ids.
- *
- * \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".<br>
- * \ref py_mcumesh_getCellsContainingPoint "Here is a Python example".
- */
-void MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
-{
- int ret=getCellContainingPoint(pos,eps);
- elts.push_back(ret);
-}
-
/*!
* Finds cells in contact with several balls (i.e. points with precision).
* This method is an extension of getCellContainingPoint() and
* Number of cells in contact with the *i*-th point is
* \a eltsIndex[ *i*+1 ] - \a eltsIndex[ *i* ].
*
+ * \if ENABLE_EXAMPLES
* \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".<br>
* \ref py_mcumesh_getCellsContainingPoints "Here is a Python example".
+ * \endif
*/
-void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const
+void MEDCouplingMesh::getCellsContainingPoints(const double *pos, mcIdType nbOfPoints, double eps, MCAuto<DataArrayIdType>& elts, MCAuto<DataArrayIdType>& eltsIndex) const
{
- eltsIndex=DataArrayInt::New(); elts=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1);
- int *eltsIndexPtr(eltsIndex->getPointer());
+ eltsIndex=DataArrayIdType::New(); elts=DataArrayIdType::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1);
+ mcIdType *eltsIndexPtr(eltsIndex->getPointer());
int spaceDim(getSpaceDimension());
const double *work(pos);
- for(int i=0;i<nbOfPoints;i++,work+=spaceDim)
+ for(mcIdType i=0;i<nbOfPoints;i++,work+=spaceDim)
{
- int ret=getCellContainingPoint(work,eps);
- if(ret>=0)
- {
- elts->pushBackSilent(ret);
- eltsIndexPtr[i+1]=eltsIndexPtr[i]+1;
- }
- else
- eltsIndexPtr[i+1]=eltsIndexPtr[i];
+ std::vector<mcIdType> ret;
+ getCellsContainingPoint(work,eps,ret);
+ elts->insertAtTheEnd(ret.begin(),ret.end());
+ eltsIndexPtr[i+1]=elts->getNumberOfTuples();
}
}
+/*!
+ * Behaves like MEDCouplingMesh::getCellsContainingPoints for cells in \a this that are linear.
+ * For quadratic cells in \a this, this method behaves by just considering linear part of cells.
+ * This method is here only for backward compatibility (interpolation GaussPoints to GaussPoints).
+ *
+ * \sa MEDCouplingMesh::getCellsContainingPoints, MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss
+ */
+void MEDCouplingMesh::getCellsContainingPointsLinearPartOnlyOnNonDynType(const double *pos, mcIdType nbOfPoints, double eps, MCAuto<DataArrayIdType>& elts, MCAuto<DataArrayIdType>& eltsIndex) const
+{
+ this->getCellsContainingPoints(pos,nbOfPoints,eps,elts,eltsIndex);
+}
+
+/*!
+ * Method computing center of mass of whole mesh (\a this)
+ * \return DataArrayDouble * - a new instance of DataArrayDouble with one tuple of n components where n is space dimension
+ */
+MCAuto<DataArrayDouble> MEDCouplingMesh::computeMeshCenterOfMass() const
+{
+ MCAuto<DataArrayDouble> cellCenters( this->computeCellCenterOfMass() );
+ MCAuto<MEDCouplingFieldDouble> vol( this->getMeasureField(true) );
+ MCAuto<DataArrayDouble> volXCenter( DataArrayDouble::Multiply(cellCenters,vol->getArray()) );
+ MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(1, this->getSpaceDimension());
+ volXCenter->accumulate( ret->getPointer() );
+ double volOfMesh(vol->accumulate(0));
+ ret->applyLin(1.0/volOfMesh,0.0);
+ return ret;
+}
+
/*!
* Writes \a this mesh into a VTK format file named as specified.
- * \param [in] fileName - the name of the file to write in.
+ * \param [in] fileName - the name of the file to write in. If the extension is OK the fileName will be used directly.
+ * If extension is invalid or no extension the right extension will be appended.
+ * \return - the real fileName
* \throw If \a fileName is not a writable file.
+ * \sa getVTKFileNameOf
*/
-void MEDCouplingMesh::writeVTK(const char *fileName, bool isBinary) const throw(INTERP_KERNEL::Exception)
+std::string MEDCouplingMesh::writeVTK(const std::string& fileName, bool isBinary) const
{
+ std::string ret(getVTKFileNameOf(fileName));
+ //
std::string cda,pda;
- MEDCouplingAutoRefCountObjectPtr<DataArrayByte> byteArr;
+ MCAuto<DataArrayByte> byteArr;
if(isBinary)
{ byteArr=DataArrayByte::New(); byteArr->alloc(0,1); }
- writeVTKAdvanced(fileName,cda,pda,byteArr);
+ writeVTKAdvanced(ret,cda,pda,byteArr);
+ return ret;
}
-void MEDCouplingMesh::writeVTKAdvanced(const char *fileName, const std::string& cda, const std::string& pda, DataArrayByte *byteData) const throw(INTERP_KERNEL::Exception)
+/*!
+ * This method takes in input a file name \a fileName and considering the VTK extension of \a this (depending on the type of \a this)
+ * returns a right file name. If the input \a fileName has a valid extension the returned string is equal to \a fileName.
+ *
+ * \sa getVTKFileExtension
+ */
+std::string MEDCouplingMesh::getVTKFileNameOf(const std::string& fileName) const
{
- std::ofstream ofs(fileName);
+ std::string ret;
+ std::string part0,part1;
+ SplitExtension(fileName,part0,part1);
+ std::string ext("."); ext+=getVTKFileExtension();
+ if(part1==ext)
+ ret=fileName;
+ else
+ ret=fileName+ext;
+ return ret;
+}
+
+/// @cond INTERNAL
+void MEDCouplingMesh::writeVTKAdvanced(const std::string& fileName, const std::string& cda, const std::string& pda, DataArrayByte *byteData) const
+{
+ std::ofstream ofs(fileName.c_str());
ofs << "<VTKFile type=\"" << getVTKDataSetType() << "\" version=\"0.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n";
writeVTKLL(ofs,cda,pda,byteData);
if(byteData)
{
ofs << "<AppendedData encoding=\"raw\">\n_1234";
ofs << std::flush; ofs.close();
- std::ofstream ofs2(fileName,std::ios_base::binary | std::ios_base::app);
+ std::ofstream ofs2(fileName.c_str(),std::ios_base::binary | std::ios_base::app);
ofs2.write(byteData->begin(),byteData->getNbOfElems()); ofs2 << std::flush; ofs2.close();
- std::ofstream ofs3(fileName,std::ios_base::app); ofs3 << "\n</AppendedData>\n</VTKFile>\n"; ofs3.close();
+ std::ofstream ofs3(fileName.c_str(),std::ios_base::app); ofs3 << "\n</AppendedData>\n</VTKFile>\n"; ofs3.close();
}
else
{
ofs.close();
}
}
+
+void MEDCouplingMesh::SplitExtension(const std::string& fileName, std::string& baseName, std::string& extension)
+{
+ std::size_t pos(fileName.find_last_of('.'));
+ if(pos==std::string::npos)
+ {
+ baseName=fileName;
+ extension.clear();
+ return ;
+ }
+ baseName=fileName.substr(0,pos);
+ extension=fileName.substr(pos);
+}
+/// @endcond