return true;
}
+/*!
+ * Checks if all values in \a this array are unique.
+ * \return bool - \a true if condition above is true
+ * \throw If \a this is not allocated.
+ * \throw If \a this->getNumberOfComponents() != 1
+ */
+bool DataArrayInt::hasUniqueValues() const
+{
+ checkAllocated();
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
+ int nbOfTuples(getNumberOfTuples());
+ std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
+ if (s.size() != nbOfTuples)
+ return false;
+ return true;
+}
+
/*!
* Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
* array to the new one.
MEDCOUPLING_EXPORT DataArrayInt *buildPermArrPerLevel() const;
MEDCOUPLING_EXPORT bool isIdentity2(int sizeExpected) const;
MEDCOUPLING_EXPORT bool isUniform(int val) const;
+ MEDCOUPLING_EXPORT bool hasUniqueValues() const;
MEDCOUPLING_EXPORT DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const;
MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo);
MEDCOUPLING_EXPORT void transpose();
da2.setIJ(1,0,1.+1.e-11);
self.assertTrue(not da2.isUniform(1.,1.e-12));
pass
+
+ def testDAHasUniqueValues1(self):
+ da=DataArrayInt([1,2,3,4,5])
+ self.assertTrue(da.hasUniqueValues())
+ da[1,0] = 5
+ self.assertFalse(da.hasUniqueValues())
+ da=DataArrayInt([])
+ self.assertTrue(da.hasUniqueValues())
+ da=DataArrayInt([(1,2), (2,3)]) # wrong num of compo
+ self.assertRaises(InterpKernelException, da.hasUniqueValues)
+ da=DataArrayInt() # non allocated array
+ self.assertRaises(InterpKernelException, da.hasUniqueValues)
+ pass
def testDADFromPolarToCart1(self):
tab1=[2.,0.2,2.5,0.7]
DataArrayInt *buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception);
bool isIdentity2(int sizeExpected) const throw(INTERP_KERNEL::Exception);
bool isUniform(int val) const throw(INTERP_KERNEL::Exception);
+ bool hasUniqueValues() const throw(INTERP_KERNEL::Exception);
DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception);
void transpose() throw(INTERP_KERNEL::Exception);
DataArrayInt *changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception);
return pd0->isEqual(pd1,what);
}
+/*!
+ * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
+ * nodes and cells. This last item is important for SMESH, see checkSMESHCoherency().
+ * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
+ * \throw if internal family array is inconsistent
+ * \sa checkSMESHCoherency()
+ */
+void MEDFileUMesh::checkCoherency() const
+{
+ if(!_coords || !_coords->isAllocated())
+ {
+ if(!_ms.size())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkCoherency(): coords are null but some mesh parts are present!");
+ if (!_fam_coords)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkCoherency(): coords are null but not the internal node family array!");
+ if (!_num_coords || !_rev_num_coords)
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkCoherency(): coords are null but not the internal node numbering array!");
+ }
+ else
+ {
+ int nbCoo = _coords->getNumberOfTuples();
+ if (_fam_coords)
+ _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkCoherency(): inconsistent internal node family array!");
+ if (_num_coords)
+ {
+ _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkCoherency(): inconsistent internal node numbering array!");
+ int pos;
+ int maxValue=_num_coords->getMaxValue(pos);
+ if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkCoherency(): inconsistent internal revert node numbering array!");
+ }
+ if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkCoherency(): inconsistent internal numbering arrays (one is null)!");
+ if (_num_coords && !_num_coords->hasUniqueValues())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkCoherency(): inconsistent internal node numbering array: duplicates found!");
+ if (_name_coords)
+ _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkCoherency(): inconsistent internal coord name array!");
+ // Now sub part check:
+ for (std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
+ it != _ms.end(); it++)
+ (*it)->checkCoherency();
+ }
+}
+
+/**
+ * Same as checkCoherency() but also checks that optional entities (edges, faces, volumes) numbers are
+ * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
+ * entities as it likes), or non overlapping between all sub-levels.
+ * \throw if the condition above is not respected
+ */
+void MEDFileUMesh::checkSMESHCoherency() const
+{
+ checkCoherency();
+ // For all sub-levels, numbering is either always null or with void intersection:
+ if (_ms.size())
+ {
+ std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
+ std::vector< const DataArrayInt * > v;
+ bool voidOrNot = ((*it)->_num == 0);
+ for (it++; it != _ms.end(); it++)
+ if( ((*it)->_num == 0) != voidOrNot )
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkCoherency(): inconsistent numbering between mesh sub-levels!");
+ else if (!voidOrNot)
+ v.push_back((*it)->_num);
+ if (!voidOrNot)
+ {
+ // don't forget the 1st one:
+ v.push_back(_ms[0]->_num);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
+ if (inter->getNumberOfTuples())
+ throw INTERP_KERNEL::Exception("MEDFileUMesh::checkCoherency(): overlapping entity numbering between mesh sub-levels!");
+ }
+ }
+}
+
+/**
+ * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
+ * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
+ */
+void MEDFileUMesh::clearNodeAndCellNumbers()
+{
+ _num_coords = 0;
+ _rev_num_coords = 0;
+ for (std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
+ it != _ms.end(); it++)
+ {
+ (*it)->_num = 0;
+ (*it)->_rev_num = 0;
+ }
+}
+
/*!
* Clears redundant attributes of incorporated data arrays.
*/
* other side of the group is no more a neighbor)
* - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
* bordering the newly created boundary use the newly computed nodes.
+ * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
+ * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
*
* \param[in] grpNameM1 name of the (-1)-level group defining the boundary
* \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
* the coord array)
* \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
* \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
+ * \sa clearNodeAndCellNumbers()
*/
void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
_fam_coords=newFam;
}
+
nodesDuplicated=nodeIdsToDuplicate.retn();
cellsModified=cellsToModifyConn0.retn();
cellsNotModified=cellsToModifyConn1.retn();
MEDLOADER_EXPORT MEDFileMesh *deepCpy() const;
MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const;
MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const;
+ MEDLOADER_EXPORT void checkCoherency() const;
+ MEDLOADER_EXPORT void checkSMESHCoherency() const;
+ MEDLOADER_EXPORT void clearNodeAndCellNumbers();
MEDLOADER_EXPORT void clearNonDiscrAttributes() const;
MEDLOADER_EXPORT void setName(const std::string& name);
//
return ret.retn();
}
+void MEDFileUMeshSplitL1::checkCoherency() const
+{
+ if (!_fam || _fam->getNumberOfTuples() != getSize())
+ throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::checkCoherency(): internal family array has an invalid size!");
+ int nbCells = getSize();
+ if (_num)
+ {
+ _num->checkNbOfTuplesAndComp(nbCells,1,"MEDFileUMeshSplitL1::checkCoherency(): inconsistent internal node numbering array!");
+ int pos;
+ int maxValue=_num->getMaxValue(pos);
+ if (!_rev_num || _rev_num->getNumberOfTuples() != (maxValue+1))
+ throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::checkCoherency(): inconsistent internal revert node numbering array!");
+ }
+ if ((_num && !_rev_num) || (!_num && _rev_num))
+ throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::checkCoherency(): inconsistent internal numbering arrays (one is null)!");
+ if (_num && !_num->hasUniqueValues())
+ throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::checkCoherency(): inconsistent internal node numbering array: duplicates found!");
+ if (_names)
+ _names->checkNbOfTuplesAndComp(nbCells,1,"MEDFileUMeshSplitL1::checkCoherency(): internal cell naming array has an invalid size!");
+
+ _m_by_types.checkCoherency();
+}
+
bool MEDFileUMeshSplitL1::isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const
{
if(!_m_by_types.isEqual(other->_m_by_types,eps,what))
return true;
}
+void MEDFileUMeshAggregateCompute::checkCoherency() const
+{
+ if(_mp_time >= _m_time)
+ for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();
+ it!=_m_parts.end(); it++)
+ (*it)->checkCoherency1();
+ else
+ _m->checkCoherency1();
+}
+
void MEDFileUMeshAggregateCompute::clearNonDiscrAttributes() const
{
for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++)
MEDFileUMeshAggregateCompute deepCpy(DataArrayDouble *coords) const;
void shallowCpyMeshes();
bool isEqual(const MEDFileUMeshAggregateCompute& other, double eps, std::string& what) const;
+ void checkCoherency() const;
void clearNonDiscrAttributes() const;
void synchronizeTinyInfo(const MEDFileMesh& master) const;
bool empty() const;
class MEDFileUMeshSplitL1 : public RefCountObject
{
friend class MEDFileUMeshPermCompute;
+ friend class MEDFileUMesh;
public:
MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other);
MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const std::string& mName, int id);
std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
MEDFileUMeshSplitL1 *shallowCpyUsingCoords(DataArrayDouble *coords) const;
MEDFileUMeshSplitL1 *deepCpy(DataArrayDouble *coords) const;
+ void checkCoherency() const;
void setCoords(DataArrayDouble *coords);
bool isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const;
void clearNonDiscrAttributes() const;
~MEDFileUMesh();
int getSpaceDimension() const throw(INTERP_KERNEL::Exception);
int getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception);
+ void checkCoherency() const throw(INTERP_KERNEL::Exception);
+ void checkSMESHCoherency() const throw(INTERP_KERNEL::Exception);
+ void clearNodeAndCellNumbers();
//
MEDCouplingUMesh *getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const throw(INTERP_KERNEL::Exception);
MEDCouplingUMesh *getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception);
self.assertTrue(mm.getHiddenCppPointer()==mm2.getHiddenCppPointer()) # optimization
pass
+ def testCheckCoherency(self):
+ m2 = MEDCouplingUMesh("2d", 2)
+ m2.setCoords(DataArrayDouble([(0.0, 1.0)] * 4, 4,2)) # whatever
+ m2.setConnectivity(DataArrayInt([NORM_TRI3, 0,1,2,NORM_TRI3, 1,2,3]), DataArrayInt(([0,4,8])))
+ m1 , _, _ , _, _ = m2.buildDescendingConnectivity()
+ mum = MEDFileUMesh()
+ mum.setMeshAtLevel(0, m2)
+ mum.setMeshAtLevel(-1, m1)
+ mum.checkCoherency()
+ mum2 = mum.deepCpy()
+
+ # Nodes
+ arr = DataArrayInt([2]*4)
+ mum.setFamilyFieldArr(1, arr); arr.reAlloc(35);
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+ mum=mum2; mum2=mum.deepCpy();
+ arr = DataArrayInt([2]*4)
+ mum.setRenumFieldArr(1, arr); arr.reAlloc(35);
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+ mum=mum2; mum2=mum.deepCpy();
+ mum.setRenumFieldArr(1, DataArrayInt([2]*4))
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+ mum=mum2; mum2=mum.deepCpy();
+ arr = DataArrayAsciiChar(['tutu x']*4)
+ mum.setNameFieldAtLevel(1, arr); arr.reAlloc(35);
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+
+ # 2D
+ mum=mum2; mum2=mum.deepCpy();
+ arr = DataArrayInt([2]*2)
+ mum.setFamilyFieldArr(0, arr); arr.reAlloc(35);
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+ mum=mum2; mum2=mum.deepCpy();
+ arr = DataArrayInt([2]*2)
+ mum.setRenumFieldArr(0, arr); arr.reAlloc(35);
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+ mum=mum2; mum2=mum.deepCpy();
+ mum.setRenumFieldArr(0, DataArrayInt([2]*2))
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+ mum=mum2; mum2=mum.deepCpy();
+ arr = DataArrayAsciiChar(['tutu x']*2)
+ mum.setNameFieldAtLevel(0, arr); arr.reAlloc(35);
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+
+ # 1D
+ mum=mum2; mum2=mum.deepCpy();
+ arr = DataArrayInt([2]*5)
+ mum.setFamilyFieldArr(-1, arr); arr.reAlloc(35);
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+ mum=mum2; mum2=mum.deepCpy();
+ arr = DataArrayInt([2]*5)
+ mum.setRenumFieldArr(-1, arr); arr.reAlloc(35);
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+ mum=mum2; mum2=mum.deepCpy();
+ mum.setRenumFieldArr(-1, DataArrayInt([2]*5))
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+ mum=mum2; mum2=mum.deepCpy();
+ arr = DataArrayAsciiChar(['tutu x']*5)
+ mum.setNameFieldAtLevel(-1, arr); arr.reAlloc(35);
+ self.assertRaises(InterpKernelException, mum.checkCoherency)
+
+ def testCheckSMESHCoherency(self):
+ m2 = MEDCouplingUMesh("2d", 2)
+ m2.setCoords(DataArrayDouble([(0.0, 1.0)] * 4, 4,2)) # whatever
+ m2.setConnectivity(DataArrayInt([NORM_TRI3, 0,1,2,NORM_TRI3, 1,2,3]), DataArrayInt(([0,4,8])))
+ m1 , _, _ , _, _ = m2.buildDescendingConnectivity()
+ mum = MEDFileUMesh()
+ mum.setMeshAtLevel(0, m2)
+ mum.setMeshAtLevel(-1, m1)
+ mum.checkCoherency()
+ mum.checkSMESHCoherency()
+ n2 = DataArrayInt(m2.getNumberOfCells(), 1); n2.iota(1)
+ n1 = DataArrayInt(m1.getNumberOfCells(), 1); n1.iota(1)
+ mum.setRenumFieldArr(0, n2)
+ mum.setRenumFieldArr(-1, n1)
+ self.assertRaises(InterpKernelException, mum.checkSMESHCoherency)
+ mum.setRenumFieldArr(-1, n1+100)
+ mum.checkSMESHCoherency()
+ pass
+
+ def testClearNodeAndCellNumbers(self):
+ m2 = MEDCouplingUMesh("2d", 2)
+ m2.setCoords(DataArrayDouble([(0.0, 1.0)] * 4, 4,2)) # whatever
+ m2.setConnectivity(DataArrayInt([NORM_TRI3, 0,1,2,NORM_TRI3, 1,2,3]), DataArrayInt(([0,4,8])))
+ m1 , _, _ , _, _ = m2.buildDescendingConnectivity()
+ mum = MEDFileUMesh()
+ mum.setMeshAtLevel(0, m2)
+ mum.setMeshAtLevel(-1, m1)
+ mum.checkCoherency()
+ n2 = DataArrayInt(m2.getNumberOfCells(), 1); n2.iota(1)
+ n1 = DataArrayInt(m1.getNumberOfCells(), 1); n1.iota(1)
+ mum.setRenumFieldArr(0, n2)
+ mum.setRenumFieldArr(-1, n1)
+ mum.clearNodeAndCellNumbers()
+ mum.checkSMESHCoherency()
+ pass
+
pass
if __name__ == "__main__":