1 // Copyright (C) 2007-2014 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"
30 using namespace ParaMEDMEM;
32 MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0)
36 MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy)
41 _x_array=other._x_array->deepCpy();
45 _y_array=other._y_array->deepCpy();
49 _z_array=other._z_array->deepCpy();
55 _x_array=other._x_array;
58 _y_array=other._y_array;
61 _z_array=other._z_array;
67 MEDCouplingCMesh::~MEDCouplingCMesh()
77 MEDCouplingCMesh *MEDCouplingCMesh::New()
79 return new MEDCouplingCMesh;
82 MEDCouplingCMesh *MEDCouplingCMesh::New(const std::string& meshName)
84 MEDCouplingCMesh *ret=new MEDCouplingCMesh;
85 ret->setName(meshName);
89 MEDCouplingMesh *MEDCouplingCMesh::deepCpy() const
94 MEDCouplingCMesh *MEDCouplingCMesh::clone(bool recDeepCpy) const
96 return new MEDCouplingCMesh(*this,recDeepCpy);
99 void MEDCouplingCMesh::updateTime() const
102 updateTimeWith(*_x_array);
104 updateTimeWith(*_y_array);
106 updateTimeWith(*_z_array);
109 std::size_t MEDCouplingCMesh::getHeapMemorySizeWithoutChildren() const
111 return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
114 std::vector<const BigMemoryObject *> MEDCouplingCMesh::getDirectChildrenWithNull() const
116 std::vector<const BigMemoryObject *> ret;
117 ret.push_back(_x_array);
118 ret.push_back(_y_array);
119 ret.push_back(_z_array);
124 * This method copyies all tiny strings from other (name and components name).
125 * @throw if other and this have not same mesh type.
127 void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
129 MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
130 const MEDCouplingCMesh *otherC(dynamic_cast<const MEDCouplingCMesh *>(other));
132 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !");
133 if(_x_array && otherC->_x_array)
134 _x_array->copyStringInfoFrom(*otherC->_x_array);
135 if(_y_array && otherC->_y_array)
136 _y_array->copyStringInfoFrom(*otherC->_y_array);
137 if(_z_array && otherC->_z_array)
138 _z_array->copyStringInfoFrom(*otherC->_z_array);
141 bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
144 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::isEqualIfNotWhy : input other pointer is null !");
145 const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
148 reason="mesh given in input is not castable in MEDCouplingCMesh !";
151 if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
153 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
154 const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
155 std::ostringstream oss; oss.precision(15);
158 if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0))
160 oss << "Only one CMesh between the two this and other has its coordinates of rank" << i << " defined !";
165 if(!thisArr[i]->isEqualIfNotWhy(*otherArr[i],prec,reason))
167 oss << "Coordinates DataArrayDouble of rank #" << i << " differ :";
168 reason.insert(0,oss.str());
175 bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
177 const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
180 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
181 const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
184 if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0))
187 if(!thisArr[i]->isEqualWithoutConsideringStr(*otherArr[i],prec))
193 void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
194 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
196 if(!isEqualWithoutConsideringStr(other,prec))
197 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalWith : Meshes are not the same !");
201 * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCMesh instance too).
202 * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCMesh, \a this and \a other are the same !
204 void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
205 DataArrayInt *&cellCor) const
207 if(!isEqualWithoutConsideringStr(other,prec))
208 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
211 void MEDCouplingCMesh::checkCoherency() const
213 const char msg0[]="Invalid ";
214 const char msg1[]=" array ! Must contain more than 1 element.";
215 const char msg2[]=" array ! Must be with only one component.";
216 getSpaceDimension();// here to check that no holes in arrays !
219 if(_x_array->getNbOfElems()<2)
221 std::ostringstream os; os << msg0 << 'X' << msg1;
222 throw INTERP_KERNEL::Exception(os.str().c_str());
224 if(_x_array->getNumberOfComponents()!=1)
226 std::ostringstream os; os << msg0 << 'X' << msg2;
227 throw INTERP_KERNEL::Exception(os.str().c_str());
232 if(_y_array->getNbOfElems()<2)
234 std::ostringstream os; os << msg0 << 'Y' << msg1;
235 throw INTERP_KERNEL::Exception(os.str().c_str());
237 if(_y_array->getNumberOfComponents()!=1)
239 std::ostringstream os; os << msg0 << 'Y' << msg2;
240 throw INTERP_KERNEL::Exception(os.str().c_str());
245 if(_z_array->getNbOfElems()<2)
247 std::ostringstream os; os << msg0 << 'Z' << msg1;
248 throw INTERP_KERNEL::Exception(os.str().c_str());
250 if(_z_array->getNumberOfComponents()!=1)
252 std::ostringstream os; os << msg0 << 'Z' << msg2;
253 throw INTERP_KERNEL::Exception(os.str().c_str());
258 void MEDCouplingCMesh::checkCoherency1(double eps) const
262 _x_array->checkMonotonic(true, eps);
264 _y_array->checkMonotonic(true, eps);
266 _z_array->checkMonotonic(true, eps);
269 void MEDCouplingCMesh::checkCoherency2(double eps) const
271 checkCoherency1(eps);
274 void MEDCouplingCMesh::getNodeGridStructure(int *res) const
276 std::vector<int> ret(getNodeGridStructure());
277 std::copy(ret.begin(),ret.end(),res);
280 std::vector<int> MEDCouplingCMesh::getNodeGridStructure() const
282 static const char MSG[]="MEDCouplingCMesh::getNodeGridStructure : mesh is invalid ! null vectors (X, Y or Z) must be put contiguously at the end !";
283 std::vector<int> ret;
287 if(!_x_array->isAllocated() || _x_array->getNumberOfComponents()!=1)
288 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : X array exits but it is not allocated or with nb of components equal to one !");
289 ret.push_back(_x_array->getNumberOfTuples());
295 if(!_y_array->isAllocated() || _y_array->getNumberOfComponents()!=1)
296 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Y array exits but it is not allocated or with nb of components equal to one !");
298 throw INTERP_KERNEL::Exception(MSG);
299 ret.push_back(_y_array->getNumberOfTuples());
305 if(!_z_array->isAllocated() || _z_array->getNumberOfComponents()!=1)
306 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Z array exits but it is not allocated or with nb of components equal to one !");
308 throw INTERP_KERNEL::Exception(MSG);
309 ret.push_back(_z_array->getNumberOfTuples());
314 MEDCouplingStructuredMesh *MEDCouplingCMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
317 int dim(getSpaceDimension());
318 if(dim!=(int)cellPart.size())
320 std::ostringstream oss; oss << "MEDCouplingCMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
321 throw INTERP_KERNEL::Exception(oss.str().c_str());
323 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> ret(dynamic_cast<MEDCouplingCMesh *>(deepCpy()));
324 for(int i=0;i<dim;i++)
326 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(ret->getCoordsAt(i)->selectByTupleId2(cellPart[i].first,cellPart[i].second+1,1));
327 ret->setCoordsAt(i,tmp);
333 * Return the space dimension of \a this. It only considers the arrays along X, Y and Z to deduce that.
334 * 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.
336 int MEDCouplingCMesh::getSpaceDimension() const
338 return (int)getNodeGridStructure().size();
341 void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
344 int spaceDim=getSpaceDimension();
345 getSplitNodeValues(tmp);
346 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
348 GetPosFromId(nodeId,spaceDim,tmp,tmp2);
349 for(int j=0;j<spaceDim;j++)
351 coo.push_back(tabs[j]->getConstPointer()[tmp2[j]]);
354 std::string MEDCouplingCMesh::simpleRepr() const
356 std::ostringstream ret;
357 ret << "Cartesian mesh with name : \"" << getName() << "\"\n";
358 ret << "Description of mesh : \"" << getDescription() << "\"\n";
360 double tt=getTime(tmpp1,tmpp2);
361 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
362 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
363 ret << "Space dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n";
366 ret << "X Array :\n";
367 _x_array->reprZipWithoutNameStream(ret);
371 ret << "Y Array :\n";
372 _y_array->reprZipWithoutNameStream(ret);
376 ret << "Z Array :\n";
377 _z_array->reprZipWithoutNameStream(ret);
382 std::string MEDCouplingCMesh::advancedRepr() const
388 * Returns a DataArrayDouble holding positions of nodes along a given axis.
389 * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage.
390 * \param [in] i - an index of axis, a value from [0,1,2].
391 * \return const DataArrayDouble * - a pointer to the data array of node coordinates
392 * referred by \a this mesh.
393 * \throw If \a i is not one of [0,1,2].
395 * \if ENABLE_EXAMPLES
396 * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br>
397 * \ref py_mccmesh_getCoordsAt "Here is a Python example".
400 const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const
411 throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
416 * Returns a DataArrayDouble holding positions of nodes along a given axis.
417 * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage.
418 * \param [in] i - an index of axis, a value from [0,1,2].
419 * \return const DataArrayDouble * - a pointer to the data array of node coordinates
420 * referred by \a this mesh.
421 * \throw If \a i is not one of [0,1,2].
423 * \if ENABLE_EXAMPLES
424 * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br>
425 * \ref py_mccmesh_getCoordsAt "Here is a Python example".
428 DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i)
439 throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
444 * Sets node coordinates along a given axis. For more info on Cartesian meshes, see
445 * \ref MEDCouplingCMeshPage.
446 * \param [in] i - an index of axis, a value in range [0,1,2].
447 * \param [in] arr - DataArrayDouble holding positions of nodes along the i-th
448 * axis. It must be an array of one component.
449 * \throw If \a arr->getNumberOfComponents() != 1.
450 * \throw If \a i is not one of [0,1,2].
452 * \if ENABLE_EXAMPLES
453 * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br>
454 * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example".
457 void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr)
460 arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt");
461 DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
463 throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
464 if(arr!=*(thisArr[i]))
467 (*(thisArr[i]))->decrRef();
468 (*(thisArr[i]))=const_cast<DataArrayDouble *>(arr);
470 (*(thisArr[i]))->incrRef();
476 * Sets node coordinates along some of the tree axes. This method updates all the
477 * three node coordinates arrays at once. For more info on Cartesian meshes, see
478 * \ref MEDCouplingCMeshPage.
479 * \param [in] coordsX - DataArrayDouble holding positions of nodes along the X
480 * axis. It must be an array of one component or \c NULL.
481 * \param [in] coordsY - DataArrayDouble holding positions of nodes along the Y
482 * axis. It must be an array of one component or \c NULL.
483 * \param [in] coordsZ - DataArrayDouble holding positions of nodes along the Z
484 * axis. It must be an array of one component or \c NULL.
485 * \throw If \a coords*->getNumberOfComponents() != 1.
487 * \if ENABLE_EXAMPLES
488 * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br>
489 * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example".
492 void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ)
495 coordsX->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsX");
497 coordsY->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsY");
499 coordsZ->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsZ");
502 _x_array=const_cast<DataArrayDouble *>(coordsX);
507 _y_array=const_cast<DataArrayDouble *>(coordsY);
512 _z_array=const_cast<DataArrayDouble *>(coordsZ);
518 void MEDCouplingCMesh::getBoundingBox(double *bbox) const
520 int dim=getSpaceDimension();
522 for (int idim=0; idim<dim; idim++)
524 const DataArrayDouble *c=getCoordsAt(idim);
527 const double *coords=c->getConstPointer();
528 int nb=c->getNbOfElems();
530 bbox[2*j+1]=coords[nb-1];
537 * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
539 * For 1D cells, the returned field contains lengths.<br>
540 * For 2D cells, the returned field contains areas.<br>
541 * For 3D cells, the returned field contains volumes.
542 * \param [in] isAbs - a not used parameter.
543 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
544 * and one time . The caller is to delete this field using decrRef() as it is no
547 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const
549 std::string name="MeasureOfMesh_";
551 int nbelem=getNumberOfCells();
552 MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
553 field->setName(name);
554 DataArrayDouble* array=DataArrayDouble::New();
555 array->alloc(nbelem,1);
556 double *area_vol=array->getPointer();
557 field->setArray(array) ;
559 field->setMesh(const_cast<MEDCouplingCMesh *>(this));
560 field->synchronizeTimeWithMesh();
562 getSplitCellValues(tmp);
563 int dim=getSpaceDimension();
564 const double **thisArr=new const double *[dim];
565 const DataArrayDouble *thisArr2[3]={_x_array,_y_array,_z_array};
566 for(int i=0;i<dim;i++)
567 thisArr[i]=thisArr2[i]->getConstPointer();
568 for(int icell=0;icell<nbelem;icell++)
571 GetPosFromId(icell,dim,tmp,tmp2);
573 for(int i=0;i<dim;i++)
574 area_vol[icell]*=thisArr[i][tmp2[i]+1]-thisArr[i][tmp2[i]];
581 * not implemented yet !
583 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) const
585 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getMeasureFieldOnNode : not implemented yet !");
589 int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const
591 int dim=getSpaceDimension();
594 for(int i=0;i<dim;i++)
596 const double *d=getCoordsAt(i)->getConstPointer();
597 int nbOfNodes=getCoordsAt(i)->getNbOfElems();
599 const double *w=std::find_if(d,d+nbOfNodes,std::bind2nd(std::greater_equal<double>(),ref));
600 int w2=(int)std::distance(d,w);
619 void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle)
621 throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to untructured mesh to apply it !");
625 * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
626 * component of the \a vector to all node coordinates of a corresponding axis.
627 * \param [in] vector - the translation vector whose size must be not less than \a
628 * this->getSpaceDimension().
630 void MEDCouplingCMesh::translate(const double *vector)
633 std::transform(_x_array->getConstPointer(),_x_array->getConstPointer()+_x_array->getNbOfElems(),
634 _x_array->getPointer(),std::bind2nd(std::plus<double>(),vector[0]));
636 std::transform(_y_array->getConstPointer(),_y_array->getConstPointer()+_y_array->getNbOfElems(),
637 _y_array->getPointer(),std::bind2nd(std::plus<double>(),vector[1]));
639 std::transform(_z_array->getConstPointer(),_z_array->getConstPointer()+_z_array->getNbOfElems(),
640 _z_array->getPointer(),std::bind2nd(std::plus<double>(),vector[2]));
644 * Applies scaling transformation to all nodes of \a this mesh.
645 * \param [in] point - coordinates of a scaling center. This array is to be of
646 * size \a this->getSpaceDimension() at least.
647 * \param [in] factor - a scale factor.
649 void MEDCouplingCMesh::scale(const double *point, double factor)
653 DataArrayDouble *c=getCoordsAt(i);
656 double *coords=c->getPointer();
657 int lgth=c->getNbOfElems();
658 std::transform(coords,coords+lgth,coords,std::bind2nd(std::minus<double>(),point[i]));
659 std::transform(coords,coords+lgth,coords,std::bind2nd(std::multiplies<double>(),factor));
660 std::transform(coords,coords+lgth,coords,std::bind2nd(std::plus<double>(),point[i]));
667 MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
669 //not implemented yet !
674 * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
675 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
676 * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
677 * components. The caller is to delete this array using decrRef() as it is
680 DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const
682 DataArrayDouble *ret=DataArrayDouble::New();
683 int spaceDim=getSpaceDimension();
684 int nbNodes=getNumberOfNodes();
685 ret->alloc(nbNodes,spaceDim);
686 double *pt=ret->getPointer();
688 getSplitNodeValues(tmp);
689 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
690 const double *tabsPtr[3];
691 for(int j=0;j<spaceDim;j++)
693 tabsPtr[j]=tabs[j]->getConstPointer();
694 ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
697 for(int i=0;i<nbNodes;i++)
699 GetPosFromId(i,spaceDim,tmp,tmp2);
700 for(int j=0;j<spaceDim;j++)
701 pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
707 * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
708 * computed by averaging coordinates of cell nodes.
709 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
710 * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
711 * components. The caller is to delete this array using decrRef() as it is
714 DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const
716 DataArrayDouble *ret=DataArrayDouble::New();
717 int spaceDim=getSpaceDimension();
718 int nbCells=getNumberOfCells();
719 ret->alloc(nbCells,spaceDim);
720 double *pt=ret->getPointer();
722 getSplitCellValues(tmp);
723 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
724 std::vector<double> tabsPtr[3];
725 for(int j=0;j<spaceDim;j++)
727 int sz=tabs[j]->getNbOfElems()-1;
728 ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
729 const double *srcPtr=tabs[j]->getConstPointer();
730 tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz);
731 std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus<double>());
732 std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),tabsPtr[j].begin(),std::bind2nd(std::multiplies<double>(),0.5));
735 for(int i=0;i<nbCells;i++)
737 GetPosFromId(i,spaceDim,tmp,tmp2);
738 for(int j=0;j<spaceDim;j++)
739 pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
744 DataArrayDouble *MEDCouplingCMesh::computeIsoBarycenterOfNodesPerCell() const
746 return MEDCouplingCMesh::getBarycenterAndOwner();
749 void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check)
751 throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !");
754 void MEDCouplingCMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
757 double time=getTime(it,order);
760 littleStrings.clear();
761 littleStrings.push_back(getName());
762 littleStrings.push_back(getDescription());
763 littleStrings.push_back(getTimeUnit());
764 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
771 val=thisArr[i]->getNumberOfTuples();
772 st=thisArr[i]->getInfoOnComponent(0);
774 tinyInfo.push_back(val);
775 littleStrings.push_back(st);
777 tinyInfo.push_back(it);
778 tinyInfo.push_back(order);
779 tinyInfoD.push_back(time);
782 void MEDCouplingCMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
792 void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
794 a1=DataArrayInt::New();
796 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
801 sz+=thisArr[i]->getNumberOfTuples();
803 a2=DataArrayDouble::New();
805 double *a2Ptr=a2->getPointer();
808 a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr);
811 void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
812 const std::vector<std::string>& littleStrings)
814 setName(littleStrings[0]);
815 setDescription(littleStrings[1]);
816 setTimeUnit(littleStrings[2]);
817 DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
818 const double *data=a2->getConstPointer();
823 (*(thisArr[i]))=DataArrayDouble::New();
824 (*(thisArr[i]))->alloc(tinyInfo[i],1);
825 (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3]);
826 std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer());
830 setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]);
833 void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
835 std::ostringstream extent;
836 DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
840 { extent << "0 " << thisArr[i]->getNumberOfTuples()-1 << " "; }
842 { extent << "0 0 "; }
844 ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n";
845 ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
846 ofs << " <PointData>\n" << pointData << std::endl;
847 ofs << " </PointData>\n";
848 ofs << " <CellData>\n" << cellData << std::endl;
849 ofs << " </CellData>\n";
850 ofs << " <Coordinates>\n";
854 thisArr[i]->writeVTK(ofs,8,"Array",byteData);
857 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=DataArrayDouble::New(); coo->alloc(1,1);
859 coo->writeVTK(ofs,8,"Array",byteData);
862 ofs << " </Coordinates>\n";
863 ofs << " </Piece>\n";
864 ofs << " </" << getVTKDataSetType() << ">\n";
867 void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const
869 stream << "MEDCouplingCMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
870 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
871 std::ostringstream stream2[3];
873 int nbOfCells=1,nbOfNodes=1;
876 isDef[i]=thisArr[i]!=0;
880 stream2[i] << tmp << " positions array ";
881 if(!thisArr[i]->isAllocated())
882 stream2[i] << "set but not allocated.";
885 int nbCompo=thisArr[i]->getNumberOfComponents();
888 int nbTuples=thisArr[i]->getNumberOfTuples();
890 { stream2[i] << "set and allocated - WARNING number of elements < 1 !"; nbOfCells=-1; nbOfNodes=-1; }
893 stream2[i] << "(length=" << nbTuples << ")" << ": ";
894 thisArr[i]->reprQuickOverviewData(stream2[i],200);
896 { nbOfNodes*=nbTuples; nbOfCells*=nbTuples-1; }
900 { stream2[i] << "set and allocated - WARNING number of components != 1 !"; nbOfCells=-1; nbOfNodes=-1; }
904 if(!isDef[0] && !isDef[1] && !isDef[2])
905 { stream << " No arrays set !"; return; }
907 { stream << std::endl << "Number of cells : " << nbOfCells << ". Number of nodes : " << nbOfNodes << "."; }
911 stream << std::endl << stream2[i].str();
915 std::string MEDCouplingCMesh::getVTKFileExtension() const
917 return std::string("vtr");
920 std::string MEDCouplingCMesh::getVTKDataSetType() const
922 return std::string("RectilinearGrid");