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 MEDCouplingCurveLinearMesh *MEDCouplingCMesh::buildCurveLinear() const
104 checkConsistencyLight();
105 int dim(getSpaceDimension());
106 MCAuto<MEDCouplingCurveLinearMesh> ret(MEDCouplingCurveLinearMesh::New());
107 ret->MEDCouplingStructuredMesh::operator=(*this);
108 INTERP_KERNEL::AutoPtr<int> ngs(new int[dim]);
109 getNodeGridStructure(ngs);
110 ret->setNodeGridStructure(ngs,ngs+dim);
111 MCAuto<DataArrayDouble> coo(getCoordinatesAndOwner());
116 void MEDCouplingCMesh::updateTime() const
119 updateTimeWith(*_x_array);
121 updateTimeWith(*_y_array);
123 updateTimeWith(*_z_array);
126 std::size_t MEDCouplingCMesh::getHeapMemorySizeWithoutChildren() const
128 return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren();
131 std::vector<const BigMemoryObject *> MEDCouplingCMesh::getDirectChildrenWithNull() const
133 std::vector<const BigMemoryObject *> ret;
134 ret.push_back(_x_array);
135 ret.push_back(_y_array);
136 ret.push_back(_z_array);
141 * This method copyies all tiny strings from other (name and components name).
142 * @throw if other and this have not same mesh type.
144 void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other)
146 MEDCouplingStructuredMesh::copyTinyStringsFrom(other);
147 const MEDCouplingCMesh *otherC(dynamic_cast<const MEDCouplingCMesh *>(other));
149 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !");
150 if(_x_array && otherC->_x_array)
151 _x_array->copyStringInfoFrom(*otherC->_x_array);
152 if(_y_array && otherC->_y_array)
153 _y_array->copyStringInfoFrom(*otherC->_y_array);
154 if(_z_array && otherC->_z_array)
155 _z_array->copyStringInfoFrom(*otherC->_z_array);
158 bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const
161 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::isEqualIfNotWhy : input other pointer is null !");
162 const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
165 reason="mesh given in input is not castable in MEDCouplingCMesh !";
168 if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason))
170 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
171 const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
172 std::ostringstream oss; oss.precision(15);
175 if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0))
177 oss << "Only one CMesh between the two this and other has its coordinates of rank" << i << " defined !";
182 if(!thisArr[i]->isEqualIfNotWhy(*otherArr[i],prec,reason))
184 oss << "Coordinates DataArrayDouble of rank #" << i << " differ :";
185 reason.insert(0,oss.str());
192 bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
194 const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other);
197 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
198 const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array};
201 if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0))
204 if(!thisArr[i]->isEqualWithoutConsideringStr(*otherArr[i],prec))
210 void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
211 DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const
213 if(!isEqualWithoutConsideringStr(other,prec))
214 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalWith : Meshes are not the same !");
218 * Nothing is done here (except to check that the other is a MEDCoupling::MEDCouplingCMesh instance too).
219 * The user intend that the nodes are the same, so by construction of MEDCoupling::MEDCouplingCMesh, \a this and \a other are the same !
221 void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
222 DataArrayInt *&cellCor) const
224 if(!isEqualWithoutConsideringStr(other,prec))
225 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !");
228 void MEDCouplingCMesh::checkConsistencyLight() const
230 const char msg0[]="Invalid ";
231 const char msg1[]=" array ! Must contain more than 1 element.";
232 const char msg2[]=" array ! Must be with only one component.";
233 getSpaceDimension();// here to check that no holes in arrays !
236 if(_x_array->getNbOfElems()<2)
238 std::ostringstream os; os << msg0 << 'X' << msg1;
239 throw INTERP_KERNEL::Exception(os.str().c_str());
241 if(_x_array->getNumberOfComponents()!=1)
243 std::ostringstream os; os << msg0 << 'X' << msg2;
244 throw INTERP_KERNEL::Exception(os.str().c_str());
249 if(_y_array->getNbOfElems()<2)
251 std::ostringstream os; os << msg0 << 'Y' << msg1;
252 throw INTERP_KERNEL::Exception(os.str().c_str());
254 if(_y_array->getNumberOfComponents()!=1)
256 std::ostringstream os; os << msg0 << 'Y' << msg2;
257 throw INTERP_KERNEL::Exception(os.str().c_str());
262 if(_z_array->getNbOfElems()<2)
264 std::ostringstream os; os << msg0 << 'Z' << msg1;
265 throw INTERP_KERNEL::Exception(os.str().c_str());
267 if(_z_array->getNumberOfComponents()!=1)
269 std::ostringstream os; os << msg0 << 'Z' << msg2;
270 throw INTERP_KERNEL::Exception(os.str().c_str());
275 void MEDCouplingCMesh::checkConsistency(double eps) const
277 checkConsistencyLight();
279 _x_array->checkMonotonic(true, eps);
281 _y_array->checkMonotonic(true, eps);
283 _z_array->checkMonotonic(true, eps);
286 void MEDCouplingCMesh::getNodeGridStructure(int *res) const
288 std::vector<int> ret(getNodeGridStructure());
289 std::copy(ret.begin(),ret.end(),res);
292 std::vector<int> MEDCouplingCMesh::getNodeGridStructure() const
294 static const char MSG[]="MEDCouplingCMesh::getNodeGridStructure : mesh is invalid ! null vectors (X, Y or Z) must be put contiguously at the end !";
295 std::vector<int> ret;
299 if(!_x_array->isAllocated() || _x_array->getNumberOfComponents()!=1)
300 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : X array exits but it is not allocated or with nb of components equal to one !");
301 ret.push_back(_x_array->getNumberOfTuples());
307 if(!_y_array->isAllocated() || _y_array->getNumberOfComponents()!=1)
308 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Y array exits but it is not allocated or with nb of components equal to one !");
310 throw INTERP_KERNEL::Exception(MSG);
311 ret.push_back(_y_array->getNumberOfTuples());
317 if(!_z_array->isAllocated() || _z_array->getNumberOfComponents()!=1)
318 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Z array exits but it is not allocated or with nb of components equal to one !");
320 throw INTERP_KERNEL::Exception(MSG);
321 ret.push_back(_z_array->getNumberOfTuples());
326 MEDCouplingStructuredMesh *MEDCouplingCMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const
328 checkConsistencyLight();
329 int dim(getSpaceDimension());
330 if(dim!=(int)cellPart.size())
332 std::ostringstream oss; oss << "MEDCouplingCMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !";
333 throw INTERP_KERNEL::Exception(oss.str().c_str());
335 MCAuto<MEDCouplingCMesh> ret(dynamic_cast<MEDCouplingCMesh *>(deepCopy()));
336 for(int i=0;i<dim;i++)
338 MCAuto<DataArrayDouble> tmp(ret->getCoordsAt(i)->selectByTupleIdSafeSlice(cellPart[i].first,cellPart[i].second+1,1));
339 ret->setCoordsAt(i,tmp);
345 * Return the space dimension of \a this. It only considers the arrays along X, Y and Z to deduce that.
346 * 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.
348 int MEDCouplingCMesh::getSpaceDimension() const
350 return (int)getNodeGridStructure().size();
353 void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const
356 int spaceDim=getSpaceDimension();
357 getSplitNodeValues(tmp);
358 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
360 GetPosFromId(nodeId,spaceDim,tmp,tmp2);
361 for(int j=0;j<spaceDim;j++)
363 coo.push_back(tabs[j]->getConstPointer()[tmp2[j]]);
366 std::string MEDCouplingCMesh::simpleRepr() const
368 std::ostringstream ret;
369 ret << "Cartesian mesh with name : \"" << getName() << "\"\n";
370 ret << "Description of mesh : \"" << getDescription() << "\"\n";
372 double tt=getTime(tmpp1,tmpp2);
373 ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
374 ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n";
375 ret << "Space dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n";
378 ret << "X Array :\n";
379 _x_array->reprZipWithoutNameStream(ret);
383 ret << "Y Array :\n";
384 _y_array->reprZipWithoutNameStream(ret);
388 ret << "Z Array :\n";
389 _z_array->reprZipWithoutNameStream(ret);
394 std::string MEDCouplingCMesh::advancedRepr() const
400 * Returns a DataArrayDouble holding positions of nodes along a given axis.
401 * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage.
402 * \param [in] i - an index of axis, a value from [0,1,2].
403 * \return const DataArrayDouble * - a pointer to the data array of node coordinates
404 * referred by \a this mesh.
405 * \throw If \a i is not one of [0,1,2].
407 * \if ENABLE_EXAMPLES
408 * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br>
409 * \ref py_mccmesh_getCoordsAt "Here is a Python example".
412 const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const
423 throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
428 * Returns a DataArrayDouble holding positions of nodes along a given axis.
429 * For more info on Cartesian meshes, see \ref MEDCouplingCMeshPage.
430 * \param [in] i - an index of axis, a value from [0,1,2].
431 * \return const DataArrayDouble * - a pointer to the data array of node coordinates
432 * referred by \a this mesh.
433 * \throw If \a i is not one of [0,1,2].
435 * \if ENABLE_EXAMPLES
436 * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br>
437 * \ref py_mccmesh_getCoordsAt "Here is a Python example".
440 DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i)
451 throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
456 * Sets node coordinates along a given axis. For more info on Cartesian meshes, see
457 * \ref MEDCouplingCMeshPage.
458 * \param [in] i - an index of axis, a value in range [0,1,2].
459 * \param [in] arr - DataArrayDouble holding positions of nodes along the i-th
460 * axis. It must be an array of one component.
461 * \throw If \a arr->getNumberOfComponents() != 1.
462 * \throw If \a i is not one of [0,1,2].
464 * \if ENABLE_EXAMPLES
465 * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br>
466 * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example".
469 void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr)
472 arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt");
473 DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
475 throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
476 if(arr!=*(thisArr[i]))
479 (*(thisArr[i]))->decrRef();
480 (*(thisArr[i]))=const_cast<DataArrayDouble *>(arr);
482 (*(thisArr[i]))->incrRef();
488 * Sets node coordinates along some of the tree axes. This method updates all the
489 * three node coordinates arrays at once. For more info on Cartesian meshes, see
490 * \ref MEDCouplingCMeshPage.
491 * \param [in] coordsX - DataArrayDouble holding positions of nodes along the X
492 * axis. It must be an array of one component or \c NULL.
493 * \param [in] coordsY - DataArrayDouble holding positions of nodes along the Y
494 * axis. It must be an array of one component or \c NULL.
495 * \param [in] coordsZ - DataArrayDouble holding positions of nodes along the Z
496 * axis. It must be an array of one component or \c NULL.
497 * \throw If \a coords*->getNumberOfComponents() != 1.
499 * \if ENABLE_EXAMPLES
500 * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br>
501 * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example".
504 void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ)
507 coordsX->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsX");
509 coordsY->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsY");
511 coordsZ->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsZ");
514 _x_array=const_cast<DataArrayDouble *>(coordsX);
519 _y_array=const_cast<DataArrayDouble *>(coordsY);
524 _z_array=const_cast<DataArrayDouble *>(coordsZ);
530 void MEDCouplingCMesh::getBoundingBox(double *bbox) const
532 int dim=getSpaceDimension();
534 for (int idim=0; idim<dim; idim++)
536 const DataArrayDouble *c=getCoordsAt(idim);
539 const double *coords=c->getConstPointer();
540 int nb=c->getNbOfElems();
542 bbox[2*j+1]=coords[nb-1];
549 * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this
551 * For 1D cells, the returned field contains lengths.<br>
552 * For 2D cells, the returned field contains areas.<br>
553 * For 3D cells, the returned field contains volumes.
554 * \param [in] isAbs - a not used parameter.
555 * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on cells
556 * and one time . The caller is to delete this field using decrRef() as it is no
559 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const
561 std::string name="MeasureOfMesh_";
563 int nbelem=getNumberOfCells();
564 MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME);
565 field->setName(name);
566 DataArrayDouble* array=DataArrayDouble::New();
567 array->alloc(nbelem,1);
568 double *area_vol=array->getPointer();
569 field->setArray(array) ;
571 field->setMesh(const_cast<MEDCouplingCMesh *>(this));
572 field->synchronizeTimeWithMesh();
574 getSplitCellValues(tmp);
575 int dim=getSpaceDimension();
576 const double **thisArr=new const double *[dim];
577 const DataArrayDouble *thisArr2[3]={_x_array,_y_array,_z_array};
578 for(int i=0;i<dim;i++)
579 thisArr[i]=thisArr2[i]->getConstPointer();
580 for(int icell=0;icell<nbelem;icell++)
583 GetPosFromId(icell,dim,tmp,tmp2);
585 for(int i=0;i<dim;i++)
586 area_vol[icell]*=thisArr[i][tmp2[i]+1]-thisArr[i][tmp2[i]];
593 * not implemented yet !
595 MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) const
597 throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getMeasureFieldOnNode : not implemented yet !");
601 int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const
603 int dim=getSpaceDimension();
606 for(int i=0;i<dim;i++)
608 const double *d=getCoordsAt(i)->getConstPointer();
609 int nbOfNodes=getCoordsAt(i)->getNbOfElems();
611 const double *w=std::find_if(d,d+nbOfNodes,std::bind2nd(std::greater_equal<double>(),ref));
612 int w2=(int)std::distance(d,w);
631 void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle)
633 throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to untructured mesh to apply it !");
637 * Translates all nodes of \a this mesh by a given vector. Actually, it adds each
638 * component of the \a vector to all node coordinates of a corresponding axis.
639 * \param [in] vector - the translation vector whose size must be not less than \a
640 * this->getSpaceDimension().
642 void MEDCouplingCMesh::translate(const double *vector)
645 std::transform(_x_array->getConstPointer(),_x_array->getConstPointer()+_x_array->getNbOfElems(),
646 _x_array->getPointer(),std::bind2nd(std::plus<double>(),vector[0]));
648 std::transform(_y_array->getConstPointer(),_y_array->getConstPointer()+_y_array->getNbOfElems(),
649 _y_array->getPointer(),std::bind2nd(std::plus<double>(),vector[1]));
651 std::transform(_z_array->getConstPointer(),_z_array->getConstPointer()+_z_array->getNbOfElems(),
652 _z_array->getPointer(),std::bind2nd(std::plus<double>(),vector[2]));
656 * Applies scaling transformation to all nodes of \a this mesh.
657 * \param [in] point - coordinates of a scaling center. This array is to be of
658 * size \a this->getSpaceDimension() at least.
659 * \param [in] factor - a scale factor.
661 void MEDCouplingCMesh::scale(const double *point, double factor)
665 DataArrayDouble *c=getCoordsAt(i);
668 double *coords=c->getPointer();
669 int lgth=c->getNbOfElems();
670 std::transform(coords,coords+lgth,coords,std::bind2nd(std::minus<double>(),point[i]));
671 std::transform(coords,coords+lgth,coords,std::bind2nd(std::multiplies<double>(),factor));
672 std::transform(coords,coords+lgth,coords,std::bind2nd(std::plus<double>(),point[i]));
679 MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
681 //not implemented yet !
686 * Returns a new DataArrayDouble holding coordinates of all nodes of \a this mesh.
687 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
688 * this->getNumberOfNodes() tuples per \a this->getSpaceDimension()
689 * components. The caller is to delete this array using decrRef() as it is
692 DataArrayDouble *MEDCouplingCMesh::getCoordinatesAndOwner() const
694 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
695 int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes());
696 ret->alloc(nbNodes,spaceDim);
697 double *pt(ret->getPointer());
699 getSplitNodeValues(tmp);
700 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
701 const double *tabsPtr[3];
702 for(int j=0;j<spaceDim;j++)
704 tabsPtr[j]=tabs[j]->getConstPointer();
705 ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
708 for(int i=0;i<nbNodes;i++)
710 GetPosFromId(i,spaceDim,tmp,tmp2);
711 for(int j=0;j<spaceDim;j++)
712 pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
718 * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is
719 * computed by averaging coordinates of cell nodes.
720 * \return DataArrayDouble * - a new instance of DataArrayDouble, of size \a
721 * this->getNumberOfCells() tuples per \a this->getSpaceDimension()
722 * components. The caller is to delete this array using decrRef() as it is
725 DataArrayDouble *MEDCouplingCMesh::computeCellCenterOfMass() const
727 DataArrayDouble *ret=DataArrayDouble::New();
728 int spaceDim=getSpaceDimension();
729 int nbCells=getNumberOfCells();
730 ret->alloc(nbCells,spaceDim);
731 double *pt=ret->getPointer();
733 getSplitCellValues(tmp);
734 const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)};
735 std::vector<double> tabsPtr[3];
736 for(int j=0;j<spaceDim;j++)
738 int sz=tabs[j]->getNbOfElems()-1;
739 ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0));
740 const double *srcPtr=tabs[j]->getConstPointer();
741 tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz);
742 std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus<double>());
743 std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),tabsPtr[j].begin(),std::bind2nd(std::multiplies<double>(),0.5));
746 for(int i=0;i<nbCells;i++)
748 GetPosFromId(i,spaceDim,tmp,tmp2);
749 for(int j=0;j<spaceDim;j++)
750 pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]];
755 DataArrayDouble *MEDCouplingCMesh::computeIsoBarycenterOfNodesPerCell() const
757 return MEDCouplingCMesh::computeCellCenterOfMass();
760 void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check)
762 throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !");
765 void MEDCouplingCMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
768 double time=getTime(it,order);
771 littleStrings.clear();
772 littleStrings.push_back(getName());
773 littleStrings.push_back(getDescription());
774 littleStrings.push_back(getTimeUnit());
775 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
782 val=thisArr[i]->getNumberOfTuples();
783 st=thisArr[i]->getInfoOnComponent(0);
785 tinyInfo.push_back(val);
786 littleStrings.push_back(st);
788 tinyInfo.push_back(it);
789 tinyInfo.push_back(order);
790 tinyInfoD.push_back(time);
793 void MEDCouplingCMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
803 void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
805 a1=DataArrayInt::New();
807 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
812 sz+=thisArr[i]->getNumberOfTuples();
814 a2=DataArrayDouble::New();
816 double *a2Ptr=a2->getPointer();
819 a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr);
822 void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2,
823 const std::vector<std::string>& littleStrings)
825 setName(littleStrings[0]);
826 setDescription(littleStrings[1]);
827 setTimeUnit(littleStrings[2]);
828 DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
829 const double *data=a2->getConstPointer();
834 (*(thisArr[i]))=DataArrayDouble::New();
835 (*(thisArr[i]))->alloc(tinyInfo[i],1);
836 (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3]);
837 std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer());
841 setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]);
844 void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const
846 std::ostringstream extent;
847 DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
851 { extent << "0 " << thisArr[i]->getNumberOfTuples()-1 << " "; }
853 { extent << "0 0 "; }
855 ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n";
856 ofs << " <Piece Extent=\"" << extent.str() << "\">\n";
857 ofs << " <PointData>\n" << pointData << std::endl;
858 ofs << " </PointData>\n";
859 ofs << " <CellData>\n" << cellData << std::endl;
860 ofs << " </CellData>\n";
861 ofs << " <Coordinates>\n";
865 thisArr[i]->writeVTK(ofs,8,"Array",byteData);
868 MCAuto<DataArrayDouble> coo=DataArrayDouble::New(); coo->alloc(1,1);
870 coo->writeVTK(ofs,8,"Array",byteData);
873 ofs << " </Coordinates>\n";
874 ofs << " </Piece>\n";
875 ofs << " </" << getVTKDataSetType() << ">\n";
878 void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const
880 stream << "MEDCouplingCMesh C++ instance at " << this << ". Name : \"" << getName() << "\".";
881 const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array};
882 std::ostringstream stream2[3];
884 int nbOfCells=1,nbOfNodes=1;
887 isDef[i]=thisArr[i]!=0;
891 stream2[i] << tmp << " positions array ";
892 if(!thisArr[i]->isAllocated())
893 stream2[i] << "set but not allocated.";
896 int nbCompo=thisArr[i]->getNumberOfComponents();
899 int nbTuples=thisArr[i]->getNumberOfTuples();
901 { stream2[i] << "set and allocated - WARNING number of elements < 1 !"; nbOfCells=-1; nbOfNodes=-1; }
904 stream2[i] << "(length=" << nbTuples << ")" << ": ";
905 thisArr[i]->reprQuickOverviewData(stream2[i],200);
907 { nbOfNodes*=nbTuples; nbOfCells*=nbTuples-1; }
911 { stream2[i] << "set and allocated - WARNING number of components != 1 !"; nbOfCells=-1; nbOfNodes=-1; }
915 if(!isDef[0] && !isDef[1] && !isDef[2])
916 { stream << " No arrays set !"; return; }
918 { stream << std::endl << "Number of cells : " << nbOfCells << ". Number of nodes : " << nbOfNodes << "."; }
922 stream << std::endl << stream2[i].str();
926 std::string MEDCouplingCMesh::getVTKFileExtension() const
928 return std::string("vtr");
931 std::string MEDCouplingCMesh::getVTKDataSetType() const
933 return std::string("RectilinearGrid");