1 // Copyright (C) 2007-2021 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 deepCpy):MEDCouplingStructuredMesh(other,deepCpy)
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 std::size_t dim(getSpaceDimension());
111 MCAuto<MEDCouplingCurveLinearMesh> ret(MEDCouplingCurveLinearMesh::New());
112 ret->MEDCouplingStructuredMesh::operator=(*this);
113 INTERP_KERNEL::AutoPtr<mcIdType> ngs(new mcIdType[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 DataArrayIdType *&cellCor, DataArrayIdType *&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 DataArrayIdType *&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(mcIdType *res) const
293 std::vector<mcIdType> ret(getNodeGridStructure());
294 std::copy(ret.begin(),ret.end(),res);
297 std::vector<mcIdType> 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<mcIdType> 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<mcIdType,mcIdType> >& cellPart) const
333 checkConsistencyLight();
334 int dim(getSpaceDimension());
335 if(dim!=ToIdType(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(mcIdType 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 mcIdType nb=ToIdType(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 mcIdType nbelem=ToIdType(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(mcIdType 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 mcIdType 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 mcIdType nbOfNodes=getCoordsAt(i)->getNbOfElems();
616 const double *w=std::find_if(d,d+nbOfNodes,std::bind(std::greater_equal<double>(),std::placeholders::_1,ref));
617 mcIdType w2=ToIdType(std::distance(d,w));
636 void MEDCouplingCMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<mcIdType>& elts) const
638 mcIdType ret(getCellContainingPoint(pos,eps));
642 void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle)
644 throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to untructured mesh to apply it !");
648 * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
649 * component of the \a vector to all node coordinates of a corresponding axis.
650 * \param [in] vector - the translation vector whose size must be not less than \a
651 * this->getSpaceDimension().
653 void MEDCouplingCMesh::translate(const double *vector)
656 std::transform(_x_array->getConstPointer(),_x_array->getConstPointer()+_x_array->getNbOfElems(),
657 _x_array->getPointer(),std::bind(std::plus<double>(),std::placeholders::_1,vector[0]));
659 std::transform(_y_array->getConstPointer(),_y_array->getConstPointer()+_y_array->getNbOfElems(),
660 _y_array->getPointer(),std::bind(std::plus<double>(),std::placeholders::_1,vector[1]));
662 std::transform(_z_array->getConstPointer(),_z_array->getConstPointer()+_z_array->getNbOfElems(),
663 _z_array->getPointer(),std::bind(std::plus<double>(),std::placeholders::_1,vector[2]));
667 * Applies scaling transformation to all nodes of \a this mesh.
668 * \param [in] point - coordinates of a scaling center. This array is to be of
669 * size \a this->getSpaceDimension() at least.
670 * \param [in] factor - a scale factor.
672 void MEDCouplingCMesh::scale(const double *point, double factor)
676 DataArrayDouble *c=getCoordsAt(i);
679 double *coords=c->getPointer();
680 mcIdType lgth=ToIdType(c->getNbOfElems());
681 std::transform(coords,coords+lgth,coords,std::bind(std::minus<double>(),std::placeholders::_1,point[i]));
682 std::transform(coords,coords+lgth,coords,std::bind(std::multiplies<double>(),std::placeholders::_1,factor));
683 std::transform(coords,coords+lgth,coords,std::bind(std::plus<double>(),std::placeholders::_1,point[i]));
690 MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
692 //not implemented yet !
697 * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
698 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
699 * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
700 * components. The caller is to delete this array using decrRef() as it is
703 DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const
705 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
706 int spaceDim(getSpaceDimension());
707 mcIdType nbNodes(getNumberOfNodes());
708 ret->alloc(nbNodes,spaceDim);
709 double *pt(ret->getPointer());
711 getSplitNodeValues(tmp);
712 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
713 const double *tabsPtr[3];
714 for(mcIdType j=0;j<spaceDim;j++)
716 tabsPtr[j]=tabs[j]->getConstPointer();
717 ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
720 for(mcIdType i=0;i<nbNodes;i++)
722 GetPosFromId(i,spaceDim,tmp,tmp2);
723 for(int j=0;j<spaceDim;j++)
724 pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
730 * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
731 * computed by averaging coordinates of cell nodes.
732 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
733 * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
734 * components. The caller is to delete this array using decrRef() as it is
737 DataArrayDouble *MEDCouplingCMesh::computeCellCenterOfMass() const
739 DataArrayDouble *ret=DataArrayDouble::New();
740 int spaceDim=getSpaceDimension();
741 mcIdType nbCells=ToIdType(getNumberOfCells());
742 ret->alloc(nbCells,spaceDim);
743 double *pt=ret->getPointer();
745 getSplitCellValues(tmp);
746 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
747 std::vector<double> tabsPtr[3];
748 for(int j=0;j<spaceDim;j++)
750 mcIdType sz=tabs[j]->getNbOfElems()-1;
751 ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
752 const double *srcPtr=tabs[j]->getConstPointer();
753 tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz);
754 std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus<double>());
755 std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),tabsPtr[j].begin(),std::bind(std::multiplies<double>(),std::placeholders::_1,0.5));
758 for(int i=0;i<nbCells;i++)
760 GetPosFromId(i,spaceDim,tmp,tmp2);
761 for(int j=0;j<spaceDim;j++)
762 pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
767 DataArrayDouble *MEDCouplingCMesh::computeIsoBarycenterOfNodesPerCell() const
769 return MEDCouplingCMesh::computeCellCenterOfMass();
772 void MEDCouplingCMesh::renumberCells(const mcIdType *old2NewBg, bool check)
774 throw INTERP_KERNEL::Exception("Functionality of renumbering cell not available for CMesh !");
777 void MEDCouplingCMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<mcIdType>& tinyInfo, std::vector<std::string>& littleStrings) const
780 double time=getTime(it,order);
783 littleStrings.clear();
784 littleStrings.push_back(getName());
785 littleStrings.push_back(getDescription());
786 littleStrings.push_back(getTimeUnit());
787 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
794 val=thisArr[i]->getNumberOfTuples();
795 st=thisArr[i]->getInfoOnComponent(0);
797 tinyInfo.push_back(val);
798 littleStrings.push_back(st);
800 tinyInfo.push_back(it);
801 tinyInfo.push_back(order);
802 tinyInfoD.push_back(time);
805 void MEDCouplingCMesh::resizeForUnserialization(const std::vector<mcIdType>& tinyInfo, DataArrayIdType *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
815 void MEDCouplingCMesh::serialize(DataArrayIdType *&a1, DataArrayDouble *&a2) const
817 a1=DataArrayIdType::New();
819 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
824 sz+=thisArr[i]->getNumberOfTuples();
826 a2=DataArrayDouble::New();
828 double *a2Ptr=a2->getPointer();
831 a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr);
834 void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<mcIdType>& tinyInfo, const DataArrayIdType *a1, DataArrayDouble *a2,
835 const std::vector<std::string>& littleStrings)
837 setName(littleStrings[0]);
838 setDescription(littleStrings[1]);
839 setTimeUnit(littleStrings[2]);
840 DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
841 const double *data=a2->getConstPointer();
846 (*(thisArr[i]))=DataArrayDouble::New();
847 (*(thisArr[i]))->alloc(tinyInfo[i],1);
848 (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3]);
849 std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer());
853 setTime(tinyInfoD[0],FromIdType<int>(tinyInfo[3]),FromIdType<int>(tinyInfo[4]));
856 void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
858 std::ostringstream extent;
859 DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
863 { extent << "0 " << thisArr[i]->getNumberOfTuples()-1 << " "; }
865 { extent << "0 0 "; }
867 ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n";
868 ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
869 ofs << " <PointData>\n" << pointData << std::endl;
870 ofs << " </PointData>\n";
871 ofs << " <CellData>\n" << cellData << std::endl;
872 ofs << " </CellData>\n";
873 ofs << " <Coordinates>\n";
877 thisArr[i]->writeVTK(ofs,8,"Array",byteData);
880 MCAuto<DataArrayDouble> coo=DataArrayDouble::New(); coo->alloc(1,1);
882 coo->writeVTK(ofs,8,"Array",byteData);
885 ofs << " </Coordinates>\n";
886 ofs << " </Piece>\n";
887 ofs << " </" << getVTKDataSetType() << ">\n";
890 void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const
892 stream << "MEDCouplingCMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
893 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
894 std::ostringstream stream2[3];
896 mcIdType nbOfCells=1,nbOfNodes=1;
899 isDef[i]=thisArr[i]!=0;
902 char tmp=(char)((int)('X')+i);
903 stream2[i] << tmp << " positions array ";
904 if(!thisArr[i]->isAllocated())
905 stream2[i] << "set but not allocated.";
908 std::size_t nbCompo=thisArr[i]->getNumberOfComponents();
911 mcIdType nbTuples=thisArr[i]->getNumberOfTuples();
913 { stream2[i] << "set and allocated - WARNING number of elements < 1 !"; nbOfCells=-1; nbOfNodes=-1; }
916 stream2[i] << "(length=" << nbTuples << ")" << ": ";
917 thisArr[i]->reprQuickOverviewData(stream2[i],200);
919 { nbOfNodes*=nbTuples; nbOfCells*=nbTuples-1; }
923 { stream2[i] << "set and allocated - WARNING number of components != 1 !"; nbOfCells=-1; nbOfNodes=-1; }
927 if(!isDef[0] && !isDef[1] && !isDef[2])
928 { stream << " No arrays set !"; return; }
930 { stream << std::endl << "Number of cells : " << nbOfCells << ". Number of nodes : " << nbOfNodes << "."; }
934 stream << std::endl << stream2[i].str();
938 std::string MEDCouplingCMesh::getVTKFileExtension() const
940 return std::string("vtr");
943 std::string MEDCouplingCMesh::getVTKDataSetType() const
945 return std::string("RectilinearGrid");