-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D
+// Copyright (C) 2007-2016 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
// Author : Anthony Geay (CEA/DEN)
#include "MEDCouplingCMesh.hxx"
-#include "MEDCouplingUMesh.hxx"
#include "MEDCouplingMemArray.hxx"
#include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingCurveLinearMesh.hxx"
+
+#include "InterpKernelAutoPtr.hxx"
#include <functional>
#include <algorithm>
#include <sstream>
#include <numeric>
-using namespace ParaMEDMEM;
+using namespace MEDCoupling;
MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0)
{
}
-MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingMesh(other)
+MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy)
{
if(deepCopy)
{
if(other._x_array)
- _x_array=other._x_array->deepCpy();
+ _x_array=other._x_array->deepCopy();
else
_x_array=0;
if(other._y_array)
- _y_array=other._y_array->deepCpy();
+ _y_array=other._y_array->deepCopy();
else
_y_array=0;
if(other._z_array)
- _z_array=other._z_array->deepCpy();
+ _z_array=other._z_array->deepCopy();
else
_z_array=0;
}
return new MEDCouplingCMesh;
}
-MEDCouplingCMesh *MEDCouplingCMesh::New(const char *meshName)
+MEDCouplingCMesh *MEDCouplingCMesh::New(const std::string& meshName)
{
- MEDCouplingCMesh *ret=new MEDCouplingCMesh;
+ MEDCouplingCMesh *ret(new MEDCouplingCMesh);
ret->setName(meshName);
return ret;
}
-MEDCouplingMesh *MEDCouplingCMesh::deepCpy() const
+MEDCouplingCMesh *MEDCouplingCMesh::deepCopy() const
{
return clone(true);
}
return new MEDCouplingCMesh(*this,recDeepCpy);
}
+const DataArrayDouble *MEDCouplingCMesh::getDirectAccessOfCoordsArrIfInStructure() const
+{
+ throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getDirectAccessOfCoordsArrIfInStructure : MEDCouplingCMesh does not aggregate array of coordinates !");
+}
+
+MEDCouplingCurveLinearMesh *MEDCouplingCMesh::buildCurveLinear() const
+{
+ checkConsistencyLight();
+ int dim(getSpaceDimension());
+ MCAuto<MEDCouplingCurveLinearMesh> ret(MEDCouplingCurveLinearMesh::New());
+ ret->MEDCouplingStructuredMesh::operator=(*this);
+ INTERP_KERNEL::AutoPtr<int> ngs(new int[dim]);
+ getNodeGridStructure(ngs);
+ ret->setNodeGridStructure(ngs,ngs+dim);
+ MCAuto<DataArrayDouble> coo(getCoordinatesAndOwner());
+ ret->setCoords(coo);
+ return ret.retn();
+}
+
void MEDCouplingCMesh::updateTime() const
{
if(_x_array)
updateTimeWith(*_z_array);
}
+std::size_t MEDCouplingCMesh::getHeapMemorySizeWithoutChildren() const
+{
+ return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
+}
+
+std::vector<const BigMemoryObject *> MEDCouplingCMesh::getDirectChildrenWithNull() const
+{
+ std::vector<const BigMemoryObject *> ret;
+ ret.push_back(_x_array);
+ ret.push_back(_y_array);
+ ret.push_back(_z_array);
+ return ret;
+}
+
/*!
* This method copyies all tiny strings from other (name and components name).
* @throw if other and this have not same mesh type.
*/
-void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
-{
- const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
+void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
+{
+ MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
+ const MEDCouplingCMesh *otherC(dynamic_cast<const MEDCouplingCMesh *>(other));
if(!otherC)
throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !");
- MEDCouplingMesh::copyTinyStringsFrom(other);
if(_x_array && otherC->_x_array)
_x_array->copyStringInfoFrom(*otherC->_x_array);
if(_y_array && otherC->_y_array)
_z_array->copyStringInfoFrom(*otherC->_z_array);
}
-bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
+bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
{
if(!other)
throw INTERP_KERNEL::Exception("MEDCouplingCMesh::isEqualIfNotWhy : input other pointer is null !");
reason="mesh given in input is not castable in MEDCouplingCMesh !";
return false;
}
- if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason))
+ if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
return false;
const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
}
void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
- DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
+ DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
{
if(!isEqualWithoutConsideringStr(other,prec))
throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalWith : Meshes are not the same !");
}
/*!
- * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCMesh instance too).
- * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCMesh, 'this' and 'other' are the same !
+ * Nothing is done here (except to check that the other is a MEDCoupling::MEDCouplingCMesh instance too).
+ * The user intend that the nodes are the same, so by construction of MEDCoupling::MEDCouplingCMesh, \a this and \a other are the same !
*/
void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
- DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
+ DataArrayInt *&cellCor) const
{
- const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
- if(!otherC)
- throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : other is NOT a cartesian mesh ! Impossible to check equivalence !");
+ if(!isEqualWithoutConsideringStr(other,prec))
+ throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
}
-void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
+void MEDCouplingCMesh::checkConsistencyLight() const
{
const char msg0[]="Invalid ";
const char msg1[]=" array ! Must contain more than 1 element.";
const char msg2[]=" array ! Must be with only one component.";
+ getSpaceDimension();// here to check that no holes in arrays !
if(_x_array)
{
if(_x_array->getNbOfElems()<2)
std::ostringstream os; os << msg0 << 'Y' << msg2;
throw INTERP_KERNEL::Exception(os.str().c_str());
}
-
}
if(_z_array)
{
}
}
-void MEDCouplingCMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingCMesh::checkConsistency(double eps) const
{
- checkCoherency();
+ checkConsistencyLight();
if(_x_array)
_x_array->checkMonotonic(true, eps);
if(_y_array)
_z_array->checkMonotonic(true, eps);
}
-void MEDCouplingCMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingCMesh::getNodeGridStructure(int *res) const
{
- checkCoherency1(eps);
-}
-
-int MEDCouplingCMesh::getNumberOfCells() const
-{
- int ret=1;
- if(_x_array)
- ret*=_x_array->getNbOfElems()-1;
- if(_y_array)
- ret*=_y_array->getNbOfElems()-1;
- if(_z_array)
- ret*=_z_array->getNbOfElems()-1;
- return ret;
+ std::vector<int> ret(getNodeGridStructure());
+ std::copy(ret.begin(),ret.end(),res);
}
-int MEDCouplingCMesh::getNumberOfNodes() const
+std::vector<int> MEDCouplingCMesh::getNodeGridStructure() const
{
- int ret=1;
+ static const char MSG[]="MEDCouplingCMesh::getNodeGridStructure : mesh is invalid ! null vectors (X, Y or Z) must be put contiguously at the end !";
+ std::vector<int> ret;
+ bool isOK(true);
if(_x_array)
- ret*=_x_array->getNbOfElems();
- if(_y_array)
- ret*=_y_array->getNbOfElems();
- if(_z_array)
- ret*=_z_array->getNbOfElems();
- return ret;
-}
-
-void MEDCouplingCMesh::getSplitCellValues(int *res) const
-{
- int spaceDim=getSpaceDimension();
- for(int l=0;l<spaceDim;l++)
- {
- int val=1;
- for(int p=0;p<spaceDim-l-1;p++)
- val*=getCoordsAt(p)->getNbOfElems()-1;
- res[spaceDim-l-1]=val;
- }
-}
-
-void MEDCouplingCMesh::getSplitNodeValues(int *res) const
-{
- int spaceDim=getSpaceDimension();
- for(int l=0;l<spaceDim;l++)
{
- int val=1;
- for(int p=0;p<spaceDim-l-1;p++)
- val*=getCoordsAt(p)->getNbOfElems();
- res[spaceDim-l-1]=val;
+ if(!_x_array->isAllocated() || _x_array->getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : X array exits but it is not allocated or with nb of components equal to one !");
+ ret.push_back(_x_array->getNumberOfTuples());
}
-}
-
-int MEDCouplingCMesh::getCellIdFromPos(int i, int j, int k) const
-{
- int tmp[3]={i,j,k};
- int tmp2[3];
- int spaceDim=getSpaceDimension();
- getSplitCellValues(tmp2);
- std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies<int>());
- return std::accumulate(tmp,tmp+spaceDim,0);
-}
-
-int MEDCouplingCMesh::getNodeIdFromPos(int i, int j, int k) const
-{
- int tmp[3]={i,j,k};
- int tmp2[3];
- int spaceDim=getSpaceDimension();
- getSplitNodeValues(tmp2);
- std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies<int>());
- return std::accumulate(tmp,tmp+spaceDim,0);
-}
-
-void MEDCouplingCMesh::GetPosFromId(int nodeId, int spaceDim, const int *split, int *res)
-{
- int work=nodeId;
- for(int i=spaceDim-1;i>=0;i--)
+ else
+ isOK=false;
+ if(_y_array)
{
- int pos=work/split[i];
- work=work%split[i];
- res[i]=pos;
+ if(!_y_array->isAllocated() || _y_array->getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Y array exits but it is not allocated or with nb of components equal to one !");
+ if(!isOK)
+ throw INTERP_KERNEL::Exception(MSG);
+ ret.push_back(_y_array->getNumberOfTuples());
}
-}
-
-int MEDCouplingCMesh::getSpaceDimension() const
-{
- int ret=0;
- if(_x_array)
- ret++;
- if(_y_array)
- ret++;
+ else
+ isOK=false;
if(_z_array)
- ret++;
- return ret;
-}
-
-int MEDCouplingCMesh::getMeshDimension() const
-{
- return getSpaceDimension();
-}
-
-INTERP_KERNEL::NormalizedCellType MEDCouplingCMesh::getTypeOfCell(int cellId) const
-{
- switch(getMeshDimension())
{
- case 3:
- return INTERP_KERNEL::NORM_HEXA8;
- case 2:
- return INTERP_KERNEL::NORM_QUAD4;
- case 1:
- return INTERP_KERNEL::NORM_SEG2;
- default:
- throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !");
+ if(!_z_array->isAllocated() || _z_array->getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Z array exits but it is not allocated or with nb of components equal to one !");
+ if(!isOK)
+ throw INTERP_KERNEL::Exception(MSG);
+ ret.push_back(_z_array->getNumberOfTuples());
}
+ return ret;
}
-std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingCMesh::getAllGeoTypes() const
+MEDCouplingStructuredMesh *MEDCouplingCMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
{
- INTERP_KERNEL::NormalizedCellType ret;
- switch(getMeshDimension())
+ checkConsistencyLight();
+ int dim(getSpaceDimension());
+ if(dim!=(int)cellPart.size())
{
- case 3:
- ret=INTERP_KERNEL::NORM_HEXA8;
- break;
- case 2:
- ret=INTERP_KERNEL::NORM_QUAD4;
- break;
- case 1:
- ret=INTERP_KERNEL::NORM_SEG2;
- break;
- default:
- throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getAllGeoTypes !");
+ std::ostringstream oss; oss << "MEDCouplingCMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
}
- std::set<INTERP_KERNEL::NormalizedCellType> ret2;
- ret2.insert(ret);
- return ret2;
-}
-
-int MEDCouplingCMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
-{
- int ret=getNumberOfCells();
- int dim=getMeshDimension();
- switch(type)
+ MCAuto<MEDCouplingCMesh> ret(dynamic_cast<MEDCouplingCMesh *>(deepCopy()));
+ for(int i=0;i<dim;i++)
{
- case INTERP_KERNEL::NORM_HEXA8:
- if(dim==3)
- return ret;
- case INTERP_KERNEL::NORM_QUAD4:
- if(dim==2)
- return ret;
- case INTERP_KERNEL::NORM_SEG2:
- if(dim==1)
- return ret;
- default:
- throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !");
+ MCAuto<DataArrayDouble> tmp(ret->getCoordsAt(i)->selectByTupleIdSafeSlice(cellPart[i].first,cellPart[i].second+1,1));
+ ret->setCoordsAt(i,tmp);
}
- return 0;
+ return ret.retn();
}
-void MEDCouplingCMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
+/*!
+ * Return the space dimension of \a this. It only considers the arrays along X, Y and Z to deduce that.
+ * This method throws exceptions if the not null arrays defining this are not contiguously at the end. For example X!=0,Y==0,Z!=0 will throw.
+ */
+int MEDCouplingCMesh::getSpaceDimension() const
{
- int spaceDim=getSpaceDimension();
- int tmpCell[3],tmpNode[3];
- getSplitCellValues(tmpCell);
- getSplitNodeValues(tmpNode);
- int tmp2[3];
- GetPosFromId(cellId,spaceDim,tmpCell,tmp2);
- switch(spaceDim)
- {
- case 1:
- conn.push_back(tmp2[0]); conn.push_back(tmp2[0]+1);
- break;
- case 2:
- conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1);
- conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]+1); conn.push_back((tmp2[1]+1)*(tmpCell[1]+1)+tmp2[0]);
- break;
- case 3:
- conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]);
- conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+tmp2[2]*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]);
- conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpCell[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]);
- conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1+(tmp2[2]+1)*tmpNode[2]); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]);
- break;
- default:
- throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeIdsOfCell : big problem spacedim must be in 1,2 or 3 !");
- };
+ return (int)getNodeGridStructure().size();
}
-void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
{
int tmp[3];
int spaceDim=getSpaceDimension();
double tt=getTime(tmpp1,tmpp2);
ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
- ret << "Mesh and SpaceDimension dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n";
+ ret << "Space dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n";
if(_x_array)
{
ret << "X Array :\n";
return simpleRepr();
}
-const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL::Exception)
+/*!
+ * Returns a DataArrayDouble holding positions of nodes along a given axis.
+ * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage.
+ * \param [in] i - an index of axis, a value from [0,1,2].
+ * \return const DataArrayDouble * - a pointer to the data array of node coordinates
+ * referred by \a this mesh.
+ * \throw If \a i is not one of [0,1,2].
+ *
+ * \if ENABLE_EXAMPLES
+ * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br>
+ * \ref py_mccmesh_getCoordsAt "Here is a Python example".
+ * \endif
+ */
+const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const
{
switch(i)
- {
+ {
case 0:
return _x_array;
case 1:
return _z_array;
default:
throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
- }
+ }
}
-DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Exception)
+/*!
+ * Returns a DataArrayDouble holding positions of nodes along a given axis.
+ * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage.
+ * \param [in] i - an index of axis, a value from [0,1,2].
+ * \return const DataArrayDouble * - a pointer to the data array of node coordinates
+ * referred by \a this mesh.
+ * \throw If \a i is not one of [0,1,2].
+ *
+ * \if ENABLE_EXAMPLES
+ * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br>
+ * \ref py_mccmesh_getCoordsAt "Here is a Python example".
+ * \endif
+ */
+DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i)
{
switch(i)
- {
+ {
case 0:
return _x_array;
case 1:
return _z_array;
default:
throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
- }
+ }
}
-void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception)
+/*!
+ * Sets node coordinates along a given axis. For more info on Cartesian meshes, see
+ * \ref MEDCouplingCMeshPage.
+ * \param [in] i - an index of axis, a value in range [0,1,2].
+ * \param [in] arr - DataArrayDouble holding positions of nodes along the i-th
+ * axis. It must be an array of one component.
+ * \throw If \a arr->getNumberOfComponents() != 1.
+ * \throw If \a i is not one of [0,1,2].
+ *
+ * \if ENABLE_EXAMPLES
+ * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br>
+ * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example".
+ * \endif
+ */
+void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr)
{
if(arr)
arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt");
}
}
+/*!
+ * Sets node coordinates along some of the tree axes. This method updates all the
+ * three node coordinates arrays at once. For more info on Cartesian meshes, see
+ * \ref MEDCouplingCMeshPage.
+ * \param [in] coordsX - DataArrayDouble holding positions of nodes along the X
+ * axis. It must be an array of one component or \c NULL.
+ * \param [in] coordsY - DataArrayDouble holding positions of nodes along the Y
+ * axis. It must be an array of one component or \c NULL.
+ * \param [in] coordsZ - DataArrayDouble holding positions of nodes along the Z
+ * axis. It must be an array of one component or \c NULL.
+ * \throw If \a coords*->getNumberOfComponents() != 1.
+ *
+ * \if ENABLE_EXAMPLES
+ * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br>
+ * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example".
+ * \endif
+ */
void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ)
{
if(coordsX)
declareAsNew();
}
-/*!
- * See MEDCouplingUMesh::getDistributionOfTypes for more information
- */
-std::vector<int> MEDCouplingCMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
-{
- //only one type of cell
- std::vector<int> ret(3);
- ret[0]=getTypeOfCell(0);
- ret[1]=getNumberOfCells();
- ret[2]=0; //ret[3*k+2]==0 because it has no sense here
- return ret;
-}
-
-/*!
- * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information
- */
-DataArrayInt *MEDCouplingCMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
-{
- if(code.empty())
- throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code is empty, should not !");
- std::size_t sz=code.size();
- if(sz!=3)
- throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code should be of size 3 exactly !");
-
- int nbCells=getNumberOfCellsWithType((INTERP_KERNEL::NormalizedCellType)code[0]);
- if(code[2]==-1)
- {
- if(code[1]==nbCells)
- return 0;
- else
- throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : number of cells mismatch !");
- }
- else
- {
- if(code[2]<-1)
- throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]<-1 mismatch !");
- if(code[2]>=(int)idsPerType.size())
- throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkTypeConsistencyAndContig : code[2]>size idsPerType !");
- return idsPerType[code[2]]->deepCpy();
- }
-}
-
-/*!
- * See MEDCouplingUMesh::splitProfilePerType for more information
- */
-void MEDCouplingCMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
-{
- int nbCells=getNumberOfCells();
- code.resize(3);
- code[0]=(int)getTypeOfCell(0);
- code[1]=nbCells;
- code[2]=0;
- idsInPflPerType.push_back(profile->deepCpy());
- idsPerType.push_back(profile->deepCpy());
-}
-
-MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
-{
- int spaceDim=getSpaceDimension();
- MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),spaceDim);
- DataArrayDouble *coords=getCoordinatesAndOwner();
- ret->setCoords(coords);
- coords->decrRef();
- switch(spaceDim)
- {
- case 1:
- fill1DUnstructuredMesh(ret);
- break;
- case 2:
- fill2DUnstructuredMesh(ret);
- break;
- case 3:
- fill3DUnstructuredMesh(ret);
- break;
- default:
- throw INTERP_KERNEL::Exception("MEDCouplingCMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !");
- };
- return ret;
-}
-
-MEDCouplingMesh *MEDCouplingCMesh::buildPart(const int *start, const int *end) const
-{
- MEDCouplingUMesh *um=buildUnstructured();
- MEDCouplingMesh *ret=um->buildPart(start,end);
- um->decrRef();
- return ret;
-}
-
-MEDCouplingMesh *MEDCouplingCMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const
-{
- MEDCouplingUMesh *um=buildUnstructured();
- MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr);
- um->decrRef();
- return ret;
-}
-
-DataArrayInt *MEDCouplingCMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
-{
- throw INTERP_KERNEL::Exception("MEDCouplingCMesh::simplexize : not available for Cartesian mesh !");
-}
-
void MEDCouplingCMesh::getBoundingBox(double *bbox) const
{
int dim=getSpaceDimension();
}
}
+/*!
+ * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
+ * mesh.<br>
+ * For 1D cells, the returned field contains lengths.<br>
+ * For 2D cells, the returned field contains areas.<br>
+ * For 3D cells, the returned field contains volumes.
+ * \param [in] isAbs - a not used parameter.
+ * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
+ * and one time . The caller is to delete this field using decrRef() as it is no
+ * more needed.
+ */
MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const
{
std::string name="MeasureOfMesh_";
name+=getName();
int nbelem=getNumberOfCells();
- MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS);
- field->setName(name.c_str());
+ MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
+ field->setName(name);
DataArrayDouble* array=DataArrayDouble::New();
array->alloc(nbelem,1);
double *area_vol=array->getPointer();
field->setArray(array) ;
array->decrRef();
field->setMesh(const_cast<MEDCouplingCMesh *>(this));
+ field->synchronizeTimeWithMesh();
int tmp[3];
getSplitCellValues(tmp);
int dim=getSpaceDimension();
//return 0;
}
-MEDCouplingFieldDouble *MEDCouplingCMesh::buildOrthogonalField() const
-{
- if(getMeshDimension()!=2)
- throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !");
- MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
- DataArrayDouble *array=DataArrayDouble::New();
- int nbOfCells=getNumberOfCells();
- array->alloc(nbOfCells,3);
- double *vals=array->getPointer();
- for(int i=0;i<nbOfCells;i++)
- { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; }
- ret->setArray(array);
- array->decrRef();
- ret->setMesh(this);
- return ret;
-}
-
int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const
{
int dim=getSpaceDimension();
void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle)
{
- throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to StructuredMesh to apply it !");
+ throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to untructured mesh to apply it !");
}
+/*!
+ * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
+ * component of the \a vector to all node coordinates of a corresponding axis.
+ * \param [in] vector - the translation vector whose size must be not less than \a
+ * this->getSpaceDimension().
+ */
void MEDCouplingCMesh::translate(const double *vector)
{
if(_x_array)
_z_array->getPointer(),std::bind2nd(std::plus<double>(),vector[2]));
}
+/*!
+ * Applies scaling transformation to all nodes of \a this mesh.
+ * \param [in] point - coordinates of a scaling center. This array is to be of
+ * size \a this->getSpaceDimension() at least.
+ * \param [in] factor - a scale factor.
+ */
void MEDCouplingCMesh::scale(const double *point, double factor)
{
for(int i=0;i<3;i++)
return 0;
}
+/*!
+ * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
+ * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
+ * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
+ * components. The caller is to delete this array using decrRef() as it is
+ * no more needed.
+ */
DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const
{
- DataArrayDouble *ret=DataArrayDouble::New();
- int spaceDim=getSpaceDimension();
- int nbNodes=getNumberOfNodes();
+ MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
+ int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
ret->alloc(nbNodes,spaceDim);
- double *pt=ret->getPointer();
+ double *pt(ret->getPointer());
int tmp[3];
getSplitNodeValues(tmp);
const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
for(int j=0;j<spaceDim;j++)
{
tabsPtr[j]=tabs[j]->getConstPointer();
- ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0).c_str());
+ ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
}
int tmp2[3];
for(int i=0;i<nbNodes;i++)
for(int j=0;j<spaceDim;j++)
pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
}
- return ret;
+ return ret.retn();
}
-DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const
+/*!
+ * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
+ * computed by averaging coordinates of cell nodes.
+ * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
+ * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
+ * components. The caller is to delete this array using decrRef() as it is
+ * no more needed.
+ */
+DataArrayDouble *MEDCouplingCMesh::computeCellCenterOfMass() const
{
DataArrayDouble *ret=DataArrayDouble::New();
int spaceDim=getSpaceDimension();
for(int j=0;j<spaceDim;j++)
{
int sz=tabs[j]->getNbOfElems()-1;
- ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0).c_str());
+ ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
const double *srcPtr=tabs[j]->getConstPointer();
tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz);
std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus<double>());
return ret;
}
-void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
-{
- throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !");
-}
-
-void MEDCouplingCMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const
+DataArrayDouble *MEDCouplingCMesh::computeIsoBarycenterOfNodesPerCell() const
{
- const DataArrayDouble *c=getCoordsAt(0);
- int nbOfCells=c->getNbOfElems()-1;
- DataArrayInt *connI=DataArrayInt::New();
- connI->alloc(nbOfCells+1,1);
- int *ci=connI->getPointer();
- DataArrayInt *conn=DataArrayInt::New();
- conn->alloc(3*nbOfCells,1);
- ci[0]=0;
- int *cp=conn->getPointer();
- for(int i=0;i<nbOfCells;i++)
- {
- cp[3*i]=(int)INTERP_KERNEL::NORM_SEG2;
- cp[3*i+1]=i;
- cp[3*i+2]=i+1;
- ci[i+1]=3*(i+1);
- }
- m->setConnectivity(conn,connI,true);
- conn->decrRef();
- connI->decrRef();
-}
-
-void MEDCouplingCMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const
-{
- const DataArrayDouble *c1=getCoordsAt(0);
- const DataArrayDouble *c2=getCoordsAt(1);
- int n1=c1->getNbOfElems()-1;
- int n2=c2->getNbOfElems()-1;
- DataArrayInt *connI=DataArrayInt::New();
- connI->alloc(n1*n2+1,1);
- int *ci=connI->getPointer();
- DataArrayInt *conn=DataArrayInt::New();
- conn->alloc(5*n1*n2,1);
- ci[0]=0;
- int *cp=conn->getPointer();
- int pos=0;
- for(int j=0;j<n2;j++)
- for(int i=0;i<n1;i++,pos++)
- {
- cp[5*pos]=(int)INTERP_KERNEL::NORM_QUAD4;
- cp[5*pos+1]=i+1+j*(n1+1);
- cp[5*pos+2]=i+j*(n1+1);
- cp[5*pos+3]=i+(j+1)*(n1+1);
- cp[5*pos+4]=i+1+(j+1)*(n1+1);
- ci[pos+1]=5*(pos+1);
- }
- m->setConnectivity(conn,connI,true);
- conn->decrRef();
- connI->decrRef();
+ return MEDCouplingCMesh::computeCellCenterOfMass();
}
-void MEDCouplingCMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const
+void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check)
{
- const DataArrayDouble *c1=getCoordsAt(0);
- const DataArrayDouble *c2=getCoordsAt(1);
- const DataArrayDouble *c3=getCoordsAt(2);
- int n1=c1->getNbOfElems()-1;
- int n2=c2->getNbOfElems()-1;
- int n3=c3->getNbOfElems()-1;
- DataArrayInt *connI=DataArrayInt::New();
- connI->alloc(n1*n2*n3+1,1);
- int *ci=connI->getPointer();
- DataArrayInt *conn=DataArrayInt::New();
- conn->alloc(9*n1*n2*n3,1);
- ci[0]=0;
- int *cp=conn->getPointer();
- int pos=0;
- for(int k=0;k<n3;k++)
- for(int j=0;j<n2;j++)
- for(int i=0;i<n1;i++,pos++)
- {
- cp[9*pos]=(int)INTERP_KERNEL::NORM_HEXA8;
- int tmp=(n1+1)*(n2+1);
- cp[9*pos+1]=i+1+j*(n1+1)+k*tmp;
- cp[9*pos+2]=i+j*(n1+1)+k*tmp;
- cp[9*pos+3]=i+(j+1)*(n1+1)+k*tmp;
- cp[9*pos+4]=i+1+(j+1)*(n1+1)+k*tmp;
- cp[9*pos+5]=i+1+j*(n1+1)+(k+1)*tmp;
- cp[9*pos+6]=i+j*(n1+1)+(k+1)*tmp;
- cp[9*pos+7]=i+(j+1)*(n1+1)+(k+1)*tmp;
- cp[9*pos+8]=i+1+(j+1)*(n1+1)+(k+1)*tmp;
- ci[pos+1]=9*(pos+1);
- }
- m->setConnectivity(conn,connI,true);
- conn->decrRef();
- connI->decrRef();
+ throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !");
}
void MEDCouplingCMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
const std::vector<std::string>& littleStrings)
{
- setName(littleStrings[0].c_str());
- setDescription(littleStrings[1].c_str());
- setTimeUnit(littleStrings[2].c_str());
+ setName(littleStrings[0]);
+ setDescription(littleStrings[1]);
+ setTimeUnit(littleStrings[2]);
DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
const double *data=a2->getConstPointer();
for(int i=0;i<3;i++)
{
(*(thisArr[i]))=DataArrayDouble::New();
(*(thisArr[i]))->alloc(tinyInfo[i],1);
- (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3].c_str());
+ (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3]);
std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer());
data+=tinyInfo[i];
}
setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]);
}
-void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
+void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
+{
+ std::ostringstream extent;
+ DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
+ for(int i=0;i<3;i++)
+ {
+ if(thisArr[i])
+ { extent << "0 " << thisArr[i]->getNumberOfTuples()-1 << " "; }
+ else
+ { extent << "0 0 "; }
+ }
+ ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n";
+ ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
+ ofs << " <PointData>\n" << pointData << std::endl;
+ ofs << " </PointData>\n";
+ ofs << " <CellData>\n" << cellData << std::endl;
+ ofs << " </CellData>\n";
+ ofs << " <Coordinates>\n";
+ for(int i=0;i<3;i++)
+ {
+ if(thisArr[i])
+ thisArr[i]->writeVTK(ofs,8,"Array",byteData);
+ else
+ {
+ MCAuto<DataArrayDouble> coo=DataArrayDouble::New(); coo->alloc(1,1);
+ coo->setIJ(0,0,0.);
+ coo->writeVTK(ofs,8,"Array",byteData);
+ }
+ }
+ ofs << " </Coordinates>\n";
+ ofs << " </Piece>\n";
+ ofs << " </" << getVTKDataSetType() << ">\n";
+}
+
+void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const
+{
+ stream << "MEDCouplingCMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
+ const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
+ std::ostringstream stream2[3];
+ bool isDef[3];
+ int nbOfCells=1,nbOfNodes=1;
+ for(int i=0;i<3;i++)
+ {
+ isDef[i]=thisArr[i]!=0;
+ if(isDef[i])
+ {
+ char tmp='X'+i;
+ stream2[i] << tmp << " positions array ";
+ if(!thisArr[i]->isAllocated())
+ stream2[i] << "set but not allocated.";
+ else
+ {
+ int nbCompo=thisArr[i]->getNumberOfComponents();
+ if(nbCompo==1)
+ {
+ int nbTuples=thisArr[i]->getNumberOfTuples();
+ if(nbTuples<1)
+ { stream2[i] << "set and allocated - WARNING number of elements < 1 !"; nbOfCells=-1; nbOfNodes=-1; }
+ else
+ {
+ stream2[i] << "(length=" << nbTuples << ")" << ": ";
+ thisArr[i]->reprQuickOverviewData(stream2[i],200);
+ if(nbOfCells!=-1)
+ { nbOfNodes*=nbTuples; nbOfCells*=nbTuples-1; }
+ }
+ }
+ else
+ { stream2[i] << "set and allocated - WARNING number of components != 1 !"; nbOfCells=-1; nbOfNodes=-1; }
+ }
+ }
+ }
+ if(!isDef[0] && !isDef[1] && !isDef[2])
+ { stream << " No arrays set !"; return; }
+ if(nbOfCells>=0)
+ { stream << std::endl << "Number of cells : " << nbOfCells << ". Number of nodes : " << nbOfNodes << "."; }
+ for(int i=0;i<3;i++)
+ {
+ if(isDef[i])
+ stream << std::endl << stream2[i].str();
+ }
+}
+
+std::string MEDCouplingCMesh::getVTKFileExtension() const
{
- throw INTERP_KERNEL::Exception("MEDCouplingCMesh::writeVTKLL : not implemented yet !");
+ return std::string("vtr");
}
-std::string MEDCouplingCMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
+std::string MEDCouplingCMesh::getVTKDataSetType() const
{
return std::string("RectilinearGrid");
}