1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCouplingCMesh.hxx"
22 #include "MEDCouplingMemArray.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24 #include "MEDCouplingCurveLinearMesh.hxx"
26 #include "InterpKernelAutoPtr.hxx"
33 using namespace MEDCoupling;
35 MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0)
39 MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy)
44 _x_array=other._x_array->deepCopy();
48 _y_array=other._y_array->deepCopy();
52 _z_array=other._z_array->deepCopy();
58 _x_array=other._x_array;
61 _y_array=other._y_array;
64 _z_array=other._z_array;
70 MEDCouplingCMesh::~MEDCouplingCMesh()
80 MEDCouplingCMesh *MEDCouplingCMesh::New()
82 return new MEDCouplingCMesh;
85 MEDCouplingCMesh *MEDCouplingCMesh::New(const std::string& meshName)
87 MEDCouplingCMesh *ret(new MEDCouplingCMesh);
88 ret->setName(meshName);
92 MEDCouplingCMesh *MEDCouplingCMesh::deepCopy() const
97 MEDCouplingCMesh *MEDCouplingCMesh::clone(bool recDeepCpy) const
99 return new MEDCouplingCMesh(*this,recDeepCpy);
102 const DataArrayDouble *MEDCouplingCMesh::getDirectAccessOfCoordsArrIfInStructure() const
104 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getDirectAccessOfCoordsArrIfInStructure : MEDCouplingCMesh does not aggregate array of coordinates !");
107 MEDCouplingCurveLinearMesh *MEDCouplingCMesh::buildCurveLinear() const
109 checkConsistencyLight();
110 int dim(getSpaceDimension());
111 MCAuto<MEDCouplingCurveLinearMesh> ret(MEDCouplingCurveLinearMesh::New());
112 ret->MEDCouplingStructuredMesh::operator=(*this);
113 INTERP_KERNEL::AutoPtr<int> ngs(new int[dim]);
114 getNodeGridStructure(ngs);
115 ret->setNodeGridStructure(ngs,ngs+dim);
116 MCAuto<DataArrayDouble> coo(getCoordinatesAndOwner());
121 void MEDCouplingCMesh::updateTime() const
124 updateTimeWith(*_x_array);
126 updateTimeWith(*_y_array);
128 updateTimeWith(*_z_array);
131 std::size_t MEDCouplingCMesh::getHeapMemorySizeWithoutChildren() const
133 return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
136 std::vector<const BigMemoryObject *> MEDCouplingCMesh::getDirectChildrenWithNull() const
138 std::vector<const BigMemoryObject *> ret;
139 ret.push_back(_x_array);
140 ret.push_back(_y_array);
141 ret.push_back(_z_array);
146 * This method copyies all tiny strings from other (name and components name).
147 * @throw if other and this have not same mesh type.
149 void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
151 MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
152 const MEDCouplingCMesh *otherC(dynamic_cast<const MEDCouplingCMesh *>(other));
154 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !");
155 if(_x_array && otherC->_x_array)
156 _x_array->copyStringInfoFrom(*otherC->_x_array);
157 if(_y_array && otherC->_y_array)
158 _y_array->copyStringInfoFrom(*otherC->_y_array);
159 if(_z_array && otherC->_z_array)
160 _z_array->copyStringInfoFrom(*otherC->_z_array);
163 bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
166 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::isEqualIfNotWhy : input other pointer is null !");
167 const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
170 reason="mesh given in input is not castable in MEDCouplingCMesh !";
173 if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
175 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
176 const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
177 std::ostringstream oss; oss.precision(15);
180 if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0))
182 oss << "Only one CMesh between the two this and other has its coordinates of rank" << i << " defined !";
187 if(!thisArr[i]->isEqualIfNotWhy(*otherArr[i],prec,reason))
189 oss << "Coordinates DataArrayDouble of rank #" << i << " differ :";
190 reason.insert(0,oss.str());
197 bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
199 const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
202 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
203 const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
206 if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0))
209 if(!thisArr[i]->isEqualWithoutConsideringStr(*otherArr[i],prec))
215 void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
216 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
218 if(!isEqualWithoutConsideringStr(other,prec))
219 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalWith : Meshes are not the same !");
223 * Nothing is done here (except to check that the other is a MEDCoupling::MEDCouplingCMesh instance too).
224 * The user intend that the nodes are the same, so by construction of MEDCoupling::MEDCouplingCMesh, \a this and \a other are the same !
226 void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
227 DataArrayInt *&cellCor) const
229 if(!isEqualWithoutConsideringStr(other,prec))
230 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
233 void MEDCouplingCMesh::checkConsistencyLight() const
235 const char msg0[]="Invalid ";
236 const char msg1[]=" array ! Must contain more than 1 element.";
237 const char msg2[]=" array ! Must be with only one component.";
238 getSpaceDimension();// here to check that no holes in arrays !
241 if(_x_array->getNbOfElems()<2)
243 std::ostringstream os; os << msg0 << 'X' << msg1;
244 throw INTERP_KERNEL::Exception(os.str().c_str());
246 if(_x_array->getNumberOfComponents()!=1)
248 std::ostringstream os; os << msg0 << 'X' << msg2;
249 throw INTERP_KERNEL::Exception(os.str().c_str());
254 if(_y_array->getNbOfElems()<2)
256 std::ostringstream os; os << msg0 << 'Y' << msg1;
257 throw INTERP_KERNEL::Exception(os.str().c_str());
259 if(_y_array->getNumberOfComponents()!=1)
261 std::ostringstream os; os << msg0 << 'Y' << msg2;
262 throw INTERP_KERNEL::Exception(os.str().c_str());
267 if(_z_array->getNbOfElems()<2)
269 std::ostringstream os; os << msg0 << 'Z' << msg1;
270 throw INTERP_KERNEL::Exception(os.str().c_str());
272 if(_z_array->getNumberOfComponents()!=1)
274 std::ostringstream os; os << msg0 << 'Z' << msg2;
275 throw INTERP_KERNEL::Exception(os.str().c_str());
280 void MEDCouplingCMesh::checkConsistency(double eps) const
282 checkConsistencyLight();
284 _x_array->checkMonotonic(true, eps);
286 _y_array->checkMonotonic(true, eps);
288 _z_array->checkMonotonic(true, eps);
291 void MEDCouplingCMesh::getNodeGridStructure(int *res) const
293 std::vector<int> ret(getNodeGridStructure());
294 std::copy(ret.begin(),ret.end(),res);
297 std::vector<int> MEDCouplingCMesh::getNodeGridStructure() const
299 static const char MSG[]="MEDCouplingCMesh::getNodeGridStructure : mesh is invalid ! null vectors (X, Y or Z) must be put contiguously at the end !";
300 std::vector<int> ret;
304 if(!_x_array->isAllocated() || _x_array->getNumberOfComponents()!=1)
305 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : X array exits but it is not allocated or with nb of components equal to one !");
306 ret.push_back(_x_array->getNumberOfTuples());
312 if(!_y_array->isAllocated() || _y_array->getNumberOfComponents()!=1)
313 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Y array exits but it is not allocated or with nb of components equal to one !");
315 throw INTERP_KERNEL::Exception(MSG);
316 ret.push_back(_y_array->getNumberOfTuples());
322 if(!_z_array->isAllocated() || _z_array->getNumberOfComponents()!=1)
323 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Z array exits but it is not allocated or with nb of components equal to one !");
325 throw INTERP_KERNEL::Exception(MSG);
326 ret.push_back(_z_array->getNumberOfTuples());
331 MEDCouplingStructuredMesh *MEDCouplingCMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
333 checkConsistencyLight();
334 int dim(getSpaceDimension());
335 if(dim!=(int)cellPart.size())
337 std::ostringstream oss; oss << "MEDCouplingCMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
338 throw INTERP_KERNEL::Exception(oss.str().c_str());
340 MCAuto<MEDCouplingCMesh> ret(dynamic_cast<MEDCouplingCMesh *>(deepCopy()));
341 for(int i=0;i<dim;i++)
343 MCAuto<DataArrayDouble> tmp(ret->getCoordsAt(i)->selectByTupleIdSafeSlice(cellPart[i].first,cellPart[i].second+1,1));
344 ret->setCoordsAt(i,tmp);
350 * Return the space dimension of \a this. It only considers the arrays along X, Y and Z to deduce that.
351 * 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.
353 int MEDCouplingCMesh::getSpaceDimension() const
355 return (int)getNodeGridStructure().size();
358 void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
361 int spaceDim=getSpaceDimension();
362 getSplitNodeValues(tmp);
363 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
365 GetPosFromId(nodeId,spaceDim,tmp,tmp2);
366 for(int j=0;j<spaceDim;j++)
368 coo.push_back(tabs[j]->getConstPointer()[tmp2[j]]);
371 std::string MEDCouplingCMesh::simpleRepr() const
373 std::ostringstream ret;
374 ret << "Cartesian mesh with name : \"" << getName() << "\"\n";
375 ret << "Description of mesh : \"" << getDescription() << "\"\n";
377 double tt=getTime(tmpp1,tmpp2);
378 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
379 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
380 ret << "Space dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n";
383 ret << "X Array :\n";
384 _x_array->reprZipWithoutNameStream(ret);
388 ret << "Y Array :\n";
389 _y_array->reprZipWithoutNameStream(ret);
393 ret << "Z Array :\n";
394 _z_array->reprZipWithoutNameStream(ret);
399 std::string MEDCouplingCMesh::advancedRepr() const
405 * Returns a DataArrayDouble holding positions of nodes along a given axis.
406 * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage.
407 * \param [in] i - an index of axis, a value from [0,1,2].
408 * \return const DataArrayDouble * - a pointer to the data array of node coordinates
409 * referred by \a this mesh.
410 * \throw If \a i is not one of [0,1,2].
412 * \if ENABLE_EXAMPLES
413 * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br>
414 * \ref py_mccmesh_getCoordsAt "Here is a Python example".
417 const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const
428 throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
433 * Returns a DataArrayDouble holding positions of nodes along a given axis.
434 * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage.
435 * \param [in] i - an index of axis, a value from [0,1,2].
436 * \return const DataArrayDouble * - a pointer to the data array of node coordinates
437 * referred by \a this mesh.
438 * \throw If \a i is not one of [0,1,2].
440 * \if ENABLE_EXAMPLES
441 * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br>
442 * \ref py_mccmesh_getCoordsAt "Here is a Python example".
445 DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i)
456 throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
461 * Sets node coordinates along a given axis. For more info on Cartesian meshes, see
462 * \ref MEDCouplingCMeshPage.
463 * \param [in] i - an index of axis, a value in range [0,1,2].
464 * \param [in] arr - DataArrayDouble holding positions of nodes along the i-th
465 * axis. It must be an array of one component.
466 * \throw If \a arr->getNumberOfComponents() != 1.
467 * \throw If \a i is not one of [0,1,2].
469 * \if ENABLE_EXAMPLES
470 * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br>
471 * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example".
474 void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr)
477 arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt");
478 DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
480 throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
481 if(arr!=*(thisArr[i]))
484 (*(thisArr[i]))->decrRef();
485 (*(thisArr[i]))=const_cast<DataArrayDouble *>(arr);
487 (*(thisArr[i]))->incrRef();
493 * Sets node coordinates along some of the tree axes. This method updates all the
494 * three node coordinates arrays at once. For more info on Cartesian meshes, see
495 * \ref MEDCouplingCMeshPage.
496 * \param [in] coordsX - DataArrayDouble holding positions of nodes along the X
497 * axis. It must be an array of one component or \c NULL.
498 * \param [in] coordsY - DataArrayDouble holding positions of nodes along the Y
499 * axis. It must be an array of one component or \c NULL.
500 * \param [in] coordsZ - DataArrayDouble holding positions of nodes along the Z
501 * axis. It must be an array of one component or \c NULL.
502 * \throw If \a coords*->getNumberOfComponents() != 1.
504 * \if ENABLE_EXAMPLES
505 * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br>
506 * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example".
509 void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ)
512 coordsX->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsX");
514 coordsY->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsY");
516 coordsZ->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsZ");
519 _x_array=const_cast<DataArrayDouble *>(coordsX);
524 _y_array=const_cast<DataArrayDouble *>(coordsY);
529 _z_array=const_cast<DataArrayDouble *>(coordsZ);
535 void MEDCouplingCMesh::getBoundingBox(double *bbox) const
537 int dim=getSpaceDimension();
539 for (int idim=0; idim<dim; idim++)
541 const DataArrayDouble *c=getCoordsAt(idim);
544 const double *coords=c->getConstPointer();
545 int nb=c->getNbOfElems();
547 bbox[2*j+1]=coords[nb-1];
554 * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
556 * For 1D cells, the returned field contains lengths.<br>
557 * For 2D cells, the returned field contains areas.<br>
558 * For 3D cells, the returned field contains volumes.
559 * \param [in] isAbs - a not used parameter.
560 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
561 * and one time . The caller is to delete this field using decrRef() as it is no
564 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const
566 std::string name="MeasureOfMesh_";
568 int nbelem=getNumberOfCells();
569 MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
570 field->setName(name);
571 DataArrayDouble* array=DataArrayDouble::New();
572 array->alloc(nbelem,1);
573 double *area_vol=array->getPointer();
574 field->setArray(array) ;
576 field->setMesh(const_cast<MEDCouplingCMesh *>(this));
577 field->synchronizeTimeWithMesh();
579 getSplitCellValues(tmp);
580 int dim=getSpaceDimension();
581 const double **thisArr=new const double *[dim];
582 const DataArrayDouble *thisArr2[3]={_x_array,_y_array,_z_array};
583 for(int i=0;i<dim;i++)
584 thisArr[i]=thisArr2[i]->getConstPointer();
585 for(int icell=0;icell<nbelem;icell++)
588 GetPosFromId(icell,dim,tmp,tmp2);
590 for(int i=0;i<dim;i++)
591 area_vol[icell]*=thisArr[i][tmp2[i]+1]-thisArr[i][tmp2[i]];
598 * not implemented yet !
600 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) const
602 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getMeasureFieldOnNode : not implemented yet !");
606 int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const
608 int dim=getSpaceDimension();
611 for(int i=0;i<dim;i++)
613 const double *d=getCoordsAt(i)->getConstPointer();
614 int nbOfNodes=getCoordsAt(i)->getNbOfElems();
616 const double *w=std::find_if(d,d+nbOfNodes,std::bind2nd(std::greater_equal<double>(),ref));
617 int w2=(int)std::distance(d,w);
636 void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle)
638 throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to untructured mesh to apply it !");
642 * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
643 * component of the \a vector to all node coordinates of a corresponding axis.
644 * \param [in] vector - the translation vector whose size must be not less than \a
645 * this->getSpaceDimension().
647 void MEDCouplingCMesh::translate(const double *vector)
650 std::transform(_x_array->getConstPointer(),_x_array->getConstPointer()+_x_array->getNbOfElems(),
651 _x_array->getPointer(),std::bind2nd(std::plus<double>(),vector[0]));
653 std::transform(_y_array->getConstPointer(),_y_array->getConstPointer()+_y_array->getNbOfElems(),
654 _y_array->getPointer(),std::bind2nd(std::plus<double>(),vector[1]));
656 std::transform(_z_array->getConstPointer(),_z_array->getConstPointer()+_z_array->getNbOfElems(),
657 _z_array->getPointer(),std::bind2nd(std::plus<double>(),vector[2]));
661 * Applies scaling transformation to all nodes of \a this mesh.
662 * \param [in] point - coordinates of a scaling center. This array is to be of
663 * size \a this->getSpaceDimension() at least.
664 * \param [in] factor - a scale factor.
666 void MEDCouplingCMesh::scale(const double *point, double factor)
670 DataArrayDouble *c=getCoordsAt(i);
673 double *coords=c->getPointer();
674 int lgth=c->getNbOfElems();
675 std::transform(coords,coords+lgth,coords,std::bind2nd(std::minus<double>(),point[i]));
676 std::transform(coords,coords+lgth,coords,std::bind2nd(std::multiplies<double>(),factor));
677 std::transform(coords,coords+lgth,coords,std::bind2nd(std::plus<double>(),point[i]));
684 MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
686 //not implemented yet !
691 * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
692 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
693 * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
694 * components. The caller is to delete this array using decrRef() as it is
697 DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const
699 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
700 int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
701 ret->alloc(nbNodes,spaceDim);
702 double *pt(ret->getPointer());
704 getSplitNodeValues(tmp);
705 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
706 const double *tabsPtr[3];
707 for(int j=0;j<spaceDim;j++)
709 tabsPtr[j]=tabs[j]->getConstPointer();
710 ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
713 for(int i=0;i<nbNodes;i++)
715 GetPosFromId(i,spaceDim,tmp,tmp2);
716 for(int j=0;j<spaceDim;j++)
717 pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
723 * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
724 * computed by averaging coordinates of cell nodes.
725 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
726 * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
727 * components. The caller is to delete this array using decrRef() as it is
730 DataArrayDouble *MEDCouplingCMesh::computeCellCenterOfMass() const
732 DataArrayDouble *ret=DataArrayDouble::New();
733 int spaceDim=getSpaceDimension();
734 int nbCells=getNumberOfCells();
735 ret->alloc(nbCells,spaceDim);
736 double *pt=ret->getPointer();
738 getSplitCellValues(tmp);
739 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
740 std::vector<double> tabsPtr[3];
741 for(int j=0;j<spaceDim;j++)
743 int sz=tabs[j]->getNbOfElems()-1;
744 ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
745 const double *srcPtr=tabs[j]->getConstPointer();
746 tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz);
747 std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus<double>());
748 std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),tabsPtr[j].begin(),std::bind2nd(std::multiplies<double>(),0.5));
751 for(int i=0;i<nbCells;i++)
753 GetPosFromId(i,spaceDim,tmp,tmp2);
754 for(int j=0;j<spaceDim;j++)
755 pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
760 DataArrayDouble *MEDCouplingCMesh::computeIsoBarycenterOfNodesPerCell() const
762 return MEDCouplingCMesh::computeCellCenterOfMass();
765 void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check)
767 throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !");
770 void MEDCouplingCMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
773 double time=getTime(it,order);
776 littleStrings.clear();
777 littleStrings.push_back(getName());
778 littleStrings.push_back(getDescription());
779 littleStrings.push_back(getTimeUnit());
780 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
787 val=thisArr[i]->getNumberOfTuples();
788 st=thisArr[i]->getInfoOnComponent(0);
790 tinyInfo.push_back(val);
791 littleStrings.push_back(st);
793 tinyInfo.push_back(it);
794 tinyInfo.push_back(order);
795 tinyInfoD.push_back(time);
798 void MEDCouplingCMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
808 void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
810 a1=DataArrayInt::New();
812 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
817 sz+=thisArr[i]->getNumberOfTuples();
819 a2=DataArrayDouble::New();
821 double *a2Ptr=a2->getPointer();
824 a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr);
827 void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
828 const std::vector<std::string>& littleStrings)
830 setName(littleStrings[0]);
831 setDescription(littleStrings[1]);
832 setTimeUnit(littleStrings[2]);
833 DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
834 const double *data=a2->getConstPointer();
839 (*(thisArr[i]))=DataArrayDouble::New();
840 (*(thisArr[i]))->alloc(tinyInfo[i],1);
841 (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3]);
842 std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer());
846 setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]);
849 void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
851 std::ostringstream extent;
852 DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
856 { extent << "0 " << thisArr[i]->getNumberOfTuples()-1 << " "; }
858 { extent << "0 0 "; }
860 ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n";
861 ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
862 ofs << " <PointData>\n" << pointData << std::endl;
863 ofs << " </PointData>\n";
864 ofs << " <CellData>\n" << cellData << std::endl;
865 ofs << " </CellData>\n";
866 ofs << " <Coordinates>\n";
870 thisArr[i]->writeVTK(ofs,8,"Array",byteData);
873 MCAuto<DataArrayDouble> coo=DataArrayDouble::New(); coo->alloc(1,1);
875 coo->writeVTK(ofs,8,"Array",byteData);
878 ofs << " </Coordinates>\n";
879 ofs << " </Piece>\n";
880 ofs << " </" << getVTKDataSetType() << ">\n";
883 void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const
885 stream << "MEDCouplingCMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
886 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
887 std::ostringstream stream2[3];
889 int nbOfCells=1,nbOfNodes=1;
892 isDef[i]=thisArr[i]!=0;
896 stream2[i] << tmp << " positions array ";
897 if(!thisArr[i]->isAllocated())
898 stream2[i] << "set but not allocated.";
901 int nbCompo=thisArr[i]->getNumberOfComponents();
904 int nbTuples=thisArr[i]->getNumberOfTuples();
906 { stream2[i] << "set and allocated - WARNING number of elements < 1 !"; nbOfCells=-1; nbOfNodes=-1; }
909 stream2[i] << "(length=" << nbTuples << ")" << ": ";
910 thisArr[i]->reprQuickOverviewData(stream2[i],200);
912 { nbOfNodes*=nbTuples; nbOfCells*=nbTuples-1; }
916 { stream2[i] << "set and allocated - WARNING number of components != 1 !"; nbOfCells=-1; nbOfNodes=-1; }
920 if(!isDef[0] && !isDef[1] && !isDef[2])
921 { stream << " No arrays set !"; return; }
923 { stream << std::endl << "Number of cells : " << nbOfCells << ". Number of nodes : " << nbOfNodes << "."; }
927 stream << std::endl << stream2[i].str();
931 std::string MEDCouplingCMesh::getVTKFileExtension() const
933 return std::string("vtr");
936 std::string MEDCouplingCMesh::getVTKDataSetType() const
938 return std::string("RectilinearGrid");