From: vsr Date: Fri, 15 Mar 2013 14:30:06 +0000 (+0000) Subject: Merge from V6_main 15/03/2013 X-Git-Tag: V7_3_1b1~463 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=0511285d155a0682ff6dad10ac916ac53f577476;p=tools%2Fmedcoupling.git Merge from V6_main 15/03/2013 --- diff --git a/doc/doxygen/Doxyfile_med_user.in b/doc/doxygen/Doxyfile_med_user.in index 29b43e3d7..e8f187713 100644 --- a/doc/doxygen/Doxyfile_med_user.in +++ b/doc/doxygen/Doxyfile_med_user.in @@ -71,6 +71,7 @@ WARN_LOGFILE = log_user #--------------------------------------------------------------------------- INPUT = @builddir@ \ @srcdir@ \ + @srcdir@/fakesources \ @srcdir@/../../src/ParaMEDMEM \ @srcdir@/../../src/INTERP_KERNEL \ @srcdir@/../../src/INTERP_KERNEL/Bases \ @@ -91,7 +92,7 @@ FILE_PATTERNS = MEDMEM_GMesh.* \ OverlapDEC.* \ DEC.* \ DisjointDEC.* \ - MPIProcessorGroup.* \ + MPIProcessorGroup.* \ StructuredCoincidentDEC.* \ ExplicitCoincidentDEC.* \ NonCoincidentDEC.* \ diff --git a/doc/doxygen/fakesources/MEDCouplingMemArray.C b/doc/doxygen/fakesources/MEDCouplingMemArray.C new file mode 100644 index 000000000..977a3a15b --- /dev/null +++ b/doc/doxygen/fakesources/MEDCouplingMemArray.C @@ -0,0 +1,595 @@ +// This file contains some code used for +// 1) generation of documentation for inline methods of array classes +// 2) grouping all methods into 3 lists" "Basic API", "Advanced API" and "Others..." + +/* class ParaMEDMEM::DataArray + * @defgroup basic_api Basic API + * @defgroup adv_api Advanced API + */ + +namespace ParaMEDMEM +{ +/*! + * Returns the attribute \a _name of \a this array. + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. + * \return std::string - array name + */ +std::string DataArray::getName() const {} + +/*! + * Returns number of components of \a this array. + * See \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. + * \return int - number of components + */ +int DataArray::getNumberOfComponents() const {} + +/*! + * Returns number of tuples of \a this array. + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. + * \return int - number of tuples + */ +int DataArray::getNumberOfTuples() const {} + +/*! + * Returns number of elements of \a this array. + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. + * \return int - number of elements == this->getNumberOfTuples() * + * this->getNumberOfComponents() + */ +int DataArray::getNbOfElems() const {} + +/*! + * Throws an exception if number of elements in \a this array differs from a given one. + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. + * \param [in] nbOfElems - expected array size. + * \param [in] msg - message to return within the thrown exception. + * \throw if this->getNbOfElems() != nbOfElems. + */ +void DataArray::checkNbOfElems(int nbOfElems, const char *msg) const {} + +/*! + * Returns values of a specified tuple. + * \param [in] tupleId - index of the tuple of interest. + * \param [out] res - C array returning values of the \a tupleId-th tuple. The \a res + * must be allocated by the caller and be of size not less than \a + * this->getNumberOfComponents(). + */ +void DataArrayDouble::getTuple(int tupleId, double *res) const {} + +/*! + * Returns a value of a specified element of \a this array. + * \param [in] tupleId - index of the tuple of interest. + * \param [in] compoId - index of the component of interest. + * \return double - the value of \a compoId-th component of \a tupleId-th tuple. + */ +double DataArrayDouble::getIJ(int tupleId, int compoId) const {} + +/*! + * Returns a pointer to the first element of the raw data of \a this array. + * \return double* - the pointer to the value of 0-th tuple and 0-th component. + */ +double * DataArrayDouble::getPointer() {} + +/*! + * Returns a const pointer to the first element of the raw data of \a this array. + * \return const double* - the pointer to the value of 0-th tuple and 0-th component. + */ +const double * DataArrayDouble::getConstPointer() const {} + +/*! + * Assigns a given value to a specified element of \a this array. + * \param [in] tupleId - index of the tuple to modify. + * \param [in] compoId - index of the component to modify. + * \param [in] newVal - the value to assign to the value at \a compoId-th component + * of \a tupleId-th tuple. + */ +void DataArrayDouble::setIJ(int tupleId, int compoId, double newVal) {} + +/*! + * Assigns a given value to a specified element of \a this array which is not marked + * as changed. + * \param [in] tupleId - index of the tuple to modify. + * \param [in] compoId - index of the component to modify. + * \param [in] newVal - the value to assign to the value at \a compoId-th component + * of \a tupleId-th tuple. + */ +void DataArrayDouble::setIJSilent(int tupleId, int compoId, double newVal) {} + +/*! + * Copies values from another array starting from a specified element of \a this. + * \param [in] id - index of element to assign the value \a element0 to. + * \param [in] element0 - value to assign to the \a id-th element of \a this. + * \param [in] others - values to assign to elements following the \a id-th + * element of \a this. + * \param [in] sizeOfOthers - number of values to copy from \a others. + */ +void DataArrayDouble::writeOnPlace(int id, double element0, const double *others, int sizeOfOthers) {} + +/*! + * Does nothing because this class does not aggregate any TimeLabel instance. + */ +void DataArrayDouble::updateTime() const {} + +/*! + * Returns values of a specified tuple. + * \param [in] tupleId - index of the tuple of interest. + * \param [out] res - C array returning values of the \a tupleId-th tuple. The \a res + * must be allocated by the caller and be of size not less than \a + * this->getNumberOfComponents(). + * + * \ref py_mcdataarrayint_getTuple "Here is a Python example". + */ +void DataArrayInt::getTuple(int tupleId, int *res) const {} + +/*! + * Returns a value of a specified element of \a this array. + * \param [in] tupleId - index of the tuple of interest. + * \param [in] compoId - index of the component of interest. + * \return int - the value of \a compoId-th component of \a tupleId-th tuple. + */ +int DataArrayInt::getIJ(int tupleId, int compoId) const {} + + +/*! + * Assigns a given value to a specified element of \a this array. + * \param [in] tupleId - index of the tuple to modify. + * \param [in] compoId - index of the component to modify. + * \param [in] newVal - the value to assign to the value at \a compoId-th component + * of \a tupleId-th tuple. + * \warning As this method declares \a this array as modified, it is more optimal to use + * setIJSilent() for modification of muliple values of array and to call + * declareAsNew() after the modification is done. + */ +void DataArrayInt::setIJ(int tupleId, int compoId, int newVal) {} + + +/*! + * Assigns a given value to a specified element of \a this array which is \b not marked + * as changed. + * \param [in] tupleId - index of the tuple to modify. + * \param [in] compoId - index of the component to modify. + * \param [in] newVal - the value to assign to the value at \a compoId-th component + * of \a tupleId-th tuple. + */ +void DataArrayInt::setIJSilent(int tupleId, int compoId, int newVal) {} + +/*! + * Returns a pointer to the first element of the raw data of \a this array. + * \return int* - the pointer to the value of 0-th tuple and 0-th component. + */ +int * DataArrayInt::getPointer() {} + +/*! + * Returns a const pointer to the first element of the raw data of \a this array. + * \return const int* - the pointer to the value of 0-th tuple and 0-th component. + */ +const int * DataArrayInt::getConstPointer() const {} + +/*! + * Copies values from another array starting from a given element of \a this. + * \param [in] id - index of element to assign the value \a element0 to. + * \param [in] element0 - value to assign to the \a id-th element of \a this. + * \param [in] others - values to assign to elements following the \a id-th + * element of \a this. + * \param [in] sizeOfOthers - number of values to copy from \a others. + */ +void DataArrayInt::writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) {} + +} + +namespace ParaMEDMEM +{ +//================================================================================ +/////////////////////// DataArray GROUPPING ////////////////////////////////////// +//================================================================================ + +/*! \name Basic API */ +///@{ +DataArray::setName(const char *name); +DataArray::copyStringInfoFrom(const DataArray& other); +DataArray::areInfoEquals(const DataArray& other) const; +DataArray::getName() const; +DataArray::setInfoOnComponents(const std::vector& info); +DataArray::getVarOnComponent(int i) const; +DataArray::getUnitOnComponent(int i) const; +DataArray::setInfoOnComponent(int i, const char *info); +DataArray::getNumberOfComponents() const; +DataArray::getNumberOfTuples() const; +DataArray::getNbOfElems() const; +DataArray::checkNbOfElems(int nbOfElems, const char *msg) const; +DataArray::GetVarNameFromInfo(const std::string& info); +DataArray::GetUnitFromInfo(const std::string& info); +///@} + +/*! \name Others... */ +///@{ +DataArray::getHeapMemorySize() const; +DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds); +DataArray::copyPartOfStringInfoFrom2(const std::vector& compoIds, const DataArray& other); +DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const; +DataArray::reprWithoutNameStream(std::ostream& stream) const; +DataArray::cppRepr(const char *varName) const; +DataArray::getInfoOnComponents() const; +DataArray::getInfoOnComponents(); +DataArray::getVarsOnComponent() const; +DataArray::getUnitsOnComponent() const; +DataArray::getInfoOnComponent(int i) const; +DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const; +DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const; +DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception); +DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception); +DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg); +DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg); +DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step); +DataArray::reprCppStream(const char *varName, std::ostream& stream) const; +DataArray::DataArray(); +DataArray::CheckValueInRange(int ref, int value, const char *msg); +DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg); +DataArray::CheckClosingParInRange(int ref, int value, const char *msg); +std::string DataArray::_name; +std::vector DataArray::_info_on_compo; +///@} + +//================================================================================ +/////////////////////// DataArrayDouble GROUPPING //////////////////////////////// +//================================================================================ + +/*! \name Basic API */ +///@{ +DataArrayDouble::isAllocated() const; +DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector& info); +DataArrayDouble::doubleValue() const; +DataArrayDouble::empty() const; +DataArrayDouble::deepCpy() const; +DataArrayDouble::performCpy(bool deepCpy) const; +DataArrayDouble::cpyFrom(const DataArrayDouble& other); +DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo); +DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo); +DataArrayDouble::fillWithZero(); +DataArrayDouble::fillWithValue(double val); +DataArrayDouble::iota(double init=0.); +DataArrayDouble::isUniform(double val, double eps) const; +DataArrayDouble::sort(bool asc=true); +DataArrayDouble::reverse(); +DataArrayDouble::checkMonotonic(bool increasing, double eps) const; +DataArrayDouble::isMonotonic(bool increasing, double eps) const; +DataArrayDouble::repr() const; +DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const; +DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const; +DataArrayDouble::reAlloc(int nbOfTuples); +DataArrayDouble::convertToIntArr() const; +DataArrayDouble::fromNoInterlace() const; +DataArrayDouble::toNoInterlace() const; +DataArrayDouble::renumberInPlace(const int* old2New); +DataArrayDouble::renumberInPlaceR(const int* new2Old); +DataArrayDouble::renumber(const int* old2New) const; +DataArrayDouble::renumberR(const int* new2Old) const; +DataArrayDouble::renumberAndReduce(const int* old2New, int newNbOfTuple) const; +DataArrayDouble::selectByTupleId(const int* new2OldBg, const int* new2OldEnd) const; +DataArrayDouble::selectByTupleIdSafe(const int* new2OldBg, const int* new2OldEnd) const; +DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const; +DataArrayDouble::selectByTupleRanges(const std::vector >& ranges) const; +DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd=-1) const; +DataArrayDouble::rearrange(int newNbOfCompo); +DataArrayDouble::transpose(); +DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const; +DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const; +DataArrayDouble::meldWith(const DataArrayDouble* other); +DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; +DataArrayDouble::getDifferentValues(double prec, int limitTupleId=-1) const; +DataArrayDouble::setSelectedComponents(const DataArrayDouble* a, const std::vector& compoIds); +DataArrayDouble::setPartOfValues1(const DataArrayDouble* a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); +DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); +DataArrayDouble::setPartOfValues2(const DataArrayDouble* a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); +DataArrayDouble::setPartOfValuesSimple2(double a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp); +DataArrayDouble::setPartOfValues3(const DataArrayDouble* a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); +DataArrayDouble::setPartOfValuesSimple3(double a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp); +DataArrayDouble::getTuple(int tupleId, double* res) const; +DataArrayDouble::getIJ(int tupleId, int compoId) const; +DataArrayDouble::back() const; +DataArrayDouble::getIJSafe(int tupleId, int compoId) const; +DataArrayDouble::setIJ(int tupleId, int compoId, double newVal); +DataArrayDouble::setIJSilent(int tupleId, int compoId, double newVal); +DataArrayDouble::useExternalArrayWithRWAccess(const double* array, int nbOfTuple, int nbOfCompo); +DataArrayDouble::writeOnPlace(int id, double element0, const double* others, int sizeOfOthers); +DataArrayDouble::checkNoNullValues() const; +DataArrayDouble::getMinMaxPerComponent(double* bounds) const; +DataArrayDouble::getMaxValue(int& tupleId) const; +DataArrayDouble::getMaxValueInArray() const; +DataArrayDouble::getMinValue(int& tupleId) const; +DataArrayDouble::getMinValueInArray() const; +DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const; +DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const; +DataArrayDouble::getAverageValue() const; +DataArrayDouble::norm2() const; +DataArrayDouble::normMax() const; +DataArrayDouble::accumulate(double* res) const; +DataArrayDouble::accumulate(int compId) const; +DataArrayDouble::fromPolarToCart() const; +DataArrayDouble::fromCylToCart() const; +DataArrayDouble::fromSpherToCart() const; +DataArrayDouble::doublyContractedProduct() const; +DataArrayDouble::determinant() const; +DataArrayDouble::eigenValues() const; +DataArrayDouble::eigenVectors() const; +DataArrayDouble::inverse() const; +DataArrayDouble::trace() const; +DataArrayDouble::deviator() const; +DataArrayDouble::magnitude() const; +DataArrayDouble::maxPerTuple() const; +DataArrayDouble::sortPerTuple(bool asc); +DataArrayDouble::abs(); +DataArrayDouble::applyLin(double a, double b, int compoId); +DataArrayDouble::applyLin(double a, double b); +DataArrayDouble::applyInv(double numerator); +DataArrayDouble::negate() const; +DataArrayDouble::applyFunc(int nbOfComp, const char* func) const; +DataArrayDouble::applyFunc(const char* func) const; +DataArrayDouble::applyFunc2(int nbOfComp, const char* func) const; +DataArrayDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const char* func) const; +DataArrayDouble::getIdsInRange(double vmin, double vmax) const; +DataArrayDouble::addEqual(const DataArrayDouble* other); +DataArrayDouble::substractEqual(const DataArrayDouble* other); +DataArrayDouble::multiplyEqual(const DataArrayDouble* other); +DataArrayDouble::divideEqual(const DataArrayDouble* other); +DataArrayDouble::updateTime() const; +DataArrayDouble::New(); +DataArrayDouble::Aggregate(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Aggregate(const std::vector& arr); +DataArrayDouble::Meld(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Meld(const std::vector& arr); +DataArrayDouble::Dot(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::CrossProduct(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Max(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Min(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Add(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Substract(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Multiply(const DataArrayDouble* a1, const DataArrayDouble* a2); +DataArrayDouble::Divide(const DataArrayDouble* a1, const DataArrayDouble* a2); +///@} + +/*! \name Advanced API */ +///@{ +DataArrayDouble::checkAllocated() const; +DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble* a, const DataArrayInt* tuplesSelec); +DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble* a, const DataArrayInt* tuplesSelec); +DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble* a, int bg, int end2, int step); +DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const; +///@} + +/*! \name Others... */ +///@{ +DataArrayDouble::getNumberOfTuples() const; +DataArrayDouble::getNbOfElems() const; +DataArrayDouble::getHeapMemorySize() const; +DataArrayDouble::reserve(int nbOfElems); +DataArrayDouble::pushBackSilent(double val); +DataArrayDouble::popBackSilent(); +DataArrayDouble::pack() const; +DataArrayDouble::getNbOfElemAllocated() const; +DataArrayDouble::reprZip() const; +DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char* nameInFile) const; +DataArrayDouble::reprStream(std::ostream& stream) const; +DataArrayDouble::reprZipStream(std::ostream& stream) const; +DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const; +DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const; +DataArrayDouble::reprCppStream(const char* varName, std::ostream& stream) const; +DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const; +DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const; +DataArrayDouble::setPartOfValues4(const DataArrayDouble* a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); +DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp); +DataArrayDouble::getPointer(); +DataArrayDouble::SetArrayIn(DataArrayDouble* newArray, DataArrayDouble* &arrayToSet); +DataArrayDouble::iterator(); +DataArrayDouble::getConstPointer() const; +DataArrayDouble::begin() const; +DataArrayDouble::end() const; +DataArrayDouble::useArray(const double* array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); +DataArrayDouble::insertAtTheEnd(InputIterator first, InputIterator last); +DataArrayDouble::computeBBoxPerTuple(double epsilon=0.0) const; +DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble* other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const; +DataArrayDouble::recenterForMaxPrecision(double eps); +DataArrayDouble::distanceToTuple(const double* tupleBg, const double* tupleEnd, int& tupleId) const; +DataArrayDouble::buildEuclidianDistanceDenseMatrix() const; +DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble* other) const; +DataArrayDouble::applyFuncFast32(const char* func); +DataArrayDouble::applyFuncFast64(const char* func); +DataArrayDouble::getTinySerializationIntInformation(std::vector& tinyInfo) const; +DataArrayDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const; +DataArrayDouble::resizeForUnserialization(const std::vector& tinyInfoI); +DataArrayDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); + +DataArrayDouble::findCommonTuplesAlg(const double* bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt* c, DataArrayInt* cI) const; + +DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree& myTree, const double* pos, int nbOfTuples, double eps, DataArrayInt* c, DataArrayInt* cI); +DataArrayDouble::DataArrayDouble(); +MemArray DataArrayDouble::_mem; +///@} + +//================================================================================ +/////////////////////// DataArrayInt GROUPPING /////////////////////////////////// +//================================================================================ + +/*! \name Advanced API */ +///@{ +DataArrayInt::checkAllocated() const; +DataArrayInt::getHashCode() const; +DataArrayInt::buildPermutationArr(const DataArrayInt& other) const; +DataArrayInt::transformWithIndArr(const int* indArrBg, const int* indArrEnd); +DataArrayInt::transformWithIndArrR(const int* indArrBg, const int* indArrEnd) const; +DataArrayInt::splitByValueRange(const int* arrBg, const int* arrEnd,DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const; +DataArrayInt::setPartOfValuesAdv(const DataArrayInt* a, const DataArrayInt* tuplesSelec); +DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt* tuplesSelec); +DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt* a, int bg, int end2, int step); +DataArrayInt::SetArrayIn(DataArrayInt* newArray, DataArrayInt* &arrayToSet); +///@} + +/*! \name Basic API */ +///@{ +DataArrayInt::isAllocated() const; +DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector& info); +DataArrayInt::intValue() const; +DataArrayInt::empty() const; +DataArrayInt::deepCpy() const; +DataArrayInt::performCpy(bool deepCpy) const; +DataArrayInt::cpyFrom(const DataArrayInt& other); +DataArrayInt::alloc(int nbOfTuple, int nbOfCompo); +DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo); +DataArrayInt::isEqual(const DataArrayInt& other) const; +DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const; +DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const; +DataArrayInt::sort(bool asc=true); +DataArrayInt::reverse(); +DataArrayInt::fillWithZero(); +DataArrayInt::fillWithValue(int val); +DataArrayInt::iota(int init=0); +DataArrayInt::repr() const; +DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const; +DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const; +DataArrayInt::reAlloc(int nbOfTuples); +DataArrayInt::convertToDblArr() const; +DataArrayInt::fromNoInterlace() const; +DataArrayInt::toNoInterlace() const; +DataArrayInt::renumberInPlace(const int* old2New); +DataArrayInt::renumberInPlaceR(const int* new2Old); +DataArrayInt::renumber(const int* old2New) const; +DataArrayInt::renumberR(const int* new2Old) const; +DataArrayInt::renumberAndReduce(const int* old2NewBg, int newNbOfTuple) const; +DataArrayInt::selectByTupleId(const int* new2OldBg, const int* new2OldEnd) const; +DataArrayInt::selectByTupleIdSafe(const int* new2OldBg, const int* new2OldEnd) const; +DataArrayInt::selectByTupleId2(int bg, int end, int step) const; +DataArrayInt::selectByTupleRanges(const std::vector >& ranges) const; +DataArrayInt::checkAndPreparePermutation() const; +DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const; +DataArrayInt::buildPermArrPerLevel() const; +DataArrayInt::isIdentity() const; +DataArrayInt::isUniform(int val) const; +DataArrayInt::substr(int tupleIdBg, int tupleIdEnd=-1) const; +DataArrayInt::rearrange(int newNbOfCompo); +DataArrayInt::transpose(); +DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const; +DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const; +DataArrayInt::meldWith(const DataArrayInt* other); +DataArrayInt::setSelectedComponents(const DataArrayInt* a, const std::vector& compoIds); +DataArrayInt::setPartOfValues1(const DataArrayInt* a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); +DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); +DataArrayInt::setPartOfValues2(const DataArrayInt* a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); +DataArrayInt::setPartOfValuesSimple2(int a, const int* bgTuples, const int* endTuples, const int* bgComp, const int* endComp); +DataArrayInt::setPartOfValues3(const DataArrayInt* a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); +DataArrayInt::setPartOfValuesSimple3(int a, const int* bgTuples, const int* endTuples, int bgComp, int endComp, int stepComp); +DataArrayInt::getTuple(int tupleId, int* res) const; +DataArrayInt::getIJ(int tupleId, int compoId) const; +DataArrayInt::getIJSafe(int tupleId, int compoId) const; +DataArrayInt::back() const; +DataArrayInt::setIJ(int tupleId, int compoId, int newVal); +DataArrayInt::setIJSilent(int tupleId, int compoId, int newVal); +DataArrayInt::getPointer(); +DataArrayInt::getConstPointer() const; +DataArrayInt::getIdsEqual(int val) const; +DataArrayInt::getIdsNotEqual(int val) const; +DataArrayInt::getIdsEqualList(const int* valsBg, const int* valsEnd) const; +DataArrayInt::getIdsNotEqualList(const int* valsBg, const int* valsEnd) const; +DataArrayInt::changeValue(int oldValue, int newValue); +DataArrayInt::presenceOfValue(int value) const; +DataArrayInt::presenceOfValue(const std::vector& vals) const; +DataArrayInt::getMaxValue(int& tupleId) const; +DataArrayInt::getMaxValueInArray() const; +DataArrayInt::getMinValue(int& tupleId) const; +DataArrayInt::getMinValueInArray() const; +DataArrayInt::abs(); +DataArrayInt::applyLin(int a, int b, int compoId); +DataArrayInt::applyLin(int a, int b); +DataArrayInt::applyInv(int numerator); +DataArrayInt::negate() const; +DataArrayInt::applyDivideBy(int val); +DataArrayInt::applyModulus(int val); +DataArrayInt::applyRModulus(int val); +DataArrayInt::buildComplement(int nbOfElement) const; +DataArrayInt::buildSubstraction(const DataArrayInt* other) const; +DataArrayInt::buildUnion(const DataArrayInt* other) const; +DataArrayInt::buildIntersection(const DataArrayInt* other) const; +DataArrayInt::deltaShiftIndex() const; +DataArrayInt::computeOffsets(); +DataArrayInt::computeOffsets2(); +DataArrayInt::buildExplicitArrByRanges(const DataArrayInt* offsets) const; +DataArrayInt::useArray(const int* array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); +DataArrayInt::writeOnPlace(int id, int element0, const int* others, int sizeOfOthers); +DataArrayInt::addEqual(const DataArrayInt* other); +DataArrayInt::substractEqual(const DataArrayInt* other); +DataArrayInt::multiplyEqual(const DataArrayInt* other); +DataArrayInt::divideEqual(const DataArrayInt* other); +DataArrayInt::modulusEqual(const DataArrayInt* other); +DataArrayInt::updateTime() const; +DataArrayInt::New(); +DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int* arr, const int* arrIBg, const int* arrIEnd, int &newNbOfTuples); +DataArrayInt::Aggregate(const DataArrayInt* a1, const DataArrayInt* a2, int offsetA2); +DataArrayInt::Aggregate(const std::vector& arr); +DataArrayInt::Meld(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::Meld(const std::vector& arr); +DataArrayInt::MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups); +DataArrayInt::BuildUnion(const std::vector& arr); +DataArrayInt::BuildIntersection(const std::vector& arr); +DataArrayInt::Add(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::Substract(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::Multiply(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::Divide(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::Modulus(const DataArrayInt* a1, const DataArrayInt* a2); +DataArrayInt::CheckAndPreparePermutation(const int* start, const int* end); +DataArrayInt::Range(int begin, int end, int step); +///@} + +/*! \name Others... */ +///@{ +DataArrayInt::getNumberOfTuples() const; +DataArrayInt::getNbOfElems() const; +DataArrayInt::getHeapMemorySize() const; +DataArrayInt::reserve(int nbOfElems); +DataArrayInt::pushBackSilent(int val); +DataArrayInt::popBackSilent(); +DataArrayInt::pack() const; +DataArrayInt::getNbOfElemAllocated() const; +DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const; +DataArrayInt::checkMonotonic(bool increasing) const; +DataArrayInt::isMonotonic(bool increasing) const; +DataArrayInt::checkStrictlyMonotonic(bool increasing) const; +DataArrayInt::isStrictlyMonotonic(bool increasing) const; +DataArrayInt::reprZip() const; +DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char* type, const char* nameInFile) const; +DataArrayInt::reprStream(std::ostream& stream) const; +DataArrayInt::reprZipStream(std::ostream& stream) const; +DataArrayInt::reprWithoutNameStream(std::ostream& stream) const; +DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const; +DataArrayInt::reprCppStream(const char* varName, std::ostream& stream) const; +DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const; +DataArrayInt::setPartOfValues4(const DataArrayInt* a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp, bool strictCompoCompare=true); +DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int* bgComp, const int* endComp); +DataArrayInt::iterator(); +DataArrayInt::begin() const; +DataArrayInt::end() const; +DataArrayInt::locateTuple(const std::vector& tupl) const; +DataArrayInt::locateValue(int value) const; +DataArrayInt::locateValue(const std::vector& vals) const; +DataArrayInt::search(const std::vector& vals) const; +DataArrayInt::presenceOfTuple(const std::vector& tupl) const; +DataArrayInt::accumulate(int* res) const; +DataArrayInt::accumulate(int compId) const; +DataArrayInt::getIdsInRange(int vmin, int vmax) const; +DataArrayInt::buildSubstractionOptimized(const DataArrayInt* other) const; +DataArrayInt::buildUnique() const; +DataArrayInt::findRangeIdForEachTuple(const DataArrayInt* ranges) const; +DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt* ranges) const; +DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const; +DataArrayInt::getDifferentValues() const; +> DataArrayInt::partitionByDifferentValues(std::vector& differentIds) const; +DataArrayInt::useExternalArrayWithRWAccess(const int* array, int nbOfTuple, int nbOfCompo); +tor> +DataArrayInt::insertAtTheEnd(InputIterator first, InputIterator last); +DataArrayInt::getTinySerializationIntInformation(std::vector& tinyInfo) const; +DataArrayInt::getTinySerializationStrInformation(std::vector& tinyInfo) const; +DataArrayInt::resizeForUnserialization(const std::vector& tinyInfoI); +DataArrayInt::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS); +DataArrayInt::DataArrayInt(); +MemArray DataArrayInt::_mem; +///@} + +} diff --git a/doc/doxygen/interptheory.dox b/doc/doxygen/interptheory.dox index f53984c82..4fd32b8bb 100644 --- a/doc/doxygen/interptheory.dox +++ b/doc/doxygen/interptheory.dox @@ -8,8 +8,8 @@ For fields with polynomial representation on each cell, the components of the di \f] \f$W\f$ is called the \anchor interpolationmatrix interpolation matrix. -The objectives of interpolators is to compute the matrix W depending on their physical -properties (\ref IntExtFields) and their mesh discretisation (P0, P1,...). +The objective of interpolators is to compute the matrix W depending on their physical +properties (\ref IntExtFields) and their mesh discretisation (on cells P0, on nodes P1,...). \section ConsInterp Conservative interpolation @@ -42,9 +42,10 @@ fully overlapped by cells of S that is \sum_{S_j} Vol(T_i\cap S_j) = Vol(T_i),\hspace{1cm} and \hspace{1cm} \sum_{T_i} Vol(S_j\cap T_i) = Vol(S_j) \f] then the meshes S and T are said to be \b -overlapping and all the algorithms will return the same results. +overlapping. In this case the two formulas in a given column in the table below give the same +result. All intensive formulas result in the same output, and all the extensive formulas give also the same output. -The ideal interpolation algorithm should be conservative and respect the maximum principle. However such an algorithm can be impossible to design if the two meshes do not overlap. When the meshes do not overlap, using either \f$Vol(T_i)\f$ or \f$\sum_{S_j} Vol(T_i\cap S_j)\f$ in the formula one obtains an algorithm that respects either conservativity either the maximum principle (see the nature of field \ref TableNatureOfField "summary table"). +The ideal interpolation algorithm should be conservative and respect the maximum principle. However such an algorithm can be impossible to design if the two meshes do not overlap. When the meshes do not overlap, using either \f$Vol(T_i)\f$ or \f$\sum_{S_j} Vol(T_i\cap S_j)\f$ one obtains an algorithm that respects either the conservativity or the maximum principle (see the nature of field \ref TableNatureOfField "summary table"). \section InterpKerRemapInt Linear conservative remapping of P0 (cell based) fields @@ -109,7 +110,7 @@ given by the formula : \f] \section TableNatureOfField Summary -In the case of fields with P0 representation, if the meshes do not overlap the scheme is either conservative or maximum preserving (not both) and depending on the prioritised property and the \ref NatureOfField the interpolation coefficients take the following value +In the case of fields with a P0 representation (cell based) and when the meshes do not overlap, the scheme is either conservative or maximum preserving (not both). Depending on the \ref NatureOfField the interpolation coefficients take the following value: * * diff --git a/doc/doxygen/medcoupling.dox b/doc/doxygen/medcoupling.dox index b8293f96e..167a3d3bb 100644 --- a/doc/doxygen/medcoupling.dox +++ b/doc/doxygen/medcoupling.dox @@ -227,23 +227,22 @@ It will be presented in this section common concept shared by the two classes to A \ref ParaMEDMEM::DataArray "DataArray" instance has an attribute **name**. **name** is particulary useful for \ref ParaMEDMEM::DataArray "DataArray" representing profiles, families, groups, fields in MEDLoader. -But excepted these useful usecases, **name** attribute is often ignored when \ref ParaMEDMEM::DataArray "DataArrays" are aggregated (field array, connectivity, coordinates) is a bigger object. -Whatever the useage of the **name** attribute of \ref ParaMEDMEM::DataArray "DataArrays", all methods in ParaMEDMEM::DataArrayDouble and ParaMEDMEM::DataArrayInt class deal with **name** as they do for components names. +But excepted these useful usecases, **name** attribute is often ignored when \ref ParaMEDMEM::DataArray "DataArrays" are aggregated (field array, connectivity, coordinates) in a bigger object. +Whatever the usage of the **name** attribute of \ref ParaMEDMEM::DataArray "DataArrays", all methods in ParaMEDMEM::DataArrayDouble and ParaMEDMEM::DataArrayInt class deal with **name** as they do for components names. \subsection MEDCouplingArrayBasicsTuplesAndCompo Raw data, tuples and components of DataArrays. The main goal of \ref ParaMEDMEM::DataArray "DataArray" is to store contiguous vector of atomical elements with same basic datatype (signed integers, double precision...). This vector of atomical elements is called **raw data** of \ref ParaMEDMEM::DataArray "DataArray". -The size of this vector of data is called, number of elements. So the number of bytes stored by a \ref ParaMEDMEM::DataArray "DataArray" instance, is equal to +The size of this vector of data is called "number of elements". So the number of bytes stored by a \ref ParaMEDMEM::DataArray "DataArray" instance, is equal to the product of the __number of elements__ * __constant size of DataType__ . -As \ref ParaMEDMEM::DataArray "DataArray" instances are designed to stored vector fields, tensor fields, coordinate of nodes, the notion of components has been -added. +As \ref ParaMEDMEM::DataArray "DataArray" instances are designed to store vector fields, tensor fields, coordinate of nodes, the notion of _components_ has been added. So, \ref ParaMEDMEM::DataArray "DataArrays" have an additional attribute that is number of components that represent the size of a contiguous set of atomical elements. -The vector of atomical elements stored into \ref ParaMEDMEM::DataArray "DataArrays" are grouped in contiguous in memory set of atomical elements having each same size. +The vector of atomical elements stored into \ref ParaMEDMEM::DataArray "DataArrays" are grouped in contiguous memory set of atomical elements having each same size. -The contiguous set of atomical elements is called **tuple**. And each **tuple** stored in raw data, have each a length exactly equal to the number of components of +The contiguous set of atomical elements is called **tuple**. And each **tuple** stored in raw data, have each a length exactly equal to the number of components of \ref ParaMEDMEM::DataArray "DataArray" storing it. Thus : @@ -256,8 +255,8 @@ Thus : N_{bytes}=N_{elements}*sizeof(DataType)=N_{tuples}*N_{components}*sizeof(DataType). \f] -In another words, **raw data** of \ref ParaMEDMEM::DataArray "DataArrays" can be seen as a dense matrix, whose number of components would be the row size and number of tuples -would be the column size. In this point of view of \ref ParaMEDMEM::DataArray "DataArrays" a **tuple** is represented by the corresponding row in the dense matrix. +In other words, **raw data** of \ref ParaMEDMEM::DataArray "DataArrays" can be seen as a dense matrix, whose number of components would be the row size and number of tuples +would be the column size. In this point of view of \ref ParaMEDMEM::DataArray "DataArrays" a **tuple** is represented by the corresponding row in the dense matrix. Typically in the **raw data** of \ref ParaMEDMEM::DataArray "DataArrays" **number of tuples** is highly bigger than **number of components** ! @@ -324,7 +323,8 @@ An another way is to do that : \section MEDCouplingArraySteps1 Building an array from scratch in C++ -Here a description of typical usages to use \ref ParaMEDMEM::DataArrayDouble "MEDCoupling arrays".\n +Here is a description of typical usages of \ref ParaMEDMEM::DataArrayDouble "MEDCoupling arrays". + In this example we will create arrays with 12 tuples constituted each of 3 components. These arrays will be created using different ways.\n @@ -436,6 +436,20 @@ There are two types of comparison : - ParaMEDMEM::DataArrayInt::isEqualWithoutConsideringStr - ParaMEDMEM::DataArrayDouble::isEqualWithoutConsideringStr +\section MEDCouplingArrayFill Filling DataArray with values + +Both DataArrayDouble and DataArrayInt provide comfort methods that +fill the array with some values. These methods are: +- ParaMEDMEM::DataArrayInt::fillWithZero and + ParaMEDMEM::DataArrayDouble::fillWithZero which assigns zero to all + values in array. +- ParaMEDMEM::DataArrayInt::fillWithValue and + ParaMEDMEM::DataArrayDouble::fillWithValue which assigns a certain value to all + values in array. +- ParaMEDMEM::DataArrayInt::iota() and + ParaMEDMEM::DataArrayDouble::iota() which assigns incrementing values to all + values in array. + \section MEDCouplingArrayRenumbering Array renumbering Here is presented all it is necessary to know concerning renumbering. @@ -497,6 +511,9 @@ Method in new to old mode that works on bijective applications : Method in new to old mode that works on surjective applications : - \ref ParaMEDMEM::DataArrayDouble::selectByTupleId "DataArrayDouble::selectByTupleId" +- \ref ParaMEDMEM::DataArrayDouble::selectByTupleIdSafe "DataArrayDouble::selectByTupleIdSafe" +- \ref ParaMEDMEM::DataArrayDouble::selectByTupleId2 "DataArrayDouble::selectByTupleId2" +- \ref ParaMEDMEM::DataArrayDouble::selectByTupleRanges "DataArrayDouble::selectByTupleRanges" \section MEDCouplingArrayApplyFunc Application of a function on DataArrayDouble instances. @@ -638,28 +655,32 @@ Let's consider DataArrayDouble instance \c ddd constituted with 4 tuples contain \section IntExtFields Overview: intensive and extensive field -\c NatureOfField is an enum which helps determining some physical significance of the field and affects the choice of interpolation formula ( see \ref TableNatureOfField). +\c NatureOfField is an enum which helps determining some physical significance of the field and affects the choice of the interpolation formula (see \ref TableNatureOfField). It has five possible values: -- "NoNature", the default value, does not allow the use of interpolation tools +- "NoNature", the default value, does not allow the use of any interpolation tools - \ref TableNatureOfFieldExampleConservVol "ConservativeVolumic", for intensive field with the maximum principle favored over conservativity. Relevant for temperature, pression fields. +- \ref TableNatureOfFieldExampleRevIntegral "RevIntegral", for intensive field with the conservativity favored over maximum principle. Relevant for power density fields. + - \ref TableNatureOfFieldExampleIntegral "Integral", for extensive field with the maximum principle favored over conservativity. Relevant for power fields. - \ref TableNatureOfFieldExampleIntegralGlobConstraint "IntegralGlobConstraint", for extensive fields with conservativity favored over the maximum principle. Relevant for power fields. -- \ref TableNatureOfFieldExampleRevIntegral "RevIntegral", for intensive field with the conservativity favored over maximum principle. Relevant for power density fields. +The first two correspond to intensive fields, the last two correspond to extensive fields. -By an intensive field we mean a field that represent volumetric or intensive physical variable such as density (\f$kg.m^{-3}\f$), power density (\f$W.m^{-3}\f$), temperature (\f$K\f$) or pressure (\f$Pa\f$). -By extensive (or integral) field we mean a field that represents an extensive physical quantity sych as mass (\f$kg\f$), volume (\f$m^3\f$), a momentum (\f$kg.m.s^{-1}\f$) or power \f$(W\f$). -For fields with a P0 representation, conservativity formulas are different depending on whether the field is extensive or intensive (see \ref InterpKerP0P0Int and \ref InterpKerP0P0Ext). -In some cases such a non \ref MeshOverlap "overlapping meshes", it is impossible to fulfill both conservation and maximum principle during the interpolation. The nature of the fields determines the formula to be used for non overlapped cells and thus the property that we will be satisfied. -We consider that fields with P1 or P2 representations are necessarily intensive. +By an intensive field we mean a field that represent an intensive physical variable such as density (\f$kg.m^{-3}\f$), power density (\f$W.m^{-3}\f$), temperature (\f$K\f$) or pressure (\f$Pa\f$). Typically the physical value doesn't scale with the size of the underlying geometry. +By extensive (or integral) field we mean a field that represents an extensive physical quantity such as mass (\f$kg\f$), volume (\f$m^3\f$), a momentum (\f$kg.m.s^{-1}\f$) or power \f$(W\f$). +Typically the field value scales linearly with respect to the underlying geometry size. +For fields with a P0 representation (cell based), conservativity formulas are different depending on whether the field is extensive or intensive (see \ref InterpKerP0P0Int and \ref InterpKerP0P0Ext). +Those two notions are themselves split into two sub-categories. +Indeed in some cases (e.g. non \ref MeshOverlap "overlapping meshes"), it is impossible to fulfill both the conservation principle and the maximum principle during the interpolation. The nature of the fields determine the formula to be used for non overlapping cells and thus the property that we will be satisfied. +Finally we consider that fields with P1 or P2 representations are necessarily intensive. \section Usage -In order to employ the various \ref interptools, it is important to specify the nature of your field. -In case the sources and target meshes do not overlap different treatments will be employed, depending on the nature of the source and target fields. +In order to employ the various \ref interptools, you have to specify the nature of your field. +When the source and target meshes do not overlap, different treatments will be employed depending on the nature of the source and target fields. You can specify the nature of the field when you create a \ref medcoupling field with the following constructor: \code MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); @@ -725,9 +746,9 @@ and 9 nodes. You can notice that it is possible to mix cell types as long as the dimension of cell is exactly equal to meshDim to respect \ref MEDCouplingMeshes "this rule". -\subpage medcouplingcppexamplesUmeshStdBuild1 "Here the C++ implementation." +\subpage medcouplingcppexamplesUmeshStdBuild1 "Here is the C++ implementation." -\subpage medcouplingpyexamplesUmeshStdBuild1 "Here the Python implementation." +\subpage medcouplingpyexamplesUmeshStdBuild1 "Here is the Python implementation." \section MEDCouplingUMeshNodalConnectivity How MEDCouplingUMesh stores its nodal connectivity. @@ -852,4 +873,4 @@ The usage is simple : The virtual call to ParaMEDMEM::TimeLabel::updateTime change the behaviour of ParaMEDMEM::TimeLabel::getTimeOfThis it is a bug, so please notify the bug into the salome forum. -*/ \ No newline at end of file +*/ diff --git a/doc/doxygen/medcouplingexamples.doxy b/doc/doxygen/medcouplingexamples.doxy index fbf1a4767..bd0ee8f68 100644 --- a/doc/doxygen/medcouplingexamples.doxy +++ b/doc/doxygen/medcouplingexamples.doxy @@ -1,11 +1,708 @@ /*! \page medcouplingcppexamples

MEDCoupling C++ examples

+ +\anchor cpp_mcdataarrayint_ +

+ +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_ +\snippet MEDCouplingExamplesTest.py PySnippet_DataArrayInt_ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_ + + +\anchor cpp_mcdataarrayint_getTuple +

Getting a tuple of DataArrayInt

+ +In this simple example we create an array of integers arranged into 3 +tuples per 2 components, and finally print the second tuple. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_getTuple_1 +The output is +
 [9, 10] 
+Note that we can traverse all tuples in the array by simply iterating +over it as the code below does. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_getTuple_2 +Its output follows. +
+(7, 8)
+(9, 10)
+(11, 12)
+
+ +\anchor cpp_mcdataarrayint_buildpermutationarr +

Building a permutation array

+ +Here we create two arrays containing same values but in different order and then we use +\ref ParaMEDMEM::DataArrayInt::buildPermutationArr "DataArrayInt::buildPermutationArr()" to get +an array showing in what places the values of \b b array are located in \b a array. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_buildPermutationArr_1 +The result array \b c contains [1,0,4,2,3]. + +

Inverting renumbering maps

+\anchor cpp_mcdataarrayint_invertarrayo2n2n2o +

invertArrayO2N2N2O()

+ +In this example we create a DataArrayInt containing a renumbering map in +"Old to New" mode, convert it into the renumbering map in "New to Old" mode and check the +result. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_invertArrayO2N2N2O_1 + +\anchor cpp_mcdataarrayint_invertarrayn2o2o2n +

invertArrayN2O2O2N()

+ +In this example we create a DataArrayInt containing a renumbering map in +"New to Old" mode, convert it into the renumbering map in "Old to New" mode and check the +result. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_invertArrayN2O2O2N_1 + + + +\anchor cpp_mcdataarraydouble_getidsinrange +

Finding values in range in DataArrayDouble

+ +In this example we create an array \b da containing same values as ones returned by +\c range( \c 10 ). Then we get an array of indices of values of \b da being in +range [ 2.5, 6 ]. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_getIdsInRange_1 +As result contents of the array \b da2 are as follows. +
+    Tuple #0 : 3
+    Tuple #1 : 4
+    Tuple #2 : 5
+    Tuple #3 : 6
+
+ + +\anchor cpp_mcdataarraydouble_setselectedcomponents +

Set part of values of DataArrayDouble

+

setSelectedComponents()

+First, we create a 'source' array. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setSelectedComponents1 +Now we create a larger zero array and assign the array \b da into it. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setSelectedComponents2 +As result contents of the array \b dv are as follows. +
+Info of components : "a2"   "a1"   "v3"   "v4"   
+    Tuple #0 : 2 1 0 0 
+    Tuple #1 : 4 3 0 0 
+    Tuple #2 : 6 5 0 0 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way (except that component info +is not copied): +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setSelectedComponents3 + +\anchor cpp_mcdataarraydouble_setpartofvalues1 +

setPartOfValues1()

+We create two arrays: +- a "large" (4x4) zero array \b da to assign to and +- a smaller (2x2) array \b dv filled with values [7.,8.,9.,10]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_1 +Now we copy \b dv to the middle of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_2 +As result contents of the array \b da are as follows. +
+    Info of components :"v1"   "v2"   "v3"   "v4"
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 8 0 
+    Tuple #2 : 0 9 10 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and copy \b dv into a component of \b da. + +Note that the last parameter \a strictCompoCompare should be \a False +in this case, else \ref ParaMEDMEM::DataArrayDouble::setPartOfValues1() +throws an exception because \b da has 2 components but only one target +component is specified. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 8 0 0 
+    Tuple #2 : 0 9 0 0 
+    Tuple #3 : 0 10 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 8 9 10 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_5 +
+    Tuple #0 : 0 7 0 8 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 9 0 10 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way: +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues1_6 + + + +\anchor cpp_mcdataarraydouble_setpartofvaluessimple1 +

setPartOfValuesSimple1()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_1 +Now we assign \b dv to the middle of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way: +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple1_6 + + +\anchor cpp_mcdataarraydouble_setpartofvaluessimple2 +

setPartOfValuesSimple2()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_1 +Now we assign \b dv to the middle of \b da. +We explicitly specify tuples and component to assign to by a list [1,2]. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple2_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValuesSimple2() can't +be explicitly called in Python. + + +\anchor cpp_mcdataarraydouble_setpartofvaluessimple3 +

setPartOfValuesSimple3()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_1 +Now we assign \b dv to the middle of \b da. +We explicitly specify tuples to assign to by a list [1,2]. And we specify +components to assign to using slicing: 1:3. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValuesSimple3_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValuesSimple3() can't +be explicitly called in Python. + + +\anchor cpp_mcdataarraydouble_setpartofvalues2 +

setPartOfValues2()

+We create two arrays: +- a "large" (4x7) zero array \b da to assign to, +- a smaller (3x2) array \b dv filled with values [7.,8.,9.,10.,11.,12.]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues2_1 +Now we assign the two components of \b dv to the components of \b da +with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with + indices [0,1,2]. This is the first mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues2_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0  7  0  8  0  0  0  
+    Tuple #1 : 0  9  0 10  0  0  0 
+    Tuple #2 : 0 11  0 12  0  0  0 
+    Tuple #3 : 0  0  0  0  0  0  0
+
+Every value of \b dv has been assigned to its own location within \b da. + +Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. +And we assign \b dv to the tuples of \b da with indices [0,2,3] . +This is the second mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues2_3 +The contents of \b dv have been assigned to each of specified tuples of \b da. +Every value of \b dv is repeated in the 3 specified tuples within \b da. +
+    Tuple #0 : 7  0  8  9 10 11 12
+    Tuple #1 : 0  0  0  0  0  0  0   
+    Tuple #2 : 7  0  8  9 10 11 12
+    Tuple #3 : 7  0  8  9 10 11 12
+
+\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValues2() can't +be explicitly called in Python. + + +\anchor cpp_mcdataarraydouble_setpartofvalues3 +

setPartOfValues3()

+We create two arrays: +- a "large" (4x7) zero array \b da to assign to, +- a smaller (3x2) array \b dv filled with values [7.,8.,9.,10.,11.,12.]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues3_1 +Now we assign the two components of \b dv to the components of \b da +with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with +indices [0,1,2] which are specified using slicing: "0:3". +This is the first mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues3_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0  7  0  8  0  0  0  
+    Tuple #1 : 0  9  0 10  0  0  0 
+    Tuple #2 : 0 11  0 12  0  0  0 
+    Tuple #3 : 0  0  0  0  0  0  0
+
+Every value of \b dv has been assigned to its own location within \b da. + +Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. +And we assign \b dv to the tuples of \b da with indices [0,2] using \a +slice notation "0:4:2". This is the second mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_setPartOfValues3_3 +The contents of \b dv have been assigned to each of specified tuples of \b da. +Every value of \b dv is repeated in the 3 specified tuples within \b da. +
+    Tuple #0 : 7  0  8  9 10 11 12
+    Tuple #1 : 0  0  0  0  0  0  0   
+    Tuple #2 : 7  0  8  9 10 11 12
+    Tuple #3 : 0  0  0  0  0  0  0   
+
+\note \ref ParaMEDMEM::DataArrayDouble::setPartOfValues3() can't +be explicitly called in Python. + + +\anchor cpp_mcdataarrayint_setselectedcomponents +

Set part of values of DataArrayInt

+

setSelectedComponents()

+First, we create a 'source' array. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setSelectedComponents1 +Now we create a larger zero array and assign the array \b da to it. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setSelectedComponents2 +As result contents of the array \b dv are as follows. +
+Info of components : "a2"   "a1"   "v3"   "v4"   
+    Tuple #0 : 2 1 0 0 
+    Tuple #1 : 4 3 0 0 
+    Tuple #2 : 6 5 0 0 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way (except that component info +is not copied): +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setSelectedComponents3 + +\anchor cpp_mcdataarrayint_setpartofvalues1 +

setPartOfValues1()

+We create two arrays: +- a "large" (4x4) zero array \b da to assign to and +- a smaller (2x2) array \b dv filled with values [7,8,9,10]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_1 +Now we copy \b dv to the middle of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_2 +As result contents of the array \b da are as follows. +
+    Info of components :"v1"   "v2"   "v3"   "v4"
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 8 0 
+    Tuple #2 : 0 9 10 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and copy \b dv into a component of \b da. + +Note that the last parameter \a strictCompoCompare should be \a False +in this case, else \ref ParaMEDMEM::DataArrayInt::setPartOfValues1() +throws an exception because \b da has 2 components but only one target +component is specified. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 8 0 0 
+    Tuple #2 : 0 9 0 0 
+    Tuple #3 : 0 10 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 8 9 10 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_5 +
+    Tuple #0 : 0 7 0 8 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 9 0 10 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way: +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues1_6 + + + +\anchor cpp_mcdataarrayint_setpartofvaluessimple1 +

setPartOfValuesSimple1()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_1 +Now we assign \b dv to the middle of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+The same result can be achieved other way: +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple1_6 + + +\anchor cpp_mcdataarrayint_setpartofvaluessimple2 +

setPartOfValuesSimple2()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_1 +Now we assign \b dv to the middle of \b da. +We explicitly specify tuples and component to assign to by a list [1,2]. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple2_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+\note \ref ParaMEDMEM::DataArrayInt::setPartOfValuesSimple2() can't +be explicitly called in Python. + + +\anchor cpp_mcdataarrayint_setpartofvaluessimple3 +

setPartOfValuesSimple3()

+We create an array (4x4) \b da to assign to and define a value \b dv to assign. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_1 +Now we assign \b dv to the middle of \b da. +We explicitly specify tuples to assign to by a list [1,2]. And we specify +components to assign to using slicing: 1:3. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 0 7 7 0 
+    Tuple #2 : 0 7 7 0 
+    Tuple #3 : 0 0 0 0 
+
+ +Here we re-fill \b da with zeros and assign \b dv to a component of \b da. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_3 +
+    Tuple #0 : 0 7 0 0 
+    Tuple #1 : 0 7 0 0 
+    Tuple #2 : 0 7 0 0 
+    Tuple #3 : 0 7 0 0 
+
+Below more two variants of location of target values are shown. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_4 +
+    Tuple #0 : 0 0 0 0 
+    Tuple #1 : 7 7 7 7 
+    Tuple #2 : 0 0 0 0 
+    Tuple #3 : 0 0 0 0 
+
+ +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValuesSimple3_5 +
+    Tuple #0 : 0 7 0 7 
+    Tuple #1 : 0 0 0 0 
+    Tuple #2 : 0 7 0 7 
+    Tuple #3 : 0 0 0 0 
+
+\note \ref ParaMEDMEM::DataArrayInt::setPartOfValuesSimple3() can't +be explicitly called in Python. + + +\anchor cpp_mcdataarrayint_setpartofvalues2 +

setPartOfValues2()

+We create two arrays: +- a "large" (4x7) zero array \b da to assign to, +- a smaller (3x2) array \b dv filled with values [7,8,9,10,11,12]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues2_1 +Now we assign the two components of \b dv to the components of \b da +with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with + indices [0,1,2]. This is the first mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues2_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0  7  0  8  0  0  0  
+    Tuple #1 : 0  9  0 10  0  0  0 
+    Tuple #2 : 0 11  0 12  0  0  0 
+    Tuple #3 : 0  0  0  0  0  0  0
+
+Every value of \b dv has been assigned to its own location within \b da. + +Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. +And we assign \b dv to the tuples of \b da with indices [0,2,3] . +This is the second mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues2_3 +The contents of \b dv have been assigned to each of specified tuples of \b da. +Every value of \b dv is repeated in the 3 specified tuples within \b da. +
+    Tuple #0 : 7  0  8  9 10 11 12
+    Tuple #1 : 0  0  0  0  0  0  0   
+    Tuple #2 : 7  0  8  9 10 11 12
+    Tuple #3 : 7  0  8  9 10 11 12
+
+\note \ref ParaMEDMEM::DataArrayInt::setPartOfValues2() can't +be explicitly called in Python. + + +\anchor cpp_mcdataarrayint_setpartofvalues3 +

setPartOfValues3()

+We create two arrays: +- a "large" (4x7) zero array \b da to assign to, +- a smaller (3x2) array \b dv filled with values [7,8,9,10,11,12]. + +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues3_1 +Now we assign the two components of \b dv to the components of \b da +with indices [1,3], and the 3 tuples of \b dv to the 3 tuples of \b da with +indices [0,1,2] which are specified using slicing: "0:3". +This is the first mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues3_2 +As result contents of the array \b da are as follows. +
+    Tuple #0 : 0  7  0  8  0  0  0  
+    Tuple #1 : 0  9  0 10  0  0  0 
+    Tuple #2 : 0 11  0 12  0  0  0 
+    Tuple #3 : 0  0  0  0  0  0  0
+
+Every value of \b dv has been assigned to its own location within \b da. + +Now we re-fill \b da with zeros and rearrange \b dv to have 6 components. +And we assign \b dv to the tuples of \b da with indices [0,2] using \a +slice notation "0:4:2". This is the second mode of usage. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayInt_setPartOfValues3_3 +The contents of \b dv have been assigned to each of specified tuples of \b da. +Every value of \b dv is repeated in the 3 specified tuples within \b da. +
+    Tuple #0 : 7  0  8  9 10 11 12
+    Tuple #1 : 0  0  0  0  0  0  0   
+    Tuple #2 : 7  0  8  9 10 11 12
+    Tuple #3 : 0  0  0  0  0  0  0   
+
+\note \ref ParaMEDMEM::DataArrayInt::setPartOfValues3() can't +be explicitly called in Python. + + +\anchor cpp_mcdataarraydouble_getdifferentvalues +

Excluding coincident tuples from DataArrayDouble

+ +The code below creates an array of real values and than an array of + unique values, not closer one to another than 0.2, is retrieved from it. +\snippet MEDCouplingExamplesTest.py Snippet_DataArrayDouble_getDifferentValues1 + + +\anchor cpp_mcdataarraydouble_findcommontuples +

Finding coincident tuples in DataArrayDouble

+ +Let's create an array of 6 tuples and 2 components that can be + considered as coordinates of 6 points in 2D space. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_findCommonTuples1 +Now we find points that are not far each from other than 1e-1. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_findCommonTuples2 +As we can realize from the above code, a hardcoded array \b expected3 is equal + to the raw data of a DataArrayInt \b c and a hardcoded array \b expected4 is equal + to the raw data of the DataArrayInt \b cI. + +The array \b c contains indices of 5 coincident points. The array \b + cI shows us boundaries of (cI->getNumberOfTuples()-1) = 2 groups of coincident points: +- The first group starts at index 0 and includes (3 - 0) = 3 points: 0,3,4. +- The second group starts at index 3 and includes (5 - 3) = 2 points: 1,2. + +\anchor cpp_mcdataarraydouble_meldwith +

Concatenating DataArrayDouble's by appending components

+ +In this example we create two data arrays including \b same number of +tuples and then we concatenate them using \ref +ParaMEDMEM::DataArrayDouble::meldWith "meldWith()". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayDouble_Meld1_1 +Now the array \b da1 includes 7 tuples (as before) of 3 components +each. Its components are: "c0da1","c1da1","c0da2". + + +\anchor cpp_mcdataarrayint_meldwith +

Concatenating DataArrayInt's by appending components

+ +In this example we create two data arrays including \b same number of +tuples and then we concatenate them using \ref +ParaMEDMEM::DataArrayInt::meldWith "meldWith()". +\snippet MEDCouplingExamplesTest.cxx CppSnippet_DataArrayInt_Meld1_1 +Now the array \b da1 includes 7 tuples (as before) of 3 components +each. Its components are: "c0da1","c1da1","c0da2". + + +\anchor cpp_mcdataarraydouble_KeepSelectedComponents + +

Creation of a sub-part of the DataArrayDouble by selecting components

+ +\snippet MEDCouplingExamplesTest.py SnippeDataArrayDoubleKeepSelectedComponents1_1 +We created an array \b a1 containing 5 tuples of 4 components each (20 +values). Now we are going to create an array \b a2 containing some +components of \b a1. +\snippet MEDCouplingExamplesTest.py SnippeDataArrayDoubleKeepSelectedComponents1_2 +Now each tuple of \b a2 includes components named "b","c","b","c","a","a". Thus +the result array \b a2 includes 30 elements (5 tuples per 6 components). + \anchor cpp_mcfielddouble_subpart1 + +\anchor cpp_mcdataarrayint_keepselectedcomponents + +

Creation of a sub-part of the DataArrayInt by selecting components

+ +\snippet MEDCouplingExamplesTest.py SnippeDataArrayIntKeepSelectedComponents1_1 +We created an array \b a1 containing 5 tuples of 4 components each (20 +values). Now we are going to create an array \b a2 containing some +components of \b a1. +\snippet MEDCouplingExamplesTest.py SnippeDataArrayIntKeepSelectedComponents1_2 +Now each tuple of \b a2 includes components named "b","c","b","c","a","a". Thus +the result array \b a2 includes 30 elements (5 tuples per 6 components). + +Note that +\ref ParaMEDMEM::DataArrayInt::keepSelectedComponents() "DataArrayInt::keepSelectedComponents()" +is called, providing the same result, by the following python code: +\snippet MEDCouplingExamplesTest.py SnippeDataArrayIntKeepSelectedComponents1_3 + +\anchor cpp_mcfielddouble_subpart1 + +

Creation of a sub part of a field


Creation of a sub part of a field on cells

\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_1 -The field on cells \b f1 lies on a mesh containg 5 cells and 9 nodes. +The field on cells \b f1 lies on a mesh containing 5 cells and 9 nodes. So this field \b f1 contains 5 tuples of 2 components each (10 values). Now let's create a subfield on cells \b f2 from \b f1. \snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_2 @@ -26,7 +723,7 @@ The underlying mesh of \b f2 contains a newly created mesh with 3 cells (not as

Creation of a sub part of a field on nodes

\snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_3 -The field on nodes \b f1 lies on a mesh containg 5 cells and 9 nodes. +The field on nodes \b f1 lies on a mesh containing 5 cells and 9 nodes. So this field \b f1 contains 9 tuples of 2 components each (18 values). Now let's create a subfield on nodes \b f2 from \b f1. \snippet MEDCouplingExamplesTest.cxx CppSnippetFieldDoubleBuildSubPart1_4 @@ -84,7 +781,7 @@ At this level the connectivity part of the mesh \b mesh as been defined. Now let \snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_4 -At this level mesh is usable. When this mesh is no more needed simply call decrRef to decrement its reference counter. +At this level mesh is usable. When this mesh is no more needed simply call decrRef() to decrement its reference counter. \snippet MEDCouplingExamplesTest.cxx CppSnippetUMeshAdvBuild1_5 @@ -101,7 +798,7 @@ Firstly retrieve for each direction the discretization and build a \ref ParaMEDM Then create ParaMEDMEM::MEDCouplingCMesh instance giving the 2 instances of \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" obtained above. -There are 2 technics to get it. +There are 2 techniques to get it. Either : diff --git a/doc/doxygen/static/header.html.in b/doc/doxygen/static/header.html.in index 4571b4363..d434d830d 100755 --- a/doc/doxygen/static/header.html.in +++ b/doc/doxygen/static/header.html.in @@ -5,6 +5,8 @@ $title + + $treeview $search $mathjax diff --git a/src/INTERP_KERNEL/BBTree.txx b/src/INTERP_KERNEL/BBTree.txx index 7b3d03782..dfb54606d 100644 --- a/src/INTERP_KERNEL/BBTree.txx +++ b/src/INTERP_KERNEL/BBTree.txx @@ -52,7 +52,9 @@ public: \param elems array to the indices of the elements contained in the BBTree \param level level in the BBTree recursive structure \param nbelems nb of elements in the BBTree - \param epsilon precision to which points are decided to be coincident + \param epsilon precision to which points are decided to be coincident. Epsilon can be positive or negative. + If \a epsilon is positive the request method will enlarge the computed bounding box (more matching elems return). + If negative the given bounding box will be tighten (less matching elems return). Parameters \a elems and \a level are used only by BBTree itself for creating trees recursively. A typical use is therefore : \code @@ -64,7 +66,7 @@ public: \endcode */ - BBTree(const double* bbs, ConnType* elems, int level, ConnType nbelems, double epsilon=1E-12): + BBTree(const double* bbs, ConnType* elems, int level, ConnType nbelems, double epsilon=1e-12): _left(0), _right(0), _level(level), _bb(bbs), _terminal(false),_nbelems(nbelems),_epsilon(epsilon) { if (nbelems < MIN_NB_ELEMS || level> MAX_LEVEL) diff --git a/src/INTERP_KERNEL/BBTreePts.txx b/src/INTERP_KERNEL/BBTreePts.txx new file mode 100644 index 000000000..934666e2f --- /dev/null +++ b/src/INTERP_KERNEL/BBTreePts.txx @@ -0,0 +1,221 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef __BBTREEPTS_TXX__ +#define __BBTREEPTS_TXX__ + +#include +#include + +#include +#include +#include + +template +class BBTreePts +{ + +private: + BBTreePts* _left; + BBTreePts* _right; + int _level; + double _max_left; + double _min_right; + const double *_pts; + typename std::vector _elems; + bool _terminal; + ConnType _nbelems; + double _epsilon; + + static const int MIN_NB_ELEMS=15; + static const int MAX_LEVEL=20; +public: + + /*! + Constructor of the bounding box tree + \param [in] pts pointer to the array containing the points that are to be indexed. + \param [in] elems array to the indices of the elements contained in the BBTreePts + \param [in] level level in the BBTreePts recursive structure + \param [in] nbelems nb of elements in the BBTreePts + \param [in] epsilon precision to which points are decided to be coincident. Contrary to BBTree, the absolute epsilon is computed. So the internal epsilon is always positive. + + Parameters \a elems and \a level are used only by BBTreePts itself for creating trees recursively. A typical use is therefore : + \code + int nbelems=... + double* pts= new double[dim*nbelems]; + // filling pts ... + ... + BBTreePts<2> tree = new BBTreePts<2>(elems,0,0,nbelems,1e-12); + \endcode + */ + BBTreePts(const double *pts, const ConnType *elems, int level, ConnType nbelems, double epsilon=1e-12): + _left(0),_right(0),_level(level),_pts(pts),_terminal(nbelems < MIN_NB_ELEMS || level> MAX_LEVEL),_nbelems(nbelems),_epsilon(std::abs(epsilon)) + { + double *nodes=new double[nbelems]; + _elems.resize(nbelems); + for (ConnType i=0;i(nodes, nodes+nbelems/2, nodes+nbelems); + double median=*(nodes+nbelems/2); + delete [] nodes; + std::vector new_elems_left,new_elems_right; + + new_elems_left.reserve(nbelems/2+1); + new_elems_right.reserve(nbelems/2+1); + double max_left = -std::numeric_limits::max(); + double min_right= std::numeric_limits::max(); + for(int i=0;imedian) + { + new_elems_right.push_back(elem); + if(mxmax_left) max_left=mx; + } + } + _max_left=max_left+_epsilon; + _min_right=min_right-_epsilon; + ConnType *tmp; + tmp=0; + if(!new_elems_left.empty()) + tmp=&(new_elems_left[0]); + _left=new BBTreePts(pts, tmp, level+1, (int)new_elems_left.size(),_epsilon); + tmp=0; + if(!new_elems_right.empty()) + tmp=&(new_elems_right[0]); + _right=new BBTreePts(pts, tmp, level+1, (int)new_elems_right.size(),_epsilon); + } + + + + ~BBTreePts() + { + delete _left; + delete _right; + } + + /*! returns in \a elems the list of elements potentially containing the point pointed to by \a xx + Contrary to BBTreePts::getElementsAroundPoint the norm 2 is used here. + + \param [in] xx pointer to query point coords + \param [in] threshold + \param elems list of elements (given in 0-indexing) intersecting the bounding box + \sa BBTreePts::getElementsAroundPoint + */ + double getElementsAroundPoint2(const double *xx, double threshold, ConnType& elem) const + { + // terminal node : return list of elements intersecting bb + if(_terminal) + { + double ret=std::numeric_limits::max(); + for(ConnType i=0;i<_nbelems;i++) + { + const double* const bb_ptr=_pts+_elems[i]*dim; + double tmp=0.; + for(int idim=0;idimgetElementsAroundPoint2(xx,threshold,elem); + if(xx[_level%dim]-s>_max_left) + return _right->getElementsAroundPoint2(xx,threshold,elem); + int eleml,elemr; + double retl=_left->getElementsAroundPoint2(xx,threshold,eleml); + double retr=_right->getElementsAroundPoint2(xx,threshold,elemr); + if(retl& elems) const + { + // terminal node : return list of elements intersecting bb + if(_terminal) + { + for(ConnType i=0;i<_nbelems;i++) + { + const double* const bb_ptr=_pts+_elems[i]*dim; + bool intersects = true; + for(int idim=0;idim_epsilon) + intersects=false; + if(intersects) + elems.push_back(_elems[i]); + } + return; + } + //non terminal node + if(xx[_level%dim]<_min_right) + { + _left->getElementsAroundPoint(xx,elems); + return; + } + if(xx[_level%dim]>_max_left) + { + _right->getElementsAroundPoint(xx,elems); + return; + } + _left->getElementsAroundPoint(xx,elems); + _right->getElementsAroundPoint(xx,elems); + } + + int size() const + { + if(_terminal) + return _nbelems; + return _left->size()+_right->size(); + } +}; + +#endif diff --git a/src/INTERP_KERNEL/CellModel.cxx b/src/INTERP_KERNEL/CellModel.cxx index 0ff626212..dae609b3b 100644 --- a/src/INTERP_KERNEL/CellModel.cxx +++ b/src/INTERP_KERNEL/CellModel.cxx @@ -116,6 +116,7 @@ namespace INTERP_KERNEL _reverse_extruded_type=NORM_ERROR; _linear_type=NORM_ERROR; _quadratic_type=NORM_ERROR; + _quadratic_type2=NORM_ERROR; _nb_of_little_sons=std::numeric_limits::max(); switch(type) { @@ -126,7 +127,7 @@ namespace INTERP_KERNEL break; case NORM_SEG2: { - _nb_of_pts=2; _nb_of_sons=2; _dim=1; _extruded_type=NORM_QUAD4; _quadratic_type=NORM_SEG3; _is_simplex=true; _is_extruded=true; _reverse_extruded_type=NORM_POINT1; + _nb_of_pts=2; _nb_of_sons=2; _dim=1; _extruded_type=NORM_QUAD4; _quadratic_type=NORM_SEG3; _quadratic_type2=NORM_SEG3; _is_simplex=true; _is_extruded=true; _reverse_extruded_type=NORM_POINT1; _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; _sons_con[0][0]=0; _nb_of_sons_con[0]=1; _sons_con[1][0]=1; _nb_of_sons_con[1]=1; @@ -169,7 +170,7 @@ namespace INTERP_KERNEL break; case NORM_HEXA8: { - _nb_of_pts=8; _nb_of_sons=6; _dim=3; _quadratic_type=NORM_HEXA20; _is_simplex=false; _is_extruded=true; _reverse_extruded_type=NORM_QUAD4; + _nb_of_pts=8; _nb_of_sons=6; _dim=3; _quadratic_type=NORM_HEXA20; _quadratic_type2=NORM_HEXA27; _is_simplex=false; _is_extruded=true; _reverse_extruded_type=NORM_QUAD4; _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_QUAD4; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4; _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _nb_of_sons_con[1]=4; @@ -193,7 +194,7 @@ namespace INTERP_KERNEL break; case NORM_QUAD4: { - _nb_of_pts=4; _nb_of_sons=4; _dim=2; _quadratic_type=NORM_QUAD8; _is_simplex=false; _is_extruded=true; + _nb_of_pts=4; _nb_of_sons=4; _dim=2; _quadratic_type=NORM_QUAD8; _quadratic_type2=NORM_QUAD9; _is_simplex=false; _is_extruded=true; _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; _sons_type[3]=NORM_SEG2; _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2; _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2; @@ -203,7 +204,7 @@ namespace INTERP_KERNEL break; case NORM_TRI3: { - _nb_of_pts=3; _nb_of_sons=3; _dim=2; _quadratic_type=NORM_TRI6; _is_simplex=true; + _nb_of_pts=3; _nb_of_sons=3; _dim=2; _quadratic_type=NORM_TRI6; _quadratic_type2=NORM_TRI7; _is_simplex=true; _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2; _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2; @@ -295,7 +296,7 @@ namespace INTERP_KERNEL _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _sons_con[1][3]=7; _sons_con[1][4]=8; _sons_con[1][5]=4; _nb_of_sons_con[1]=6; _sons_con[2][0]=1; _sons_con[2][1]=3; _sons_con[2][2]=2; _sons_con[2][3]=8; _sons_con[2][4]=9; _sons_con[2][5]=5; _nb_of_sons_con[2]=6; _sons_con[3][0]=2; _sons_con[3][1]=3; _sons_con[3][2]=0; _sons_con[3][3]=9; _sons_con[3][4]=7; _sons_con[3][5]=6; _nb_of_sons_con[3]=6; _quadratic=true; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=4; _nb_of_little_sons=6; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=4; _nb_of_little_sons=6; _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=5; _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; _little_sons_con[2][2]=6; _little_sons_con[3][0]=0; _little_sons_con[3][1]=3; _little_sons_con[3][2]=7; @@ -327,7 +328,7 @@ namespace INTERP_KERNEL _sons_con[2][0]=1; _sons_con[2][1]=4; _sons_con[2][2]=2; _sons_con[2][3]=10; _sons_con[2][4]=11; _sons_con[2][5]=6; _nb_of_sons_con[2]=6; _sons_con[3][0]=2; _sons_con[3][1]=4; _sons_con[3][2]=3; _sons_con[3][3]=11; _sons_con[3][4]=12; _sons_con[3][5]=7; _nb_of_sons_con[3]=6; _sons_con[4][0]=3; _sons_con[4][1]=4; _sons_con[4][2]=0; _sons_con[4][3]=12; _sons_con[4][4]=9; _sons_con[4][5]=8; _nb_of_sons_con[4]=6; _quadratic=true; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=5; _nb_of_little_sons=8; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=5; _nb_of_little_sons=8; _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=6; _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; _little_sons_con[2][2]=7; _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; _little_sons_con[3][2]=8; @@ -346,7 +347,7 @@ namespace INTERP_KERNEL _sons_con[2][0]=0; _sons_con[2][1]=3; _sons_con[2][2]=4; _sons_con[2][3]=1; _sons_con[2][4]=12; _sons_con[2][5]=9; _sons_con[2][6]=13; _sons_con[2][7]=6; _nb_of_sons_con[2]=8; _sons_con[3][0]=1; _sons_con[3][1]=4; _sons_con[3][2]=5; _sons_con[3][3]=2; _sons_con[3][4]=13; _sons_con[3][5]=10; _sons_con[3][6]=14; _sons_con[3][7]=7; _nb_of_sons_con[3]=8; _sons_con[4][0]=2; _sons_con[4][1]=4; _sons_con[4][2]=5; _sons_con[4][3]=0; _sons_con[4][4]=14; _sons_con[4][5]=11; _sons_con[4][6]=12; _sons_con[4][7]=8; _nb_of_sons_con[4]=8; _quadratic=true; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=6; _nb_of_little_sons=9; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=6; _nb_of_little_sons=9; _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=7; _little_sons_con[2][0]=2; _little_sons_con[2][1]=0; _little_sons_con[2][2]=8; _little_sons_con[3][0]=3; _little_sons_con[3][1]=4; _little_sons_con[3][2]=9; @@ -367,7 +368,7 @@ namespace INTERP_KERNEL _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][3]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9;_nb_of_sons_con[3]=8; _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][3]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _nb_of_sons_con[4]=8; _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][3]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _nb_of_sons_con[5]=8; _quadratic=true; - _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=8; _nb_of_little_sons=12; + _little_sons_con[0][0]=0; _little_sons_con[0][1]=1; _little_sons_con[0][2]=8; _nb_of_little_sons=12; _little_sons_con[1][0]=1; _little_sons_con[1][1]=2; _little_sons_con[1][2]=9; _little_sons_con[2][0]=2; _little_sons_con[2][1]=3; _little_sons_con[2][2]=10; _little_sons_con[3][0]=3; _little_sons_con[3][1]=0; _little_sons_con[3][2]=11; @@ -520,26 +521,40 @@ namespace INTERP_KERNEL throw INTERP_KERNEL::Exception("CellModel::fillSonCellNodalConnectivity2 : no sons on NORM_POLYL !"); } } + + /*! + * Equivalent to CellModel::fillSonCellNodalConnectivity2 except for HEXA8 where the order of sub faces is not has MED file numbering for transformation HEXA8->HEXA27 + */ + unsigned CellModel::fillSonCellNodalConnectivity4(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const + { + if(_type==NORM_HEXA8) + { + static const int permutation[6]={0,2,3,4,1}; + return fillSonCellNodalConnectivity2(permutation[sonId],nodalConn,lgth,sonNodalConn,typeOfSon); + } + else + return fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); + } unsigned CellModel::fillSonEdgesNodalConnectivity3D(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const { if(!isDynamic()) { - if(!isQuadratic()) - { - typeOfSon=NORM_SEG2; - sonNodalConn[0]=nodalConn[_little_sons_con[sonId][0]]; - sonNodalConn[1]=nodalConn[_little_sons_con[sonId][1]]; - return 2; - } - else - { - typeOfSon=NORM_SEG3; - sonNodalConn[0]=nodalConn[_little_sons_con[sonId][0]]; - sonNodalConn[1]=nodalConn[_little_sons_con[sonId][1]]; - sonNodalConn[2]=nodalConn[_little_sons_con[sonId][2]]; - return 3; - } + if(!isQuadratic()) + { + typeOfSon=NORM_SEG2; + sonNodalConn[0]=nodalConn[_little_sons_con[sonId][0]]; + sonNodalConn[1]=nodalConn[_little_sons_con[sonId][1]]; + return 2; + } + else + { + typeOfSon=NORM_SEG3; + sonNodalConn[0]=nodalConn[_little_sons_con[sonId][0]]; + sonNodalConn[1]=nodalConn[_little_sons_con[sonId][1]]; + sonNodalConn[2]=nodalConn[_little_sons_con[sonId][2]]; + return 3; + } } else throw INTERP_KERNEL::Exception("CellModel::fillSonEdgesNodalConnectivity3D : not implemented yet for NORM_POLYHED !"); diff --git a/src/INTERP_KERNEL/CellModel.hxx b/src/INTERP_KERNEL/CellModel.hxx index cff77c2de..fc8faa019 100644 --- a/src/INTERP_KERNEL/CellModel.hxx +++ b/src/INTERP_KERNEL/CellModel.hxx @@ -63,10 +63,12 @@ namespace INTERP_KERNEL INTERPKERNEL_EXPORT NormalizedCellType getReverseExtrudedType() const { return _reverse_extruded_type; } INTERPKERNEL_EXPORT NormalizedCellType getLinearType() const { return _linear_type; } INTERPKERNEL_EXPORT NormalizedCellType getQuadraticType() const { return _quadratic_type; } + INTERPKERNEL_EXPORT NormalizedCellType getQuadraticType2() const { return _quadratic_type2; } INTERPKERNEL_EXPORT NormalizedCellType getSonType(unsigned sonId) const { return _sons_type[sonId]; } INTERPKERNEL_EXPORT NormalizedCellType getSonType2(unsigned sonId) const; INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const; INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const; + INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity4(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const; INTERPKERNEL_EXPORT unsigned fillSonEdgesNodalConnectivity3D(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const; private: bool _dyn; @@ -82,6 +84,7 @@ namespace INTERP_KERNEL NormalizedCellType _reverse_extruded_type; NormalizedCellType _linear_type; NormalizedCellType _quadratic_type; + NormalizedCellType _quadratic_type2; unsigned _sons_con[MAX_NB_OF_SONS][MAX_NB_OF_NODES_PER_ELEM]; unsigned _little_sons_con[MAX_NB_OF_LITTLE_SONS][3]; unsigned _nb_of_sons_con[MAX_NB_OF_SONS]; diff --git a/src/INTERP_KERNEL/Interpolation.hxx b/src/INTERP_KERNEL/Interpolation.hxx index 3c5eab131..92c38349d 100644 --- a/src/INTERP_KERNEL/Interpolation.hxx +++ b/src/INTERP_KERNEL/Interpolation.hxx @@ -43,7 +43,7 @@ namespace INTERP_KERNEL int fromIntegralUniform(const MyMeshType& meshT, MatrixType& result, const char *method) { return fromToIntegralUniform(false,meshT,result,method); } template int toIntegralUniform(const MyMeshType& meshS, MatrixType& result, const char *method) { return fromToIntegralUniform(true,meshS,result,method); } - static void checkAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception); + static void CheckAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception); template static double CalculateCharacteristicSizeOfMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, const int printLevel); protected: diff --git a/src/INTERP_KERNEL/Interpolation.txx b/src/INTERP_KERNEL/Interpolation.txx index 201b44671..befbd4714 100644 --- a/src/INTERP_KERNEL/Interpolation.txx +++ b/src/INTERP_KERNEL/Interpolation.txx @@ -56,7 +56,7 @@ namespace INTERP_KERNEL } template - void Interpolation::checkAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception) + void Interpolation::CheckAndSplitInterpolationMethod(const char *method, std::string& srcMeth, std::string& trgMeth) throw(INTERP_KERNEL::Exception) { const int NB_OF_METH_MANAGED=4; const char *METH_MANAGED[NB_OF_METH_MANAGED]={"P0P0","P0P1","P1P0","P1P1"}; @@ -66,7 +66,7 @@ namespace INTERP_KERNEL found=(methodC==METH_MANAGED[i]); if(!found) { - std::string msg("The interpolation method : \'"); msg+=method; msg+="\' not managed !"; + std::string msg("The interpolation method : \'"); msg+=method; msg+="\' not managed by INTERP_KERNEL interpolators ! Supported are \"P0P0\", \"P0P1\", \"P1P0\" and \"P1P1\"."; throw INTERP_KERNEL::Exception(msg.c_str()); } srcMeth=methodC.substr(0,2); diff --git a/src/INTERP_KERNEL/Makefile.am b/src/INTERP_KERNEL/Makefile.am index a21327824..bb81f0a65 100644 --- a/src/INTERP_KERNEL/Makefile.am +++ b/src/INTERP_KERNEL/Makefile.am @@ -28,6 +28,7 @@ lib_LTLIBRARIES = libinterpkernel.la salomeinclude_HEADERS = \ BBTree.txx \ +BBTreePts.txx \ BoundingBox.hxx \ CellModel.hxx \ ConvexIntersector.hxx \ diff --git a/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx b/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx index a35c5b9dd..be5a38af3 100644 --- a/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx @@ -638,6 +638,8 @@ void MEDCouplingCurveLinearMesh::rotate(const double *center, const double *vect void MEDCouplingCurveLinearMesh::translate(const double *vector) { + if(!vector) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::translate : NULL input point !"); if(!((DataArrayDouble *)_coords)) throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::translate : no coordinates set !"); double *coords=_coords->getPointer(); @@ -652,6 +654,8 @@ void MEDCouplingCurveLinearMesh::translate(const double *vector) void MEDCouplingCurveLinearMesh::scale(const double *point, double factor) { + if(!point) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::scale : NULL input point !"); if(!((DataArrayDouble *)_coords)) throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::scale : no coordinates set !"); double *coords=_coords->getPointer(); diff --git a/src/MEDCoupling/MEDCouplingField.cxx b/src/MEDCoupling/MEDCouplingField.cxx index 7a11d759d..527ff74e4 100644 --- a/src/MEDCoupling/MEDCouplingField.cxx +++ b/src/MEDCoupling/MEDCouplingField.cxx @@ -344,14 +344,18 @@ MEDCouplingField::MEDCouplingField(TypeOfField type):_nature(NoNature),_mesh(0), { } -MEDCouplingField::MEDCouplingField(const MEDCouplingField& other):RefCountObject(other),_name(other._name),_desc(other._desc),_nature(other._nature), - _mesh(0),_type(other._type->clone()) +MEDCouplingField::MEDCouplingField(const MEDCouplingField& other, bool deepCopy):RefCountObject(other),_name(other._name),_desc(other._desc),_nature(other._nature), + _mesh(0),_type(0) { if(other._mesh) { _mesh=other._mesh; _mesh->incrRef(); } + if(deepCopy) + _type=other._type->clone(); + else + _type=other._type; } /*! diff --git a/src/MEDCoupling/MEDCouplingField.hxx b/src/MEDCoupling/MEDCouplingField.hxx index 06f5f5969..22b9345ef 100644 --- a/src/MEDCoupling/MEDCouplingField.hxx +++ b/src/MEDCoupling/MEDCouplingField.hxx @@ -86,7 +86,7 @@ namespace ParaMEDMEM std::size_t getHeapMemorySize() const; protected: MEDCouplingField(TypeOfField type); - MEDCouplingField(const MEDCouplingField& other); + MEDCouplingField(const MEDCouplingField& other, bool deepCopy=true); MEDCouplingField(MEDCouplingFieldDiscretization *type, NatureOfField nature=NoNature); virtual ~MEDCouplingField(); protected: diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx index b18ac9978..1c0c1ace6 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx @@ -101,7 +101,7 @@ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::New(TypeOfField } } -TypeOfField MEDCouplingFieldDiscretization::getTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception) +TypeOfField MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception) { std::string reprCpp(repr); if(reprCpp==MEDCouplingFieldDiscretizationP0::REPR) @@ -399,7 +399,7 @@ bool MEDCouplingFieldDiscretizationP0::isEqualIfNotWhy(const MEDCouplingFieldDis return ret; } -int MEDCouplingFieldDiscretizationP0::getNumberOfTuples(const MEDCouplingMesh *mesh) const +int MEDCouplingFieldDiscretizationP0::getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) { return mesh->getNumberOfCells(); } @@ -555,7 +555,7 @@ MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshData(const MEDCou return ret; } -int MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuples(const MEDCouplingMesh *mesh) const +int MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) { return mesh->getNumberOfNodes(); } @@ -988,9 +988,11 @@ const char *MEDCouplingFieldDiscretizationGauss::getRepr() const return REPR; } -int MEDCouplingFieldDiscretizationGauss::getNumberOfTuples(const MEDCouplingMesh *) const +int MEDCouplingFieldDiscretizationGauss::getNumberOfTuples(const MEDCouplingMesh *) const throw(INTERP_KERNEL::Exception) { int ret=0; + if (_discr_per_cell == 0) + throw INTERP_KERNEL::Exception("Discretization is not initialized!"); const int *dcPtr=_discr_per_cell->getConstPointer(); int nbOfTuples=_discr_per_cell->getNumberOfTuples(); for(const int *w=dcPtr;w!=dcPtr+nbOfTuples;w++) @@ -1446,7 +1448,7 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellFie /*! * This method makes the assumption that _discr_per_cell is set. * This method reduces as much as possible number size of _loc. - * This method is usefull when several set on same cells has been done and that some Gauss Localization are no more used. + * This method is useful when several set on same cells has been done and that some Gauss Localization are no more used. */ void MEDCouplingFieldDiscretizationGauss::zipGaussLocalizations() { @@ -1476,7 +1478,7 @@ void MEDCouplingFieldDiscretizationGauss::zipGaussLocalizations() } /*! - * This method is usefull when 'this' describes a field discretization with several gauss discretization on a \b same cell type. + * This method is useful when 'this' describes a field discretization with several gauss discretization on a \b same cell type. * For example same NORM_TRI3 cells having 6 gauss points and others with 12 gauss points. * This method returns 2 arrays with same size : the return value and 'locIds' output parameter. * For a given i into [0,locIds.size) ret[i] represents the set of cell ids of i_th set an locIds[i] represents the set of discretisation of the set. @@ -1525,7 +1527,7 @@ bool MEDCouplingFieldDiscretizationGaussNE::isEqualIfNotWhy(const MEDCouplingFie return ret; } -int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples(const MEDCouplingMesh *mesh) const +int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) { int ret=0; int nbOfCells=mesh->getNumberOfCells(); @@ -1602,6 +1604,9 @@ DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getLocalizationOfDiscVal throw INTERP_KERNEL::Exception("Not implemented yet !"); } +/*! + * Reimplemented from MEDCouplingFieldDiscretization::integral for performance reason. The default implementation is valid too for GAUSS_NE spatial discretization. + */ void MEDCouplingFieldDiscretizationGaussNE::integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception) { if(!mesh || !arr) @@ -1609,7 +1614,7 @@ void MEDCouplingFieldDiscretizationGaussNE::integral(const MEDCouplingMesh *mesh int nbOfCompo=arr->getNumberOfComponents(); std::fill(res,res+nbOfCompo,0.); // - MEDCouplingAutoRefCountObjectPtr vol=getMeasureField(mesh,isWAbs); + MEDCouplingAutoRefCountObjectPtr vol=mesh->getMeasureField(isWAbs); std::set types=mesh->getAllGeoTypes(); MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); nbOfNodesPerCell->computeOffsets2(); @@ -1723,7 +1728,35 @@ MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGaussNE::getMeasureField(c { if(!mesh) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getMeasureField : mesh instance specified is NULL !"); - throw INTERP_KERNEL::Exception("Not implemented yet !"); + MEDCouplingAutoRefCountObjectPtr vol=mesh->getMeasureField(isAbs); + const double *volPtr=vol->getArray()->begin(); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_GAUSS_NE); + ret->setMesh(mesh); + // + std::set types=mesh->getAllGeoTypes(); + MEDCouplingAutoRefCountObjectPtr nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); + int nbTuples=nbOfNodesPerCell->accumulate(0); + nbOfNodesPerCell->computeOffsets2(); + MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); arr->alloc(nbTuples,1); + ret->setArray(arr); + double *arrPtr=arr->getPointer(); + for(std::set::const_iterator it=types.begin();it!=types.end();it++) + { + std::size_t wArrSz=-1; + const double *wArr=GetWeightArrayFromGeometricType(*it,wArrSz); + INTERP_KERNEL::AutoPtr wArr2=new double[wArrSz]; + double sum=std::accumulate(wArr,wArr+wArrSz,0.); + std::transform(wArr,wArr+wArrSz,(double *)wArr2,std::bind2nd(std::multiplies(),1./sum)); + MEDCouplingAutoRefCountObjectPtr ids=mesh->giveCellsWithType(*it); + MEDCouplingAutoRefCountObjectPtr ids2=ids->buildExplicitArrByRanges(nbOfNodesPerCell); + const int *ptIds2=ids2->begin(),*ptIds=ids->begin(); + int nbOfCellsWithCurGeoType=ids->getNumberOfTuples(); + for(int i=0;isynchronizeTimeWithSupport(); + return ret.retn(); } void MEDCouplingFieldDiscretizationGaussNE::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx index c4930dc01..ad69756a9 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx @@ -47,7 +47,7 @@ namespace ParaMEDMEM void setPrecision(double val) { _precision=val; } void updateTime() const; std::size_t getHeapMemorySize() const; - static TypeOfField getTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception); + static TypeOfField GetTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception); virtual TypeOfField getEnum() const = 0; virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; virtual bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const = 0; @@ -56,7 +56,7 @@ namespace ParaMEDMEM virtual MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; virtual std::string getStringRepr() const = 0; virtual const char *getRepr() const = 0; - virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const = 0; + virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) = 0; virtual int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const = 0; virtual DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const = 0; virtual void normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception); @@ -115,7 +115,7 @@ namespace ParaMEDMEM std::string getStringRepr() const; const char *getRepr() const; bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, @@ -142,7 +142,7 @@ namespace ParaMEDMEM class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationOnNodes : public MEDCouplingFieldDiscretization { public: - int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, @@ -217,7 +217,7 @@ namespace ParaMEDMEM std::string getStringRepr() const; const char *getRepr() const; std::size_t getHeapMemorySize() const; - int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, @@ -280,7 +280,7 @@ namespace ParaMEDMEM std::string getStringRepr() const; const char *getRepr() const; bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index 03d44c8d0..fd0cb1740 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -26,6 +26,8 @@ #include "MEDCouplingAutoRefCountObjectPtr.hxx" #include "MEDCouplingNatureOfField.hxx" +#include "InterpKernelAutoPtr.hxx" + #include #include #include @@ -54,7 +56,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTime * \return a newly allocated field the caller should deal with. */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td) +MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td) { return new MEDCouplingFieldDouble(ft,td); } @@ -544,12 +546,12 @@ MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscr { } -MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td):MEDCouplingField(*ft), +MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingField(ft), _time_discr(MEDCouplingTimeDiscretization::New(td)) { } -MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other), +MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other,deepCopy), _time_discr(other._time_discr->performCpy(deepCopy)) { } @@ -751,17 +753,44 @@ double MEDCouplingFieldDouble::normMax() const throw(INTERP_KERNEL::Exception) * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown. * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default. * If default array does not exist, an exception will be thrown. + * + * \param [out] res the location where the result will be stored. \a res is expected to be a location with \c this->getNumberOfComponents() places available. + * \param [in] isWAbs specifies if abs is applied on measure on underlying mesh before performing computation. For a user already sure that all cells of its underlying mesh + * are all well oriented this parameter can be set to false to be 'faster'. By default this parameter is true. */ -double MEDCouplingFieldDouble::getWeightedAverageValue() const throw(INTERP_KERNEL::Exception) +void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const throw(INTERP_KERNEL::Exception) { if(getArray()==0) throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !"); - MEDCouplingFieldDouble *w=buildMeasureField(true); + MEDCouplingAutoRefCountObjectPtr w=buildMeasureField(isWAbs); double deno=w->getArray()->accumulate(0); - w->getArray()->multiplyEqual(getArray()); - double res=w->getArray()->accumulate(0); - w->decrRef(); - return res/deno; + MEDCouplingAutoRefCountObjectPtr arr=getArray()->deepCpy(); + arr->multiplyEqual(w->getArray()); + std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::multiplies(),1./deno)); + arr->accumulate(res); +} + +/*! + * This method returns the average value in \a this weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField. + * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown. + * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default. + * If default array does not exist, an exception will be thrown. + * + * \param [in] compId The component id that should be in [0, \c this->getNumberOfComponents() ). If not an INTERP_KERNEL::Exception will be thrown. + * \param [in] isWAbs specifies if abs is applied on measure on underlying mesh before performing computation. For a user already sure that all cells of its underlying mesh + * are all well oriented this parameter can be set to false to be 'faster'. By default this parameter is true in C++ not in python (overloading confusion). + */ +double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception) +{ + int nbComps=getArray()->getNumberOfComponents(); + if(compId<0 || compId>=nbComps) + { + std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + INTERP_KERNEL::AutoPtr res=new double[nbComps]; + getWeightedAverageValue(res,isWAbs); + return res[compId]; } /*! @@ -776,21 +805,14 @@ double MEDCouplingFieldDouble::normL1(int compId) const throw(INTERP_KERNEL::Exc if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1"); int nbComps=getArray()->getNumberOfComponents(); - if(compId>=nbComps) - throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !"); - double *res=new double[nbComps]; - try - { - _type->normL1(_mesh,getArray(),res); - } - catch(INTERP_KERNEL::Exception& e) + if(compId<0 || compId>=nbComps) { - delete [] res; - throw e; + std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - double ret=res[compId]; - delete [] res; - return ret; + INTERP_KERNEL::AutoPtr res=new double[nbComps]; + _type->normL1(_mesh,getArray(),res); + return res[compId]; } /*! @@ -819,21 +841,14 @@ double MEDCouplingFieldDouble::normL2(int compId) const throw(INTERP_KERNEL::Exc if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2"); int nbComps=getArray()->getNumberOfComponents(); - if(compId>=nbComps) - throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !"); - double *res=new double[nbComps]; - try - { - _type->normL2(_mesh,getArray(),res); - } - catch(INTERP_KERNEL::Exception& e) + if(compId<0 || compId>=nbComps) { - delete [] res; - throw e; + std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - double ret=res[compId]; - delete [] res; - return ret; + INTERP_KERNEL::AutoPtr res=new double[nbComps]; + _type->normL2(_mesh,getArray(),res); + return res[compId]; } /*! @@ -853,34 +868,27 @@ void MEDCouplingFieldDouble::normL2(double *res) const throw(INTERP_KERNEL::Exce /*! * Returns the accumulation (the sum) of comId_th component of each tuples weigthed by the field * returns by getWeightingField relative of the _type of field of default array. - * This method is usefull to check the conservativity of interpolation method. + * This method is useful to check the conservativity of interpolation method. */ double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception) { if(!_mesh) throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral"); int nbComps=getArray()->getNumberOfComponents(); - if(compId>=nbComps) - throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !"); - double *res=new double[nbComps]; - try - { - _type->integral(_mesh,getArray(),isWAbs,res); - } - catch(INTERP_KERNEL::Exception& e) + if(compId<0 || compId>=nbComps) { - delete [] res; - throw e; + std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } - double ret=res[compId]; - delete [] res; - return ret; + INTERP_KERNEL::AutoPtr res=new double[nbComps]; + _type->integral(_mesh,getArray(),isWAbs,res); + return res[compId]; } /*! * Returns the accumulation (the sum) of each tuples weigthed by the field * returns by getWeightingField relative of the _type of field of default array. - * This method is usefull to check the conservativity of interpolation method. + * This method is useful to check the conservativity of interpolation method. */ void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception) { diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index da5e01ba0..76fb40f41 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -34,7 +34,7 @@ namespace ParaMEDMEM { public: static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); - static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=ONE_TIME); + static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); void setTimeUnit(const char *unit); const char *getTimeUnit() const; void synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception); @@ -99,7 +99,8 @@ namespace ParaMEDMEM double getAverageValue() const throw(INTERP_KERNEL::Exception); double norm2() const throw(INTERP_KERNEL::Exception); double normMax() const throw(INTERP_KERNEL::Exception); - double getWeightedAverageValue() const throw(INTERP_KERNEL::Exception); + void getWeightedAverageValue(double *res, bool isWAbs=true) const throw(INTERP_KERNEL::Exception); + double getWeightedAverageValue(int compId, bool isWAbs=true) const throw(INTERP_KERNEL::Exception); double normL1(int compId) const throw(INTERP_KERNEL::Exception); void normL1(double *res) const throw(INTERP_KERNEL::Exception); double normL2(int compId) const throw(INTERP_KERNEL::Exception); @@ -188,7 +189,7 @@ namespace ParaMEDMEM MEDCouplingTimeDiscretization *getTimeDiscretizationUnderGround() { return _time_discr; } private: MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td); - MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td); + MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td); MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy); MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); ~MEDCouplingFieldDouble(); diff --git a/src/MEDCoupling/MEDCouplingFieldTemplate.cxx b/src/MEDCoupling/MEDCouplingFieldTemplate.cxx index 628ee6b72..a94b6700a 100644 --- a/src/MEDCoupling/MEDCouplingFieldTemplate.cxx +++ b/src/MEDCoupling/MEDCouplingFieldTemplate.cxx @@ -27,7 +27,7 @@ using namespace ParaMEDMEM; -MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception) +MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception) { return new MEDCouplingFieldTemplate(f); } @@ -40,8 +40,9 @@ MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(TypeOfField type) return new MEDCouplingFieldTemplate(type); } -MEDCouplingFieldTemplate::MEDCouplingFieldTemplate(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception):MEDCouplingField(*f) +MEDCouplingFieldTemplate::MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception):MEDCouplingField(f,false) { + forceTimeOfThis(f); checkCoherency(); } diff --git a/src/MEDCoupling/MEDCouplingFieldTemplate.hxx b/src/MEDCoupling/MEDCouplingFieldTemplate.hxx index d93411ecb..562fdc7ed 100644 --- a/src/MEDCoupling/MEDCouplingFieldTemplate.hxx +++ b/src/MEDCoupling/MEDCouplingFieldTemplate.hxx @@ -30,7 +30,7 @@ namespace ParaMEDMEM class MEDCOUPLING_EXPORT MEDCouplingFieldTemplate : public MEDCouplingField { public: - static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception); static MEDCouplingFieldTemplate *New(TypeOfField type); std::string simpleRepr() const; std::string advancedRepr() const; @@ -44,7 +44,7 @@ namespace ParaMEDMEM void serialize(DataArrayInt *&dataInt) const; // private: - MEDCouplingFieldTemplate(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception); MEDCouplingFieldTemplate(TypeOfField type); }; } diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index a49ba2d8d..1e87420cc 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -84,6 +84,30 @@ void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree& myTr } } +template +void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res) +{ + double distOpt(dist); + const double *p(pos); + int *r(res); + for(int i=0;i::max()) + { + distOpt=std::max(ret,1e-4); + *r=elem; + break; + } + else + { distOpt=2*distOpt; continue; } + } + } +} + std::size_t DataArray::getHeapMemorySize() const { std::size_t sz1=_name.capacity(); @@ -94,11 +118,26 @@ std::size_t DataArray::getHeapMemorySize() const return sz1+sz2+sz3; } +/*! + * Sets the attribute \a _name of \a this array. + * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. + * \param [in] name - new array name + */ void DataArray::setName(const char *name) { _name=name; } +/*! + * Copies textual data from an \a other DataArray. The copied data are + * - the name attribute, + * - the information of components. + * + * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos". + * + * \param [in] other - another instance of DataArray to copy the textual data from. + * \throw If number of components of \a this array differs from that of the \a other. + */ void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception) { if(_info_on_compo.size()!=other._info_on_compo.size()) @@ -160,6 +199,16 @@ bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reaso return true; } +/*! + * Compares textual information of \a this DataArray with that of an \a other one. + * The compared data are + * - the name attribute, + * - the information of components. + * + * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos". + * \param [in] other - another instance of DataArray to compare the textual data of. + * \return bool - \a true if the textual information is same, \a false else. + */ bool DataArray::areInfoEquals(const DataArray& other) const { std::string tmp; @@ -182,6 +231,12 @@ std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::E return ret.str(); } +/*! + * Sets information on all components. To know more on format of this information + * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] info - a vector of strings. + * \throw If size of \a info differs from the number of components of \a this. + */ void DataArray::setInfoOnComponents(const std::vector& info) throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=(int)info.size()) @@ -210,6 +265,14 @@ std::vector DataArray::getUnitsOnComponent() const return ret; } +/*! + * Returns information on a component specified by an index. + * To know more on format of this information + * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] i - the index (zero based) of the component of interest. + * \return std::string - a string containing the information on \a i-th component. + * \throw If \a i is not a valid component index. + */ std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception) { if(i<(int)_info_on_compo.size() && i>=0) @@ -222,8 +285,16 @@ std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exce } /*! - * In the info part of i_th component this method returns the var part. - * For example, if getInfoOnComponent(0) return "SIGXY (N/m^2)", getVarOnComponent(0) will return "SIGXY" + * Returns the var part of the full information of the \a i-th component. + * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then + * \c getVarOnComponent(0) returns "SIGXY". + * If a unit part of information is not detected by presence of + * two square brackets, then the full information is returned. + * To read more about the component information format, see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] i - the index (zero based) of the component of interest. + * \return std::string - a string containing the var information, or the full info. + * \throw If \a i is not a valid component index. */ std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception) { @@ -239,8 +310,16 @@ std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Excep } /*! - * In the info part of i_th component this method returns the var part. - * For example, if getInfoOnComponent(0) return "SIGXY (N/m^2)", getUnitOnComponent(0) will return "N/m^2" + * Returns the unit part of the full information of the \a i-th component. + * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then + * \c getUnitOnComponent(0) returns " N/m^2". + * If a unit part of information is not detected by presence of + * two square brackets, then an empty string is returned. + * To read more about the component information format, see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] i - the index (zero based) of the component of interest. + * \return std::string - a string containing the unit information, if any, or "". + * \throw If \a i is not a valid component index. */ std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception) { @@ -255,6 +334,16 @@ std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exce } } +/*! + * Returns the var part of the full component information. + * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY". + * If a unit part of information is not detected by presence of + * two square brackets, then the whole \a info is returned. + * To read more about the component information format, see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] info - the full component information. + * \return std::string - a string containing only var information, or the \a info. + */ std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception) { std::size_t p1=info.find_last_of('['); @@ -269,6 +358,16 @@ std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_ return info.substr(0,p3+1); } +/*! + * Returns the unit part of the full component information. + * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2". + * If a unit part of information is not detected by presence of + * two square brackets, then an empty string is returned. + * To read more about the component information format, see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] info - the full component information. + * \return std::string - a string containing only unit information, if any, or "". + */ std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception) { std::size_t p1=info.find_last_of('['); @@ -280,6 +379,15 @@ std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KER return info.substr(p1+1,p2-p1-1); } +/*! + * Sets information on a component specified by an index. + * To know more on format of this information + * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] i - the index (zero based) of the component of interest. + * \param [in] info - the string containing the information. + * \throw If \a i is not a valid component index. + * \warning Don't pass NULL as \a info! + */ void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception) { if(i<(int)_info_on_compo.size() && i>=0) @@ -450,16 +558,29 @@ int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end return -1; } +/*! + * Returns a new instance of DataArrayDouble. The caller is to delete this array + * using decrRef() as it is no more needed. + */ DataArrayDouble *DataArrayDouble::New() { return new DataArrayDouble; } +/*! + * Checks if raw data is allocated. Read more on the raw data + * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. + * \return bool - \a true if the raw data is allocated, \a false else. + */ bool DataArrayDouble::isAllocated() const { return getConstPointer()!=0; } +/*! + * Checks if raw data is allocated and throws an exception if it is not the case. + * \throw If the raw data is not allocated. + */ void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception) { if(!isAllocated()) @@ -474,10 +595,14 @@ std::size_t DataArrayDouble::getHeapMemorySize() const } /*! - * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()' - * and if 'this' is not allocated it will change the number of components of 'this'. - * If 'this->getNumberOfComponents()==info.size()' the behaviour is the same than DataArray::setInfoOnComponents method. - * If 'this->getNumberOfComponents()!=info.size()' and the 'this' is already allocated an exception will be thrown. + * Sets information on all components. This method can change number of components + * at certain conditions; if the conditions are not respected, an exception is thrown. + * The number of components can be changed provided that \a this is not allocated. + * + * To know more on format of the component information see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] info - a vector of component infos. + * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated() */ void DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception) { @@ -496,8 +621,10 @@ void DataArrayDouble::setInfoAndChangeNbOfCompo(const std::vector& } /*! - * This method returns the only one value in 'this', if and only if number of elements (nb of tuples * nb of components) is equal to 1, and that 'this' is allocated. - * If one or more conditions is not fulfilled an exception will be thrown. + * Returns the only one value in \a this, if and only if number of elements + * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. + * \return double - the sole value stored in \a this array. + * \throw If at least one of conditions stated above is not fulfilled. */ double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception) { @@ -515,8 +642,9 @@ double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception) } /*! - * This method should be called on an allocated DataArrayDouble instance. If not an exception will be throw ! - * This method checks the number of tupes. If it is equal to 0, it returns true, if not false is returned. + * Checks the number of tuples. + * \return bool - \a true if getNumberOfTuples() == 0, \a false else. + * \throw If \a this is not allocated. */ bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception) { @@ -524,11 +652,23 @@ bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception) return getNumberOfTuples()==0; } +/*! + * Returns a full copy of \a this. For more info on copying data arrays see + * \ref MEDCouplingArrayBasicsCopyDeep. + * \return DataArrayDouble * - a new instance of DataArrayDouble. + */ DataArrayDouble *DataArrayDouble::deepCpy() const { return new DataArrayDouble(*this); } +/*! + * Returns either a \a deep or \a shallow copy of this array. For more info see + * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow. + * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one. + * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy + * == \a true) or \a this instance (if \a dCpy == \a false). + */ DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const { if(dCpy) @@ -540,6 +680,12 @@ DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const } } +/*! + * Copies all the data from another DataArrayDouble. For more info see + * \ref MEDCouplingArrayBasicsCopyDeepAssign. + * \param [in] other - another instance of DataArrayDouble to copy data from. + * \throw If the \a other is not allocated. + */ void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception) { other.checkAllocated(); @@ -554,6 +700,14 @@ void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL: copyStringInfoFrom(other); } +/*! + * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this. + * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown. + * If \a this has not already been allocated, number of components is set to one. + * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this. + * + * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent + */ void DataArrayDouble::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception) { int nbCompo=getNumberOfComponents(); @@ -570,6 +724,14 @@ void DataArrayDouble::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !"); } +/*! + * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation + * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. + * + * \param [in] val the value to be added in \a this + * \throw If \a this has already been allocated with number of components different from one. + * \sa DataArrayDouble::pushBackValsSilent + */ void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception) { int nbCompo=getNumberOfComponents(); @@ -584,6 +746,16 @@ void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !"); } +/*! + * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation + * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. + * + * \param [in] valsBg - an array of values to push at the end of \this. + * \param [in] valsEnd - specifies the end of the array \a valsBg, so that + * the last value of \a valsBg is \a valsEnd[ -1 ]. + * \throw If \a this has already been allocated with number of components different from one. + * \sa DataArrayDouble::pushBackSilent + */ void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception) { int nbCompo=getNumberOfComponents(); @@ -598,6 +770,11 @@ void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *val throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !"); } +/*! + * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it. + * \throw If \a this is already empty. + * \throw If \a this has number of components different from one. + */ double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()==1) @@ -606,11 +783,23 @@ double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !"); } +/*! + * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store. + * + * \sa DataArrayDouble::getHeapMemorySize, DataArrayDouble::reserve + */ void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception) { _mem.pack(); } +/*! + * Allocates the raw data in memory. If exactly same memory as needed already + * allocated, it is not re-allocated. + * \param [in] nbOfTuple - number of tuples of data to allocate. + * \param [in] nbOfCompo - number of components of data to allocate. + * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0. + */ void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) { if(isAllocated()) @@ -622,6 +811,14 @@ void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) alloc(nbOfTuple,nbOfCompo); } +/*! + * Allocates the raw data in memory. If the memory was already allocated, then it is + * freed and re-allocated. See an example of this method use + * \ref MEDCouplingArraySteps1WC "here". + * \param [in] nbOfTuple - number of tuples of data to allocate. + * \param [in] nbOfCompo - number of components of data to allocate. + * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0. + */ void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception) { if(nbOfTuple<0 || nbOfCompo<0) @@ -631,6 +828,11 @@ void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::E declareAsNew(); } +/*! + * Assign zero to all values in \a this array. To know more on filling arrays see + * \ref MEDCouplingArrayFill. + * \throw If \a this is not allocated. + */ void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -638,6 +840,12 @@ void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Assign \a val to all values in \a this array. To know more on filling arrays see + * \ref MEDCouplingArrayFill. + * \param [in] val - the value to fill with. + * \throw If \a this is not allocated. + */ void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -645,6 +853,13 @@ void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Set all values in \a this array so that the i-th element equals to \a init + i + * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill. + * \param [in] init - value to assign to the first element of array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this is not allocated. + */ void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -657,6 +872,15 @@ void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Checks if all values in \a this array are equal to \a val at precision \a eps. + * \param [in] val - value to check equality of array values to. + * \param [in] eps - precision to check the equality. + * \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_), + * \a false else. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this is not allocated. + */ bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -673,6 +897,12 @@ bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNE return true; } +/*! + * Sorts values of the array. + * \param [in] asc - \a true means ascending order, \a false, descending. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + */ void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -681,6 +911,11 @@ void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception) _mem.sort(asc); } +/*! + * Reverse the array values. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. + */ void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -690,11 +925,18 @@ void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception) } /*! - * This method check that (Maths) array consistently INCREASING or DECREASING in value, - * with at least absolute difference value of |eps| at each step. - * if not an exception will be thrown. + * Checks that \a this array is consistently **increasing** or **decreasing** in value, + * with at least absolute difference value of |\a eps| at each step. + * If not an exception is thrown. + * \param [in] increasing - if \a true, the array values should be increasing. + * \param [in] eps - minimal absolute difference between the neighbor values at which + * the values are considered different. + * \throw If sequence of values is not strictly monotonic in agreement with \a + * increasing arg. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. */ - void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception) +void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception) { if(!isMonotonic(increasing,eps)) { @@ -706,8 +948,14 @@ void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception) } /*! - * This method check that (Maths) array consistently INCREASING or DECREASING in value, - * with at least absolute difference value of |eps| at each step. + * Checks that \a this array is consistently **increasing** or **decreasing** in value, + * with at least absolute difference value of |\a eps| at each step. + * \param [in] increasing - if \a true, array values should be increasing. + * \param [in] eps - minimal absolute difference between the neighbor values at which + * the values are considered different. + * \return bool - \a true if values change in accordance with \a increasing arg. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. */ bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception) { @@ -742,6 +990,11 @@ bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTER } } +/*! + * Returns a textual and human readable representation of \a this instance of + * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python. + * \return std::string - text describing \a this DataArrayDouble. + */ std::string DataArrayDouble::repr() const { std::ostringstream ret; @@ -817,18 +1070,38 @@ bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, return _mem.isEqual(other._mem,prec,reason); } +/*! + * Checks if \a this and another DataArrayDouble are fully equal. For more info see + * \ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayDouble to compare with \a this one. + * \param [in] prec - precision value to compare numeric data of the arrays. + * \return bool - \a true if the two arrays are equal, \a false else. + */ bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const { std::string tmp; return isEqualIfNotWhy(other,prec,tmp); } +/*! + * Checks if values of \a this and another DataArrayDouble are equal. For more info see + * \ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayDouble to compare with \a this one. + * \param [in] prec - precision value to compare numeric data of the arrays. + * \return bool - \a true if the values of two arrays are equal, \a false else. + */ bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const { std::string tmp; return _mem.isEqual(other._mem,prec,tmp); } +/*! + * Changes number of tuples in the array. If the new number of tuples is smaller + * than the current number the array is truncated, otherwise the array is extended. + * \param [in] nbOfTuples - new number of tuples. + * \throw If \a this is not allocated. + */ void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -836,6 +1109,11 @@ void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this + * array to the new one. + * \return DataArrayInt * - the new instance of DataArrayInt. + */ DataArrayInt *DataArrayDouble::convertToIntArr() const { DataArrayInt *ret=DataArrayInt::New(); @@ -848,6 +1126,16 @@ DataArrayInt *DataArrayDouble::convertToIntArr() const return ret; } +/*! + * Returns a new DataArrayDouble holding the same values as \a this array but differently + * arranged in memory. If \a this array holds 2 components of 3 values: + * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged + * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \warning Do not confuse this method with transpose()! + */ DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception) { if(_mem.isNull()) @@ -858,6 +1146,16 @@ DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::E return ret; } +/*! + * Returns a new DataArrayDouble holding the same values as \a this array but differently + * arranged in memory. If \a this array holds 2 components of 3 values: + * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged + * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \warning Do not confuse this method with transpose()! + */ DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception) { if(_mem.isNull()) @@ -869,8 +1167,13 @@ DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exc } /*! - * This method does \b not change the number of tuples after this call. - * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used. + * Permutes values of \a this array as required by \a old2New array. The values are + * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains + * the same as in \this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old value. */ void DataArrayDouble::renumberInPlace(const int *old2New) { @@ -887,8 +1190,14 @@ void DataArrayDouble::renumberInPlace(const int *old2New) } /*! - * This method does \b not change the number of tuples after this call. - * Only a permutation is done. + * Permutes values of \a this array as required by \a new2Old array. The values are + * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains + * the same as in \this one. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() + * giving a previous position of i-th new value. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. */ void DataArrayDouble::renumberInPlaceR(const int *new2Old) { @@ -905,8 +1214,16 @@ void DataArrayDouble::renumberInPlaceR(const int *new2Old) } /*! - * This method does \b not change the number of tuples after this call. - * Only a permutation is done. If a permutation reduction is needed renumberAndReduce. + * Returns a copy of \a this array with values permuted as required by \a old2New array. + * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. + * Number of tuples in the result array remains the same as in \this one. + * If a permutation reduction is needed, renumberAndReduce() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old value. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. */ DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const { @@ -925,8 +1242,15 @@ DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const } /*! - * This method does \b not change the number of tuples after this call. - * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used. + * Returns a copy of \a this array with values permuted as required by \a new2Old array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of + * tuples in the result array remains the same as in \this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() + * giving a previous position of i-th new value. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. */ DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const { @@ -945,10 +1269,17 @@ DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const } /*! - * Idem DataArrayDouble::renumber method except that the number of tuples is reduced. - * That is to say that it is expected that newNbOfTuplegetNumberOfTuples(). - * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'+getNumberOfTuples()) the corresponding tuple is - * omitted. + * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is + * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array. + * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all + * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which + * \a old2New[ i ] is negative, is missing from the result array. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old tuple and giving negative position for + * for i-th old tuple that should be omitted. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. */ DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const { @@ -970,8 +1301,20 @@ DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newN } /*! - * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here. - * This method is equivalent to DataArrayDouble::renumberAndReduce except that convention in input is new2old and \b not old2new. + * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is + * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by + * \a new2OldBg array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. + * This method is equivalent to renumberAndReduce() except that convention in input is + * \c new2old and \b not \c old2new. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a + * tuple index in \a this array to fill the i-th tuple in the new array. + * \param [in] new2OldEnd - specifies the end of the permutation array that starts at + * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: + * \a new2OldBg <= \a pi < \a new2OldEnd. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. */ DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const { @@ -990,7 +1333,23 @@ DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const in } /*! - * This method is equivalent to DataArrayDouble::selectByTupleId except that an analyze to the content of input range to check that it will not lead to memory corruption ! + * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is + * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by + * \a new2OldBg array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. + * This method is equivalent to renumberAndReduce() except that convention in input is + * \c new2old and \b not \c old2new. + * This method is equivalent to selectByTupleId() except that it prevents coping data + * from behind the end of \a this array. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a + * tuple index in \a this array to fill the i-th tuple in the new array. + * \param [in] new2OldEnd - specifies the end of the permutation array that starts at + * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: + * \a new2OldBg <= \a pi < \a new2OldEnd. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples(). */ DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception) { @@ -1013,12 +1372,20 @@ DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, cons } /*! - * Idem than DataArrayInt::selectByTupleIdSafe except that the input array is not constructed explicitely. - * The convention is as python one. ['bg','end2') with steps of 'step'. - * Returns a newly created array. - * This method is a generalization of DataArrayDouble::substr. - * - * \sa DataArrayDouble::substr + * Returns a shorten copy of \a this array. The new DataArrayDouble contains every + * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th + * tuple. Indices of the selected tuples are the same as ones returned by the Python + * command \c range( \a bg, \a end2, \a step ). + * This method is equivalent to selectByTupleIdSafe() except that the input array is + * not constructed explicitly. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] bg - index of the first tuple to copy from \a this array. + * \param [in] end2 - index of the tuple before which the tuples to copy are located. + * \param [in] step - index increment to get index of the next tuple to copy. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If (\a end2 < \a bg) or (\a step <= 0). + * \sa DataArrayDouble::substr. */ DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception) { @@ -1036,9 +1403,16 @@ DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) c } /*! - * This method returns a newly allocated array that is the concatenation of all tuples ranges in param 'ranges'. - * Each pair in input 'ranges' is in [begin,end) format. If there is a range in 'ranges' so that end is before begin an exception - * will be thrown. If there is a range in 'ranges' so that end is greater than number of tuples of 'this', an exception will be thrown too. + * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges + * of tuples specified by \a ranges parameter. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] ranges - std::vector of std::pair's each of which defines a range + * of tuples in [\c begin,\c end) format. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a end < \a begin. + * \throw If \a end > \a this->getNumberOfTuples(). + * \throw If \a this is not allocated. */ DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception) { @@ -1093,12 +1467,19 @@ DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vectorend()) will be kept. - * This method check that interval is valid regarding this, if not an exception will be thrown. - * This method is a specialization of method DataArrayDouble::selectByTupleId2. - * - * \sa DataArrayDouble::selectByTupleId2 + * Returns a shorten copy of \a this array. The new DataArrayDouble contains all + * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before + * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr(). + * This method is a specialization of selectByTupleId2(). + * \param [in] tupleIdBg - index of the first tuple to copy from \a this array. + * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located. + * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a tupleIdBg < 0. + * \throw If \a tupleIdBg > \a this->getNumberOfTuples(). + \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples(). + * \sa DataArrayDouble::selectByTupleId2 */ DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception) { @@ -1125,9 +1506,17 @@ DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const th } /*! - * This method builds a new instance of DataArrayDouble (to deal with) that is reduction or an extension of 'this'. - * if 'newNbOfComp' < this->getNumberOfComponents() a reduction is done and for each tuple 'newNbOfComp' first components are kept. - * If 'newNbOfComp' > this->getNumberOfComponents() an extension is done, and for each components i such that i > getNumberOfComponents() 'dftValue' parameter is taken. + * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less + * than \a this->getNumberOfComponents() then the result array is shorten as each tuple + * is truncated to have \a newNbOfComp components, keeping first components. If \a + * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is + * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp + * components. + * \param [in] newNbOfComp - number of components for the new array to have. + * \param [in] dftValue - value assigned to new values added to the new array. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. */ DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception) { @@ -1155,11 +1544,12 @@ DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double d } /*! - * Contrary to DataArrayDouble::changeNbOfComponents method this method is \b not const. The content - * This method \b do \b not change the content of data but changes the splitting of this data seen by the caller. - * This method makes the assumption that 'this' is already allocated. If not an exception will be thrown. - * This method checks that getNbOfElems()%newNbOfCompo==0. If not an exception will be throw ! - * This method erases all components info set before call ! + * Changes the number of components within \a this array so that its raw data **does + * not** change, instead splitting this data into tuples changes. + * \param [in] newNbOfComp - number of components for \a this array to have. + * \throw If \a this is not allocated + * \throw If getNbOfElems() % \a newNbOfCompo != 0. + * \warning This method erases all (name and unit) component info set before! */ void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception) { @@ -1173,9 +1563,14 @@ void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception } /*! - * This method makes the assumption that \b this is allocated. If not an INTERP_KERNEL::Exception will be raised. - * This method does not echange the values stored in \b this. Simply, the number of components before the call becomes the number of - * tuples and inversely the number of tuples becomes the number of components. \b WARNING the info on components can be alterated by this method. + * Changes the number of components within \a this array to be equal to its number + * of tuples, and inversely its number of tuples to become equal to its number of + * components. So that its raw data **does not** change, instead splitting this + * data into tuples changes. + * \throw If \a this is not allocated. + * \warning This method erases all (name and unit) component info set before! + * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()! + * \sa rearrange() */ void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception) { @@ -1184,6 +1579,21 @@ void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception) rearrange(nbOfTuples); } +/*! + * Returns a copy of \a this array composed of selected components. + * The new DataArrayDouble has the same number of tuples but includes components + * specified by \a compoIds parameter. So that getNbOfElems() of the result array + * can be either less, same or more than \a this->getNbOfElems(). + * \param [in] compoIds - sequence of zero based indices of components to include + * into the new array. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If a component index (\a i) is not valid: + * \a i < 0 || \a i >= \a this->getNumberOfComponents(). + * + * \ref cpp_mcdataarraydouble_keepselectedcomponents "Here is a Python example". + */ DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -1208,10 +1618,16 @@ DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& } /*! - * This method melds the components of 'this' with components of 'other'. - * After this call in case of success, 'this' will contain a number of components equal to the sum of 'this' - * before the call and the number of components of 'other'. - * This method expects that 'this' and 'other' have exactly the same number of tuples. If not an exception is thrown. + * Appends components of another array to components of \a this one, tuple by tuple. + * So that the number of tuples of \a this array remains the same and the number of + * components increases. + * \param [in] other - the DataArrayDouble to append to \a this one. + * \throw If \a this is not allocated. + * \throw If \a this and \a other arrays have different number of tuples. + * + * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example". + * + * \ref py_mcdataarraydouble_meldwith "Here is a Python example". */ void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { @@ -1239,19 +1655,36 @@ void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL } /*! - * This methods searches for each tuple if there are any tuples in 'this' that are less far than 'prec' from n1. if any, these tuples are stored in out params - * comm and commIndex. The distance is computed using norm2. This method expects that 'this' is allocated and that the number of components is in [1,2,3]. - * If not an exception will be thrown. - * This method is typically used by MEDCouplingPointSet::findCommonNodes and MEDCouplingUMesh::mergeNodes. - * In case of success, commIndex->getNumberOfTuples()-1 gives the number of tuples groupes that are within distance 'prec'. - * comm->getNumberOfTuples()==commIndex->back() - * The returned pair of DataArrayInt instances ('comm','commIndex') is called Surjectived Format 2 \sa DataArrayInt::BuildNew2OldArrayFromSurjectiveFormat2. - * This format is more compact in surjective format because only all tuple ids not in 'comm' are remain unchanged. - * - * @param prec is an absolute precision. - * @param limitTupleId is the limit tuple id. All tuples which id is strictly lower than 'limiTupleId' will not be merged each other. - * @param comm out parameter (not inout). Number of components is equal to 1. - * @param commIndex out parameter (not inout). Number of components is equal to 1. + * Searches for tuples coincident within \a prec tolerance. Each tuple is considered + * as coordinates of a point in getNumberOfComponents()-dimensional space. The + * distance is computed using norm2. + * + * Indices of coincident tuples are stored in output arrays. + * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2". + * + * This method is typically used by MEDCouplingPointSet::findCommonNodes() and + * MEDCouplingUMesh::mergeNodes(). + * \param [in] prec - minimal absolute distance between two tuples at which they are + * considered not coincident. + * \param [in] limitTupleId - limit tuple id. Tuples with id strictly lower than \a + * limitTupleId are not considered. + * \param [out] comm - the array holding ids (== indices) of coincident tuples. + * \a comm->getNumberOfComponents() == 1. + * \a comm->getNumberOfTuples() == \a commIndex->back(). + * \param [out] commIndex - the array dividing all indices stored in \a comm into + * groups of (indices of) coincident tuples. Its every value is a tuple + * index where a next group of tuples begins. For example the second + * group of tuples in \a comm is described by following range of indices: + * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1 + * gives the number of groups of coincident tuples. + * \throw If \a this is not allocated. + * \throw If \a this and \a other arrays have different number of tuples. + * \throw If the number of components is not in [1,2,3]. + * + * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example". + * + * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example". + * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(). */ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception) { @@ -1312,13 +1745,109 @@ DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const th } /*! - * This method returns a newly allocated object the user should deal with. - * This method works for arrays which have number of components into [1,2,3]. If not an exception will be thrown. - * This method returns the different values in 'this' using 'prec'. The different values are kept in the same - * order than 'this'. That is to say that returned DataArrayDouble instance is not systematically sorted. + * This methods returns the minimal distance between the two set of points \a this and \a other. + * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown. + * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3. + * + * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance + * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance + * \return the minimal distance between the two set of points \a this and \a other. + * \sa DataArrayDouble::findClosestTupleId + */ +double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr part1=findClosestTupleId(other); + int nbOfCompo(getNumberOfComponents()); + int otherNbTuples(other->getNumberOfTuples()); + const double *thisPt(begin()),*otherPt(other->begin()); + const int *part1Pt(part1->begin()); + double ret=std::numeric_limits::max(); + for(int i=0;igetNumberOfTuples() tuples and one components. + * \sa DataArrayDouble::minimalDistanceTo + */ +DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !"); + checkAllocated(); other->checkAllocated(); + int nbOfCompo=getNumberOfComponents(); + if(nbOfCompo!=other->getNumberOfComponents()) + { + std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo; + oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfTuples=other->getNumberOfTuples(); + int thisNbOfTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); + double bounds[6]; + getMinMaxPerComponent(bounds); + switch(nbOfCompo) + { + case 3: + { + double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4])); + double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta); + double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.); + BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12); + FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer()); + break; + } + case 2: + { + double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])); + double delta=std::max(xDelta,yDelta); + double characSize=sqrt(delta/(double)thisNbOfTuples); + BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12); + FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer()); + break; + } + case 1: + { + double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples; + BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12); + FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer()); + break; + } + default: + throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3."); + } + return ret.retn(); +} + +/*! + * Returns a copy of \a this array by excluding coincident tuples. Each tuple is + * considered as coordinates of a point in getNumberOfComponents()-dimensional + * space. The distance between tuples is computed using norm2. If several tuples are + * not far each from other than \a prec, only one of them remains in the result + * array. The order of tuples in the result array is same as in \a this one except + * that coincident tuples are excluded. + * \param [in] prec - minimal absolute distance between two tuples at which they are + * considered not coincident. + * \param [in] limitTupleId - limit tuple id. Tuples with id strictly lower than \a + * limiTupleId are not considered and thus not excluded. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If the number of components is not in [1,2,3]. * - * @param prec is an absolute precision. - * @param limitTupleId is the limit tuple id. All tuples which id is strictly lower than 'limiTupleId' will not be merged each other. + * \ref cpp_mcdataarraydouble_getdifferentvalues "Here is a Python example". */ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception) { @@ -1331,6 +1860,20 @@ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTuple return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples); } +/*! + * Copy all components in a specified order from another DataArrayDouble. + * The specified components become the first ones in \a this array. + * Both numerical and textual data is copied. The number of tuples in \a this and + * the other array can be different. + * \param [in] a - the array to copy data from. + * \param [in] compoIds - sequence of zero based indices of components, data of which is + * to be copied. + * \throw If \a a is NULL. + * \throw If \a compoIds.size() != \a a->getNumberOfComponents(). + * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). + * + * \ref cpp_mcdataarraydouble_setselectedcomponents "Here is a Python example". + */ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) { if(!a) @@ -1348,8 +1891,38 @@ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std: } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. - * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test. + * Copy all values from another DataArrayDouble into specified tuples and components + * of \a this array. Textual data is not copied. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step). + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - index of the first tuple of \a this array to assign values to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \param [in] bgComp - index of the first component of \a this array to assign values to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() + * must be equal to the number of columns to assign to, else an + * exception is thrown; if \a false, then it is only required that \a + * a->getNbOfElems() equals to number of values to assign to (this condition + * must be respected even if \a strictCompoCompare is \a true). The number of + * values to assign to is given by following Python expression: + * \a nbTargetValues = + * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If parameters specifying tuples and components to assign to do not give a + * non-empty range of increasing indices. + * \throw If \a a->getNbOfElems() != \a nbTargetValues. + * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * + * \ref cpp_mcdataarraydouble_setpartofvalues1 "Here is a Python example". */ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -1395,7 +1968,24 @@ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, i } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. + * Assign a given value to values at specified tuples and components of \a this array. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step).. + * \param [in] a - the value to assign. + * \param [in] bgTuples - index of the first tuple of \a this array to assign to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \throw If \a this is not allocated. + * \throw If parameters specifying tuples and components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref cpp_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example". */ void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception) { @@ -1414,8 +2004,42 @@ void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTupl } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. - * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test. + * Copy all values from another DataArrayDouble (\a a) into specified tuples and + * components of \a this array. Textual data is not copied. + * The tuples and components to assign to are defined by C arrays of indices. + * There are two *modes of usage*: + * - If \a a->getNbOfElems() equals to number of values to assign to, then every value + * of \a a is assigned to its own location within \a this array. + * - If \a a includes one tuple, then all values of \a a are assigned to the specified + * components of every specified tuple of \a this array. In this mode it is required + * that \a a->getNumberOfComponents() equals to the number of specified components. + * + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign values of \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign values of \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \param [in] strictCompoCompare - this parameter is checked only if the + * *mode of usage* is the first; if it is \a true (default), + * then \a a->getNumberOfComponents() must be equal + * to the number of specified columns, else this is not required. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If any index of tuple/component given by bgTuples / bgComp is + * out of a valid range for \a this array. + * \throw In the first *mode of usage*, if strictCompoCompare == true and + * if a->getNumberOfComponents() != (endComp - bgComp) . + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * a->getNumberOfComponents() != (endComp - bgComp). + * + * \ref cpp_mcdataarraydouble_setpartofvalues2 "Here is a Python example". */ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -1469,7 +2093,24 @@ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTu } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. + * Assign a given value to values at specified tuples and components of \a this array. + * The tuples and components to assign to are defined by C arrays of indices. + * \param [in] a - the value to assign. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (\a pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (\a pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \throw If \a this is not allocated. + * \throw If any index of tuple/component given by bgTuples / bgComp is + * out of a valid range for \a this array. + * + * \ref cpp_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example". */ void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception) { @@ -1488,8 +2129,48 @@ void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, cons } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. - * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test. + * Copy all values from another DataArrayDouble (\a a) into specified tuples and + * components of \a this array. Textual data is not copied. + * The tuples to assign to are defined by a C array of indices. + * The components to assign to are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * There are two *modes of usage*: + * - If \a a->getNbOfElems() equals to number of values to assign to, then every value + * of \a a is assigned to its own location within \a this array. + * - If \a a includes one tuple, then all values of \a a are assigned to the specified + * components of every specified tuple of \a this array. In this mode it is required + * that \a a->getNumberOfComponents() equals to the number of specified components. + * + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign values of \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \param [in] strictCompoCompare - this parameter is checked only in the first + * *mode of usage*; if \a strictCompoCompare is \a true (default), + * then \a a->getNumberOfComponents() must be equal + * to the number of specified columns, else this is not required. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If any index of tuple given by \a bgTuples is out of a valid range for + * \a this array. + * \throw In the first *mode of usage*, if strictCompoCompare == true and + * if a->getNumberOfComponents() is unequal to the number of components + * defined by (bgComp,endComp,stepComp). + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * a->getNumberOfComponents() is unequal to the number of components + * defined by (bgComp,endComp,stepComp). + * \throw If parameters specifying components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref cpp_mcdataarraydouble_setpartofvalues3 "Here is a Python example". */ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -1540,7 +2221,28 @@ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTu } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. + * Assign a given value to values at specified tuples and components of \a this array. + * The tuples to assign to are defined by a C array of indices. + * The components to assign to are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * \param [in] a - the value to assign. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \throw If \a this is not allocated. + * \throw If any index of tuple given by \a bgTuples is out of a valid range for + * \a this array. + * \throw If parameters specifying components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref cpp_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example". */ void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception) { @@ -1559,6 +2261,40 @@ void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, cons } } +/*! + * Copy all values from another DataArrayDouble into specified tuples and components + * of \a this array. Textual data is not copied. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step). + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - index of the first tuple of \a this array to assign values to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (\a pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() + * must be equal to the number of columns to assign to, else an + * exception is thrown; if \a false, then it is only required that \a + * a->getNbOfElems() equals to number of values to assign to (this condition + * must be respected even if \a strictCompoCompare is \a true). The number of + * values to assign to is given by following Python expression: + * \a nbTargetValues = + * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If parameters specifying tuples and components to assign to do not give a + * non-empty range of increasing indices. + * \throw If \a a->getNbOfElems() != \a nbTargetValues. + * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * + */ void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { if(!a) @@ -1620,9 +2356,25 @@ void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTupl } /*! - * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown. - * @param a is an array having exactly the same number of components than 'this' - * @param tuplesSelec is an array having exactly 2 components. The first one refers to the tuple ids of 'this' that will be set. The second one refers to the tuple ids of 'a' that will be used for setting. + * Copy some tuples from another DataArrayDouble into specified tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt. + * All components of selected tuples are copied. + * \param [in] a - the array to copy values from. + * \param [in] tuplesSelec - the array specifying both source tuples of \a a and + * target tuples of \a this. \a tuplesSelec has two components, and the + * first component specifies index of the source tuple and the second + * one specifies index of the target tuple. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a tuplesSelec is NULL. + * \throw If \a tuplesSelec is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a tuplesSelec->getNumberOfComponents() != 2. + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * the corresponding (\a this or \a a) array. */ void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) { @@ -1663,10 +2415,27 @@ void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArr } /*! - * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown. - * This is a method that is a specialization to DataArrayDouble::setPartOfValuesAdv method, except that here the tuple selection of 'a' is given by a range ('bg','end2' and 'step') - * rather than an explicite array of tuple ids (given by the 2nd component) and the feeding is done in 'this' contiguously starting from 'tupleIdStart'. - * @param a is an array having exactly the same number of components than 'this' + * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * The tuples to assign to are defined by index of the first tuple, and + * their number is defined by \a tuplesSelec->getNumberOfTuples(). + * The tuples to copy are defined by values of a DataArrayInt. + * All components of selected tuples are copied. + * \param [in] tupleIdStart - index of the first tuple of \a this array to assign + * values to. + * \param [in] a - the array to copy values from. + * \param [in] tuplesSelec - the array specifying tuples of \a a to copy. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a tuplesSelec is NULL. + * \throw If \a tuplesSelec is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a tuplesSelec->getNumberOfComponents() != 1. + * \throw If tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples(). + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * \a a array. */ void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) { @@ -1703,10 +2472,29 @@ void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const Data } /*! - * 'this' and 'a' are expected to be defined. If not an exception will be thrown. - * This is a method that is a specialization to DataArrayDouble::setContigPartOfSelectedValues method, except that here the tuple selection is givenin a is done by a range ('bg','end2' and 'step') - * rather than an explicite array of tuple ids. - * @param a is an array having exactly the same number of components than 'this' + * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * The tuples to copy are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * The tuples to assign to are defined by index of the first tuple, and + * their number is defined by number of tuples to copy. + * All components of selected tuples are copied. + * \param [in] tupleIdStart - index of the first tuple of \a this array to assign + * values to. + * \param [in] a - the array to copy values from. + * \param [in] bg - index of the first tuple to copy of the array \a a. + * \param [in] end2 - index of the tuple of \a a before which the tuples to copy + * are located. + * \param [in] step - index increment to get index of the next tuple to copy. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples(). + * \throw If parameters specifying tuples to copy, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for the array \a a. */ void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayDouble *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) { @@ -1734,9 +2522,16 @@ void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const Dat } /*! - * This method is equivalent to DataArrayDouble::getIJ except that here \b tupleId is checked to be in [0,this->getNumberOfTuples()) and compoId to be in [0,this->getNumberOfComponents()). - * If one of these check fails an INTERP_KERNEL::Exception will be thrown. - * So this method is safe but expensive if used to go through all data of \b this. + * Returns a value located at specified tuple and component. + * This method is equivalent to DataArrayDouble::getIJ() except that validity of + * parameters is checked. So this method is safe but expensive if used to go through + * all values of \a this. + * \param [in] tupleId - index of tuple of interest. + * \param [in] compoId - index of component of interest. + * \return double - value located by \a tupleId and \a compoId. + * \throw If \a this is not allocated. + * \throw If condition ( 0 <= tupleId < this->getNumberOfTuples() ) is violated. + * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. */ double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) { @@ -1755,9 +2550,11 @@ double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_K } /*! - * This method returns the last element in 'this'. So this method makes the hypothesis that 'this' is allocated. - * This method works only for arrays that have exactly number of components equal to 1. If not an exception is thrown. - * And to finish this method works for arrays that have number of tuples >= 1. + * Returns the last value of \a this. + * \return double - the last value of \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 1. */ double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception) { @@ -1782,6 +2579,18 @@ void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &ar } } +/*! + * Sets a C array to be used as raw data of \a this. The previously set info + * of components is retained and re-sized. + * For more info see \ref MEDCouplingArraySteps1. + * \param [in] array - the C array to be used as raw data of \a this. + * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this. + * \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC, + * \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC, + * \c free(\c array ) will be called. + * \param [in] nbOfTuple - new number of tuples in \a this. + * \param [in] nbOfCompo - new number of components in \a this. + */ void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) { _info_on_compo.resize(nbOfCompo); @@ -1796,6 +2605,11 @@ void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOf declareAsNew(); } +/*! + * Checks if 0.0 value is present in \a this array. If it is the case, an exception + * is thrown. + * \throw If zero is found in \a this array. + */ void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception) { const double *tmp=getConstPointer(); @@ -1806,12 +2620,16 @@ void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception) } /*! - * This method assume that \b this is allocated. If not an INTERP_KERNEL::Exception will be thrown. - * This method fills \b bounds params like that : \b bounds[0]=XMin, \b bounds[1]=XMax, \b bounds[2]=YMin, \b bounds[3]=YMax... - * Where X refers to component #0, and Y to component #1... - * This method set 2*this->getNumberOfComponents() elements in \b bounds, so it is up to the caller to allocated enough space before calling this method. - * - * @param [out] bounds array of size 2*this->getNumberOfComponents(). + * Computes minimal and maximal value in each component. An output array is filled + * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate + * enough memory before calling this method. + * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents(). + * It is filled as follows:
+ * \a bounds[0] = \c min_of_component_0
+ * \a bounds[1] = \c max_of_component_0
+ * \a bounds[2] = \c min_of_component_1
+ * \a bounds[3] = \c max_of_component_1
+ * ... */ void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception) { @@ -1949,6 +2767,13 @@ void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::E } } +/*! + * Returns the maximal value and its location within \a this one-dimensional array. + * \param [out] tupleId - index of the tuple holding the maximal value. + * \return double - the maximal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -1964,7 +2789,10 @@ double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exc } /*! - * Idem to DataArrayDouble::getMaxValue expect that here number of components can be >=1. + * Returns the maximal value within \a this array that is allowed to have more than + * one component. + * \return double - the maximal value among all values of \a this array. + * \throw If \a this is not allocated. */ double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception) { @@ -1973,6 +2801,15 @@ double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exceptio return *loc; } +/*! + * Returns the maximal value and all its locations within \a this one-dimensional array. + * \param [out] tupleIds - a new instance of DataArrayInt containg indices of + * tuples holding the maximal value. The caller is to delete it using + * decrRef() as it is no more needed. + * \return double - the maximal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception) { int tmp; @@ -1982,6 +2819,13 @@ double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP return ret; } +/*! + * Returns the minimal value and its location within \a this one-dimensional array. + * \param [out] tupleId - index of the tuple holding the minimal value. + * \return double - the minimal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -1997,7 +2841,10 @@ double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exc } /*! - * Idem to DataArrayDouble::getMinValue expect that here number of components can be >=1. + * Returns the minimal value within \a this array that is allowed to have more than + * one component. + * \return double - the minimal value among all values of \a this array. + * \throw If \a this is not allocated. */ double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception) { @@ -2006,6 +2853,15 @@ double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exceptio return *loc; } +/*! + * Returns the minimal value and all its locations within \a this one-dimensional array. + * \param [out] tupleIds - a new instance of DataArrayInt containg indices of + * tuples holding the minimal value. The caller is to delete it using + * decrRef() as it is no more needed. + * \return double - the minimal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception) { int tmp; @@ -2015,6 +2871,12 @@ double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP return ret; } +/*! + * Returns the average value of \a this one-dimensional array. + * \return double - the average value over all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) @@ -2027,6 +2889,12 @@ double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception) return ret/nbOfTuples; } +/*! + * Returns the Euclidean norm of the vector defined by \a this array. + * \return double - the value of the Euclidean norm, i.e. + * the square root of the inner product of vector. + * \throw If \a this is not allocated. + */ double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2038,6 +2906,12 @@ double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception) return sqrt(ret); } +/*! + * Returns the maximum norm of the vector defined by \a this array. + * \return double - the value of the maximum norm, i.e. + * the maximal absolute value among values of \a this array. + * \throw If \a this is not allocated. + */ double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2053,6 +2927,13 @@ double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception) return ret; } +/*! + * Accumulates values of each component of \a this array. + * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated + * by the caller, that is filled by this method with sum value for each + * component. + * \throw If \a this is not allocated. + */ void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2103,6 +2984,14 @@ double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tup return sqrt(ret0); } +/*! + * Accumulate values of the given component of \a this array. + * \param [in] compId - the index of the component of interest. + * \return double - a sum value of \a compId-th component. + * \throw If \a this is not allocated. + * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is + * not respected. + */ double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2117,6 +3006,16 @@ double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Except return ret; } +/*! + * Converts each 2D point defined by the tuple of \a this array from the Polar to the + * Cartesian coordinate system. The two components of the tuple of \a this array are + * considered to contain (1) radius and (2) angle of the point in the Polar CS. + * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple + * contains X and Y coordinates of the point in the Cartesian CS. The caller + * is to delete this array using decrRef() as it is no more needed. The array + * does not contain any textual info on components. + * \throw If \a this->getNumberOfComponents() != 2. + */ DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2136,6 +3035,17 @@ DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::E return ret; } +/*! + * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to + * the Cartesian coordinate system. The three components of the tuple of \a this array + * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in + * the Cylindrical CS. + * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple + * contains X, Y and Z coordinates of the point in the Cartesian CS. The info + * on the third component is copied from \a this array. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 3. + */ DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2157,6 +3067,17 @@ DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exc return ret; } +/*! + * Converts each 3D point defined by the tuple of \a this array from the Spherical to + * the Cartesian coordinate system. The three components of the tuple of \a this array + * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the + * point in the Cylindrical CS. + * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple + * contains X, Y and Z coordinates of the point in the Cartesian CS. The info + * on the third component is copied from \a this array. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 3. + */ DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2177,6 +3098,15 @@ DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::E return ret; } +/*! + * Computes the doubly contracted product of every tensor defined by the tuple of \a this + * array contating 6 components. + * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple + * is calculated from the tuple (t) of \a this array as follows: + * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$. + * The caller is to delete this result array using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 6. + */ DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2193,6 +3123,16 @@ DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_K return ret; } +/*! + * Computes the determinant of every square matrix defined by the tuple of \a this + * array, which contains either 4, 6 or 9 components. The case of 6 components + * corresponds to that of the upper triangular matrix. + * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple + * is the determinant of matrix of the corresponding tuple of \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. + */ DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2221,6 +3161,16 @@ DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Excep } } +/*! + * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of + * \a this array, which contains 6 components. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3 + * components, whose each tuple contains the eigenvalues of the matrix of + * corresponding tuple of \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 6. + */ DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2237,6 +3187,16 @@ DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Excep return ret; } +/*! + * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of + * \a this array, which contains 6 components. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9 + * components, whose each tuple contains 3 eigenvectors of the matrix of + * corresponding tuple of \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 6. + */ DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2258,6 +3218,17 @@ DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exce return ret; } +/*! + * Computes the inverse matrix of every matrix defined by the tuple of \a this + * array, which contains either 4, 6 or 9 components. The case of 6 components + * corresponds to that of the upper triangular matrix. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of components as \a this one, whose each tuple is the inverse + * matrix of the matrix of corresponding tuple of \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. + */ DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2306,6 +3277,17 @@ if(nbOfComp==6) return ret; } +/*! + * Computes the trace of every matrix defined by the tuple of \a this + * array, which contains either 4, 6 or 9 components. The case of 6 components + * corresponds to that of the upper triangular matrix. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing + * 1 component, whose each tuple is the trace of + * the matrix of corresponding tuple of \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() is not in [4,6,9]. + */ DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2329,6 +3311,15 @@ DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception) return ret; } +/*! + * Computes the stress deviator tensor of every stress tensor defined by the tuple of + * \a this array, which contains 6 components. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of components and tuples as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 6. + */ DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2353,6 +3344,15 @@ DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exceptio return ret; } +/*! + * Computes the magnitude of every vector defined by the tuple of + * \a this array. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array and one component. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + */ DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2372,6 +3372,14 @@ DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Excepti return ret; } +/*! + * Computes the maximal value within every tuple of \a this array. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array and one component. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + */ DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2475,6 +3483,12 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const Da return ret.retn(); } +/*! + * Sorts value within every tuple of \a this array. + * \param [in] asc - if \a true, the values are sorted in ascending order, else, + * in descending order. + * \throw If \a this is not allocated. + */ void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2490,6 +3504,10 @@ void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Converts every value of \a this array to its absolute value. + * \throw If \a this is not allocated. + */ void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2499,6 +3517,14 @@ void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Apply a liner function to a given component of \a this array, so that + * an array element (x) becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \param [in] compoId - the index of component to modify. + * \throw If \a this is not allocated. + */ void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2510,6 +3536,13 @@ void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KER declareAsNew(); } +/*! + * Apply a liner function to all elements of \a this array, so that + * an element _x_ becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \throw If \a this is not allocated. + */ void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2521,9 +3554,14 @@ void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exceptio } /*! - * This method applies the operation 'numerator/x' for each element 'x' in 'this'. - * If there is a value in 'this' exactly equal to 0. an exception is thrown. - * Warning if presence of null this is modified for each values previous than place where exception was thrown ! + * Modify all elements of \a this array, so that + * an element _x_ becomes \f$ numerator / x \f$. + * \param [in] numerator - the numerator used to modify array elements. + * \throw If \a this is not allocated. + * \throw If there is an element equal to 0.0 in \a this array. + * \warning If an exception is thrown because of presence of 0.0 element in \a this + * array, all elements processed before detection of the zero element remain + * modified. */ void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception) { @@ -2547,8 +3585,12 @@ void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception) } /*! - * This method returns a newly allocated array containing the application of negate on \b this. - * This method throws an INTERP_KERNEL::Exception if \b this is not allocated. + * Returns a full copy of \a this array except that sign of all elements is reversed. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples and component as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. */ DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception) { @@ -2563,6 +3605,24 @@ DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception) return newArr; } +/*! + * Returns a new DataArrayDouble created from \a this one by applying \a + * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied. + * For more info see \ref MEDCouplingArrayApplyFunc + * \param [in] nbOfComp - number of components in the result array. + * \param [in] func - the \a FunctionToEvaluate declared as + * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), + * where \a pos points to the first component of a tuple of \a this array + * and \a res points to the first component of a tuple of the result array. + * Note that length (number of components) of \a pos can differ from + * that of \a res. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \throw If \a func returns \a false. + */ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2587,8 +3647,18 @@ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate fun } /*! - * This method returns a newly allocated array the caller should deal with. - * The returned array will have 'nbOfComp' components (that can be different from this->getNumberOfComponents()) contrary to the other DataArrayDouble::applyFunc overload method. + * Returns a new DataArrayDouble created from \a this one by applying a function to every + * tuple of \a this array. Textual data is not copied. + * For more info see \ref MEDCouplingArrayApplyFunc1. + * \param [in] nbOfComp - number of components in the result array. + * \param [in] func - the expression defining how to transform a tuple of \a this array. + * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array and \a nbOfComp components. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \throw If computing \a func fails. */ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception) { @@ -2631,6 +3701,19 @@ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) cons return newArr; } +/*! + * Returns a new DataArrayDouble created from \a this one by applying a function to every + * tuple of \a this array. Textual data is not copied. + * For more info see \ref MEDCouplingArrayApplyFunc0. + * \param [in] func - the expression defining how to transform a tuple of \a this array. + * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples and components as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \throw If computing \a func fails. + */ DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2663,8 +3746,19 @@ DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP } /*! - * This method is equivalent than DataArrayDouble::applyFunc, except that here components names are used to determine vars orders. - * If 'func' contains vars that are not in \c this->getInfoOnComponent() an exception will be thrown. + * Returns a new DataArrayDouble created from \a this one by applying a function to every + * tuple of \a this array. Textual data is not copied. + * For more info see \ref MEDCouplingArrayApplyFunc2. + * \param [in] nbOfComp - number of components in the result array. + * \param [in] func - the expression defining how to transform a tuple of \a this array. + * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \throw If \a func contains vars that are not in \a this->getInfoOnComponent(). + * \throw If computing \a func fails. */ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception) { @@ -2707,8 +3801,20 @@ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) con } /*! - * This method is equivalent than DataArrayDouble::applyFunc, except that here order of vars is passed explicitely in parameter. - * In 'func' contains vars not in 'varsOrder' an exception will be thrown. + * Returns a new DataArrayDouble created from \a this one by applying a function to every + * tuple of \a this array. Textual data is not copied. + * For more info see \ref MEDCouplingArrayApplyFunc3. + * \param [in] nbOfComp - number of components in the result array. + * \param [in] varsOrder - sequence of vars defining their order. + * \param [in] func - the expression defining how to transform a tuple of \a this array. + * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \throw If \a func contains vars not in \a varsOrder. + * \throw If computing \a func fails. */ DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception) { @@ -2791,6 +3897,20 @@ DataArrayDoubleIterator *DataArrayDouble::iterator() return new DataArrayDoubleIterator(this); } +/*! + * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional + * array whose values are within a given range. Textual data is not copied. + * \param [in] vmin - a lowest acceptable value. + * \param [in] vmax - a greatest acceptable value. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 1 + * + * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example". + * + * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example". + */ DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -2808,6 +3928,20 @@ DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const thr return ret; } +/*! + * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number + * of tuples in the result array is a sum of the number of tuples of given arrays and (2) + * the number of component in the result array is same as that of each of given arrays. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] a1 - an array to include in the result array. + * \param [in] a2 - another array to include in the result array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If both \a a1 and \a a2 are NULL. + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents(). + */ DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { std::vector tmp(2); @@ -2815,6 +3949,19 @@ DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const Dat return Aggregate(tmp); } +/*! + * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number + * of tuples in the result array is a sum of the number of tuples of given arrays and (2) + * the number of component in the result array is same as that of each of given arrays. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] arr - a sequence of arrays to include in the result array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arr are NULL. + * \throw If getNumberOfComponents() of arrays within \a arr. + */ DataArrayDouble *DataArrayDouble::Aggregate(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; @@ -2841,6 +3988,22 @@ DataArrayDouble *DataArrayDouble::Aggregate(const std::vectorgetNumberOfTuples() != \a a2->getNumberOfTuples() + */ DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { std::vector arr(2); @@ -2848,6 +4011,21 @@ DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArra return Meld(arr); } +/*! + * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number + * of components in the result array is a sum of the number of components of given arrays + * and (2) the number of tuples in the result array is same as that of each of given + * arrays. In other words the i-th tuple of result array includes all components of + * i-th tuples of all given arrays. + * Number of tuples in the given arrays must be the same. + * \param [in] arr - a sequence of arrays to include in the result array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arr are NULL. + * \throw If any given array is not allocated. + * \throw If getNumberOfTuples() of arrays within \a arr is different. + */ DataArrayDouble *DataArrayDouble::Meld(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; @@ -2889,6 +4067,22 @@ DataArrayDouble *DataArrayDouble::Meld(const std::vectorgetNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() + */ DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -2918,6 +4112,23 @@ DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArray return ret; } +/*! + * Returns a new DataArrayDouble containing a cross product of two given arrays, so that + * the i-th tuple of the result array contains 3 components of a vector which is a cross + * product of two vectors defined by the i-th tuples of given arrays. + * Info on components is copied from the first of the given arrays. + * Number of tuples in the given arrays must be the same. + * Number of components in the given arrays must be 3. + * \param [in] a1 - a given array. + * \param [in] a2 - another given array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != 3 + * \throw If \a a2->getNumberOfComponents() != 3 + */ DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -2945,6 +4156,19 @@ DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const return ret; } +/*! + * Returns a new DataArrayDouble containing maximal values of two given arrays. + * Info on components is copied from the first of the given arrays. + * Number of tuples and components in the given arrays must be the same. + * \param [in] a1 - an array to compare values with another one. + * \param [in] a2 - another array to compare values with the first one. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() + */ DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -2967,6 +4191,19 @@ DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArray return ret; } +/*! + * Returns a new DataArrayDouble containing minimal values of two given arrays. + * Info on components is copied from the first of the given arrays. + * Number of tuples and components in the given arrays must be the same. + * \param [in] a1 - an array to compare values with another one. + * \param [in] a2 - another array to compare values with the first one. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() + */ DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -2989,6 +4226,31 @@ DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArray return ret; } +/*! + * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2, + * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - an array to sum up. + * \param [in] a2 - another array to sum up. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -3059,6 +4321,23 @@ DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArray return ret.retn(); } +/*! + * Adds values of another DataArrayDouble to values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is added to the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] += _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] += _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] += _a2_ [ 0, j ]. + * + * \param [in] other - an array to add to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { if(!other) @@ -3103,6 +4382,31 @@ void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL declareAsNew(); } +/*! + * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a subtraction of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - an array to subtract from. + * \param [in] a2 - an array to subtract. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -3158,6 +4462,23 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat } } +/*! + * Subtract values of another DataArrayDouble from values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is subtracted from the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] -= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] -= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] -= _a2_ [ 0, j ]. + * + * \param [in] other - an array to subtract from \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { if(!other) @@ -3202,6 +4523,31 @@ void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_ declareAsNew(); } +/*! + * Returns a new DataArrayDouble that is a product of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a product of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - a factor array. + * \param [in] a2 - another factor array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -3272,6 +4618,23 @@ DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const Data return ret.retn(); } +/*! + * Multiply values of another DataArrayDouble to values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is multiplied to the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] *= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] *= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] *= _a2_ [ 0, j ]. + * + * \param [in] other - an array to multiply to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { if(!other) @@ -3316,6 +4679,32 @@ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_K declareAsNew(); } +/*! + * Returns a new DataArrayDouble that is a division of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a division of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - a numerator array. + * \param [in] a2 - a denominator array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + * \warning No check of division by zero is performed! + */ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -3371,6 +4760,24 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr } } +/*! + * Divide values of \a this array by values of another DataArrayDouble. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a this array is divided by the corresponding value of \a other one, i.e.: + * _a_ [ i, j ] /= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] /= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] /= _a2_ [ 0, j ]. + * + * \param [in] other - an array to divide \a this one by. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + * \warning No check of division by zero is performed! + */ void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { if(!other) @@ -3561,16 +4968,29 @@ DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCom } } +/*! + * Returns a new instance of DataArrayInt. The caller is to delete this array + * using decrRef() as it is no more needed. + */ DataArrayInt *DataArrayInt::New() { return new DataArrayInt; } +/*! + * Checks if raw data is allocated. Read more on the raw data + * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. + * \return bool - \a true if the raw data is allocated, \a false else. + */ bool DataArrayInt::isAllocated() const { return getConstPointer()!=0; } +/*! + * Checks if raw data is allocated and throws an exception if it is not the case. + * \throw If the raw data is not allocated. + */ void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception) { if(!isAllocated()) @@ -3585,10 +5005,14 @@ std::size_t DataArrayInt::getHeapMemorySize() const } /*! - * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()' - * and if 'this' is not allocated it will change the number of components of 'this'. - * If 'this->getNumberOfComponents()==info.size()' the behaviour is the same than DataArray::setInfoOnComponents method. - * If 'this->getNumberOfComponents()!=info.size()' and the 'this' is already allocated an exception will be thrown. + * Sets information on all components. This method can change number of components + * at certain conditions; if the conditions are not respected, an exception is thrown. + * The number of components can be changed provided that \a this is not allocated. + * + * To know more on format of the component information see + * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". + * \param [in] info - a vector of component infos. + * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated() */ void DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception) { @@ -3607,8 +5031,10 @@ void DataArrayInt::setInfoAndChangeNbOfCompo(const std::vector& inf } /*! - * This method returns the only one value in 'this', if and only if number of elements (nb of tuples * nb of components) is equal to 1, and that 'this' is allocated. - * If one or more conditions is not fulfilled an exception will be thrown. + * Returns the only one value in \a this, if and only if number of elements + * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. + * \return double - the sole value stored in \a this array. + * \throw If at least one of conditions stated above is not fulfilled. */ int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception) { @@ -3626,7 +5052,10 @@ int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception) } /*! - * This method expects that \b this is well allocated. If not an INTERP_KERNEL::Exception will be thrown. This method is useful for a quick comparison of many instances of DataArrayInt. + * Returns an integer value characterizing \a this array, which is useful for a quick + * comparison of many instances of DataArrayInt. + * \return int - the hash value. + * \throw If \a this is not allocated. */ int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception) { @@ -3644,8 +5073,9 @@ int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception) } /*! - * This method should be called on an allocated DataArrayInt instance. If not an exception will be throw ! - * This method checks the number of tupes. If it is equal to 0, it returns true, if not false is returned. + * Checks the number of tuples. + * \return bool - \a true if getNumberOfTuples() == 0, \a false else. + * \throw If \a this is not allocated. */ bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception) { @@ -3653,11 +5083,23 @@ bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception) return getNumberOfTuples()==0; } +/*! + * Returns a full copy of \a this. For more info on copying data arrays see + * \ref MEDCouplingArrayBasicsCopyDeep. + * \return DataArrayInt * - a new instance of DataArrayInt. + */ DataArrayInt *DataArrayInt::deepCpy() const { return new DataArrayInt(*this); } +/*! + * Returns either a \a deep or \a shallow copy of this array. For more info see + * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow. + * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one. + * \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy + * == \a true) or \a this instance (if \a dCpy == \a false). + */ DataArrayInt *DataArrayInt::performCpy(bool dCpy) const { if(dCpy) @@ -3669,6 +5111,12 @@ DataArrayInt *DataArrayInt::performCpy(bool dCpy) const } } +/*! + * Copies all the data from another DataArrayInt. For more info see + * \ref MEDCouplingArrayBasicsCopyDeepAssign. + * \param [in] other - another instance of DataArrayInt to copy data from. + * \throw If the \a other is not allocated. + */ void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception) { other.checkAllocated(); @@ -3683,6 +5131,14 @@ void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Excep copyStringInfoFrom(other); } +/*! + * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this. + * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown. + * If \a this has not already been allocated, number of components is set to one. + * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this. + * + * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent + */ void DataArrayInt::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception) { int nbCompo=getNumberOfComponents(); @@ -3699,6 +5155,14 @@ void DataArrayInt::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !"); } +/*! + * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation + * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. + * + * \param [in] val the value to be added in \a this + * \throw If \a this has already been allocated with number of components different from one. + * \sa DataArrayInt::pushBackValsSilent + */ void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception) { int nbCompo=getNumberOfComponents(); @@ -3713,6 +5177,16 @@ void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !"); } +/*! + * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation + * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. + * + * \param [in] valsBg - an array of values to push at the end of \this. + * \param [in] valsEnd - specifies the end of the array \a valsBg, so that + * the last value of \a valsBg is \a valsEnd[ -1 ]. + * \throw If \a this has already been allocated with number of components different from one. + * \sa DataArrayInt::pushBackSilent + */ void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception) { int nbCompo=getNumberOfComponents(); @@ -3727,6 +5201,11 @@ void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) thr throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !"); } +/*! + * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it. + * \throw If \a this is already empty. + * \throw If \a this has number of components different from one. + */ int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()==1) @@ -3735,11 +5214,23 @@ int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !"); } +/*! + * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store. + * + * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve + */ void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception) { _mem.pack(); } +/*! + * Allocates the raw data in memory. If exactly as same memory as needed already + * allocated, it is not re-allocated. + * \param [in] nbOfTuple - number of tuples of data to allocate. + * \param [in] nbOfCompo - number of components of data to allocate. + * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0. + */ void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) { if(isAllocated()) @@ -3751,6 +5242,14 @@ void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) alloc(nbOfTuple,nbOfCompo); } +/*! + * Allocates the raw data in memory. If the memory was already allocated, then it is + * freed and re-allocated. See an example of this method use + * \ref MEDCouplingArraySteps1WC "here". + * \param [in] nbOfTuple - number of tuples of data to allocate. + * \param [in] nbOfCompo - number of components of data to allocate. + * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0. + */ void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception) { if(nbOfTuple<0 || nbOfCompo<0) @@ -3760,6 +5259,11 @@ void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exce declareAsNew(); } +/*! + * Assign zero to all values in \a this array. To know more on filling arrays see + * \ref MEDCouplingArrayFill. + * \throw If \a this is not allocated. + */ void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -3767,6 +5271,12 @@ void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Assign \a val to all values in \a this array. To know more on filling arrays see + * \ref MEDCouplingArrayFill. + * \param [in] val - the value to fill with. + * \throw If \a this is not allocated. + */ void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -3774,6 +5284,13 @@ void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Set all values in \a this array so that the i-th element equals to \a init + i + * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill. + * \param [in] init - value to assign to the first element of array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this is not allocated. + */ void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -3786,6 +5303,11 @@ void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Returns a textual and human readable representation of \a this instance of + * DataArrayInt. This text is shown when a DataArrayInt is printed in Python. + * \return std::string - text describing \a this DataArrayInt. + */ std::string DataArrayInt::repr() const { std::ostringstream ret; @@ -3852,11 +5374,15 @@ void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) cons } /*! - * This method expects a number of components equal to 1. - * This method sweeps all the values (tuples) in 'this' (it should be allocated) and for each value v is replaced by - * indArr[v] where 'indArr' is defined by ['indArrBg','indArrEnd'). - * This method is safe that is to say if there is a value in 'this' not in [0,std::distance('indArrBg','indArrEnd')) an exception - * will be thrown. + * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ], + * i.e. a current value is used as in index to get a new value from \a indArrBg. + * \param [in] indArrBg - pointer to the first element of array of new values to assign + * to \a this array. + * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that + * the last value of \a indArrBg is \a indArrEnd[ -1 ]. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If any value of \a this can't be used as a valid index for + * [\a indArrBg, \a indArrEnd). */ void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception) { @@ -3880,21 +5406,51 @@ void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd } /*! - * 'this' should be allocated and with numberOfComponents set to one. If not an exception will be thrown. - * This method takes as input an array defined by ['arrBg','arrEnd'). The size of the array (std::distance(arrBg,arrEnd)) is equal to the number of cast + 1. - * The values contained in ['arrBg','arrEnd') should be sorted ascendently. No check of this will be done. If not the result is not waranted. - * For each cast j the value range that defines the cast is equal to [arrBg[j],arrBg[j+1]). - * This method returns three arrays (to be managed by the caller). - * This method is typically usefull for entity number spliting by types for example. - * Example : If 'this' contains [6,5,0,3,2,7,8,1,4] and if ['arrBg','arrEnd') contains [0,4,9] then the output of this method will be : - * - 'castArr' : [1,1,0,0,0,1,1,0,1] - * - 'rankInsideCast' : [2,1,0,3,2,3,4,1,0] - * - 'return' : [0,1] + * Computes distribution of values of \a this one-dimensional array between given value + * ranges (casts). This method is typically useful for entity number spliting by types, + * for example. + * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th + * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range, + * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a + * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg + * should be more than every value in \a this array. + * \param [in] arrEnd - specifies the end of the array \a arrBg, so that + * the last value of \a arrBg is \a arrEnd[ -1 ]. + * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array + * (same number of tuples and components), the caller is to delete + * using decrRef() as it is no more needed. + * This array contains indices of ranges for every value of \a this array. I.e. + * the i-th value of \a castArr gives the index of range the i-th value of \a this + * belongs to. Or, in other words, this parameter contains for each tuple in \a + * this in which cast it holds. + * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this + * array, the caller is to delete using decrRef() as it is no more needed. + * This array contains ranks of values of \a this array within ranges + * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of + * the i-th value of \a this array within the \a castArr[ i ]-th range, to which + * the i-th value of \a this belongs to. Or, in other words, this param contains + * for each tuple its rank inside its cast. The rank is computed as difference + * between the value and the lowest value of range. + * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of + * ranges (casts) to which at least one value of \a this array belongs. + * Or, in other words, this param contains the casts that \a this contains. + * The caller is to delete this array using decrRef() as it is no more needed. * - * @param castArr is a returned param has the same number of tuples than 'this' and number of components set to one. In case of sucess, this param contains for each tuple in 'this' in which cast it holds. - * @param rankInsideCast is an another returned param has the same number of tuples than 'this' and number of components set to one too. In case of sucess, this param contains for each tuple its rank inside its cast. - * @param castsPresent the casts that 'this' contains. - * @throw if a value in 'this' is greater or equal to the last value of ['arrBg','arrEnd') + * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then + * the output of this method will be : + * - \a castArr : [1,1,0,0,0,1,1,0,1] + * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0] + * - \a castsPresent : [0,1] + * + * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the + * range #1 and its rank within this range is 2; etc. + * + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a arrEnd - arrBg < 2. + * \throw If any value of \a this is not less than \a arrEnd[-1]. + * \warning The values contained in \a arrBg should be sorted ascendently. No + * check of this is be done. If not, the result is not warranted. + * */ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd, DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception) @@ -3909,7 +5465,7 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd, nbOfCast--; const int *work=getConstPointer(); typedef std::reverse_iterator rintstart; - rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater of equal 2 + rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2 rintstart end2(arrBg); MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); @@ -3944,12 +5500,20 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd, } /*! - * This method expects a number of components equal to 1. - * This method sweeps all the values (tuples) in 'this' (it should be allocated) and for each value v on place i, place indArr[v] will have - * value i. - * indArr[v] where 'indArr' is defined by ['indArrBg','indArrEnd'). - * This method is safe that is to say if there is location i so that indArr[v] is not in [0,this->getNumberOfTuples()) an exception - * will be thrown. An exception is also thrown if there is a location i so that \a this[i] not in [0,distance(indArrBg,indArrEnd)) ! + * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from + * values of \a this (\a a) and the given (\a indArr) arrays as follows: + * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ], + * new value in place \a indArr[ \a v ] is i. + * \param [in] indArrBg - the array holding indices within the result array to assign + * indices of values of \a this array pointing to values of \a indArrBg. + * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that + * the last value of \a indArrBg is \a indArrEnd[ -1 ]. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If any value of \a this array is not a valid index for \a indArrBg array. + * \throw If any value of \a indArrBg is not a valid index for \a this array. */ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception) { @@ -3986,8 +5550,18 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int } /*! - * This method invert array 'di' that is a conversion map from Old to New numbering to New to Old numbering. - * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [3,1,2,4,9,6,8] + * Creates a one-dimensional DataArrayInt of given length, whose contents are computed + * from values of \a this array, which is supposed to contain a renumbering map in + * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode. + * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering. + * \param [in] newNbOfElem - the number of tuples in the result array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * + * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example". + * + * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example". */ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const { @@ -4020,7 +5594,18 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(I } /*! - * This method invert array 'di' that is a conversion map from New to old numbering to Old to New numbering. + * Creates a one-dimensional DataArrayInt of given length, whose contents are computed + * from values of \a this array, which is supposed to contain a renumbering map in + * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode. + * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering. + * \param [in] newNbOfElem - the number of tuples in the result array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * + * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example". + * + * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example". */ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const { @@ -4043,18 +5628,37 @@ bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reaso return _mem.isEqual(other._mem,0,reason); } +/*! + * Checks if \a this and another DataArrayInt are fully equal. For more info see + * \ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayInt to compare with \a this one. + * \return bool - \a true if the two arrays are equal, \a false else. + */ bool DataArrayInt::isEqual(const DataArrayInt& other) const { std::string tmp; return isEqualIfNotWhy(other,tmp); } +/*! + * Checks if values of \a this and another DataArrayInt are equal. For more info see + * \ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayInt to compare with \a this one. + * \return bool - \a true if the values of two arrays are equal, \a false else. + */ bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const { std::string tmp; return _mem.isEqual(other._mem,0,tmp); } +/*! + * Checks if values of \a this and another DataArrayInt are equal. Comparison is + * performed on sorted value sequences. + * For more info see\ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayInt to compare with \a this one. + * \return bool - \a true if the sorted values of two arrays are equal, \a false else. + */ bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception) { MEDCouplingAutoRefCountObjectPtr a=deepCpy(); @@ -4064,6 +5668,12 @@ bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& othe return a->isEqualWithoutConsideringStr(*b); } +/*! + * Sorts values of the array. + * \param [in] asc - \a true means ascending order, \a false, descending. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + */ void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -4072,6 +5682,11 @@ void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception) _mem.sort(asc); } +/*! + * Reverse the array values. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. + */ void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -4081,7 +5696,13 @@ void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception) } /*! - * This method check that array consistently INCREASING or DECREASING in value. + * Checks that \a this array is consistently **increasing** or **decreasing** in value. + * If not an exception is thrown. + * \param [in] increasing - if \a true, the array values should be increasing. + * \throw If sequence of values is not strictly monotonic in agreement with \a + * increasing arg. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. */ void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception) { @@ -4095,7 +5716,11 @@ void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Ex } /*! - * This method check that array consistently INCREASING or DECREASING in value. + * Checks that \a this array is consistently **increasing** or **decreasing** in value. + * \param [in] increasing - if \a true, array values should be increasing. + * \return bool - \a true if values change in accordance with \a increasing arg. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. */ bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception) { @@ -4181,11 +5806,23 @@ void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KE } /*! - * This method expects that 'this' and 'other' have the same number of tuples and exactly one component both. If not an exception will be thrown. - * This method retrieves a newly created array with same number of tuples than 'this' and 'other' with one component. - * The returned array 'ret' contains the correspondance from 'this' to 'other' that is to say for every i so that 0<=igetIJ(ret->getIJ(i),0) - * If such permutation is not possible because it exists some elements in 'other' not in 'this', an exception will be thrown. + * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given + * one-dimensional arrays that must be of the same length. The result array describes + * correspondence between \a this and \a other arrays, so that + * other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0). If such a permutation is + * not possible because some element in \a other is not in \a this, an exception is thrown. + * \param [in] other - an array to compute permutation to. + * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array + * from \a this to \a other. The caller is to delete this array using decrRef() as it is + * no more needed. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a other->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples(). + * \throw If \a other includes a value which is not in \a this array. + * + * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example". + * + * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example". */ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception) { @@ -4218,6 +5855,18 @@ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const return ret.retn(); } +/*! + * Sets a C array to be used as raw data of \a this. The previously set info + * of components is retained and re-sized. + * For more info see \ref MEDCouplingArraySteps1. + * \param [in] array - the C array to be used as raw data of \a this. + * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this. + * \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC, + * \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC, + * \c free(\c array ) will be called. + * \param [in] nbOfTuple - new number of tuples in \a this. + * \param [in] nbOfCompo - new number of components in \a this. + */ void DataArrayInt::useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) { _info_on_compo.resize(nbOfCompo); @@ -4232,6 +5881,16 @@ void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, declareAsNew(); } +/*! + * Returns a new DataArrayInt holding the same values as \a this array but differently + * arranged in memory. If \a this array holds 2 components of 3 values: + * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged + * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \warning Do not confuse this method with transpose()! + */ DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -4243,6 +5902,16 @@ DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Excepti return ret; } +/*! + * Returns a new DataArrayInt holding the same values as \a this array but differently + * arranged in memory. If \a this array holds 2 components of 3 values: + * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged + * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \warning Do not confuse this method with transpose()! + */ DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -4254,6 +5923,15 @@ DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception return ret; } +/*! + * Permutes values of \a this array as required by \a old2New array. The values are + * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains + * the same as in \this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old value. + */ void DataArrayInt::renumberInPlace(const int *old2New) { checkAllocated(); @@ -4268,6 +5946,16 @@ void DataArrayInt::renumberInPlace(const int *old2New) declareAsNew(); } +/*! + * Permutes values of \a this array as required by \a new2Old array. The values are + * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains + * the same as in \this one. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() + * giving a previous position of i-th new value. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + */ void DataArrayInt::renumberInPlaceR(const int *new2Old) { checkAllocated(); @@ -4283,9 +5971,16 @@ void DataArrayInt::renumberInPlaceR(const int *new2Old) } /*! - * This method expects that 'this' is allocated, if not an exception is thrown. - * This method in case of success returns a newly created array the user should deal with. - * In the case of having a renumber array in "old to new" format. More info on renumbering \ref MEDCouplingArrayRenumbering "here". + * Returns a copy of \a this array with values permuted as required by \a old2New array. + * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. + * Number of tuples in the result array remains the same as in \this one. + * If a permutation reduction is needed, renumberAndReduce() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old value. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. */ DataArrayInt *DataArrayInt::renumber(const int *old2New) const { @@ -4303,6 +5998,17 @@ DataArrayInt *DataArrayInt::renumber(const int *old2New) const return ret; } +/*! + * Returns a copy of \a this array with values permuted as required by \a new2Old array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of + * tuples in the result array remains the same as in \this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() + * giving a previous position of i-th new value. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + */ DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const { checkAllocated(); @@ -4320,10 +6026,17 @@ DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const } /*! - * Idem DataArrayInt::renumber method except that the number of tuples is reduced. - * That is to say that it is expected that newNbOfTuplegetNumberOfTuples(). - * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'getNumberOfTuples()) the corresponding tuple is - * omitted. + * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is + * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array. + * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all + * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which + * \a old2New[ i ] is negative, is missing from the result array. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * giving a new position for i-th old tuple and giving negative position for + * for i-th old tuple that should be omitted. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. */ DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const { @@ -4345,8 +6058,20 @@ DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTup } /*! - * This method is a generalization of DataArrayInt::substr method because a not contigous range can be specified here. - * This method is equavalent to DataArrayInt::renumberAndReduce except that convention in input is new2old and \b not old2new. + * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is + * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by + * \a new2OldBg array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. + * This method is equivalent to renumberAndReduce() except that convention in input is + * \c new2old and \b not \c old2new. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a + * tuple index in \a this array to fill the i-th tuple in the new array. + * \param [in] new2OldEnd - specifies the end of the permutation array that starts at + * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: + * \a new2OldBg <= \a pi < \a new2OldEnd. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. */ DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const { @@ -4365,7 +6090,23 @@ DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new } /*! - * This method is equivalent to DataArrayInt::selectByTupleId except that an analyze to the content of input range to check that it will not lead to memory corruption ! + * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is + * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by + * \a new2OldBg array. + * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. + * This method is equivalent to renumberAndReduce() except that convention in input is + * \c new2old and \b not \c old2new. + * This method is equivalent to selectByTupleId() except that it prevents coping data + * from behind the end of \a this array. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a + * tuple index in \a this array to fill the i-th tuple in the new array. + * \param [in] new2OldEnd - specifies the end of the permutation array that starts at + * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: + * \a new2OldBg <= \a pi < \a new2OldEnd. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples(). */ DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception) { @@ -4388,12 +6129,20 @@ DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int } /*! - * Idem than DataArrayInt::selectByTupleIdSafe except that the input array is not constructed explicitely. - * The convention is as python one. ['bg','end2') with steps of 'step'. - * Returns a newly created array. - * This method is an extension of DataArrayInt::substr method. - * - * \sa DataArrayInt::substr + * Returns a shorten copy of \a this array. The new DataArrayInt contains every + * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th + * tuple. Indices of the selected tuples are the same as ones returned by the Python + * command \c range( \a bg, \a end2, \a step ). + * This method is equivalent to selectByTupleIdSafe() except that the input array is + * not constructed explicitly. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] bg - index of the first tuple to copy from \a this array. + * \param [in] end2 - index of the tuple before which the tuples to copy are located. + * \param [in] step - index increment to get index of the next tuple to copy. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If (\a end2 < \a bg) or (\a step <= 0). + * \sa DataArrayInt::substr. */ DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception) { @@ -4411,9 +6160,16 @@ DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const t } /*! - * This method returns a newly allocated array that is the concatenation of all tuples ranges in param 'ranges'. - * Each pair in input 'ranges' is in [begin,end) format. If there is a range in 'ranges' so that end is before begin an exception - * will be thrown. If there is a range in 'ranges' so that end is greater than number of tuples of 'this', an exception will be thrown too. + * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges + * of tuples specified by \a ranges parameter. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * \param [in] ranges - std::vector of std::pair's each of which defines a range + * of tuples in [\c begin,\c end) format. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a end < \a begin. + * \throw If \a end > \a this->getNumberOfTuples(). + * \throw If \a this is not allocated. */ DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector >& ranges) const throw(INTERP_KERNEL::Exception) { @@ -4468,11 +6224,18 @@ DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vectorrenumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11]. + * This method is useful for renumbering (in MED file for example). For more info + * on renumbering see \ref MEDCouplingArrayRenumbering. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If there are equal values in \a this array. */ DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception) { @@ -4488,15 +6251,39 @@ DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERN } /*! - * This method makes the assumption that 'this' is correctly set, and has exactly one component. If not an exception will be thrown. - * Given a sujective application defined by 'this' from a set of size this->getNumberOfTuples() to a set of size targetNb. - * 'targetNb'getNumberOfTuples(). 'this' should be surjective that is to say for each id in [0,'targetNb') it exists at least one tupleId tid - * so that this->getIJ(tid,0)==id. - * If not an exception will be thrown. - * This method returns 2 newly allocated arrays 'arr' and 'arrI', corresponding respectively to array and its corresponding index. - * This method is usefull for methods that returns old2New numbering concecutive to a reduction ( MEDCouplingUMesh::zipConnectivityTraducer, MEDCouplingUMesh::zipConnectivityTraducer for example) - * Example : if 'this' equals [0,3,2,3,2,2,1,2] this method will return arrI=[0,1,2,6,8] arr=[0, 6, 2,4,5,7, 1,3] - * That is to say elt id 2 has arrI[2+1]-arrI[2]=4 places in 'this'. The corresponding tuple ids are [2,4,5,7]. + * Returns two arrays describing a surjective mapping from \a this set of values (\a A) + * onto a set of values of size \a targetNb (\a B). The surjective function is + * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a + * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so + * that this->getIJ( tid, 0 ) == id.
+ * The first of out arrays returns indices of elements of \a this array, grouped by their + * place in the set \a B. The second out array is the index of the first one; it shows how + * many elements of \a A are mapped into each element of \a B.
+ * For more info on + * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering.
+ * \b Example: + * - \a this: [0,3,2,3,2,2,1,2] + * - \a targetNb: 4 + * - \a arr: [0, 6, 2,4,5,7, 1,3] + * - \a arrI: [0,1,2,6,8] + * + * This result means:
+ * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and + * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);
+ * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and + * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : + * \a arrI[ 2+1 ]]);
etc. + * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more + * than the maximal value of \a A. + * \param [out] arr - a new instance of DataArrayInt returning indices of + * elements of \a this, grouped by their place in the set \a B. The caller is to delete + * this array using decrRef() as it is no more needed. + * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal + * elements of \a this. The caller is to delete this array using decrRef() as it + * is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If any value in \a this is more or equal to \a targetNb. */ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception) { @@ -4534,17 +6321,31 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data arrI=retI.retn(); } + /*! - * This static method computes a old 2 new format DataArrayInt instance from a zip representation of a surjective format (retrived by DataArrayInt::findCommonTuples for example) - * The retrieved array minimizes the permutation. - * Let's take an example : - * If 'nbOfOldTuples'==10 and 'arr'==[0,3, 5,7,9] and 'arrI'==[0,2,5] it returns the following array [0,1,2,0,3,4,5,4,6,4] and newNbOfTuples==7. + * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed + * from a zip representation of a surjective format (returned e.g. by + * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()" + * for example). The result array minimizes the permutation.
+ * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
+ * \b Example:
+ * - \a nbOfOldTuples: 10 + * - \a arr : [0,3, 5,7,9] + * - \a arrIBg : [0,2,5] + * - \a newNbOfTuples: 7 + * - result array : [0,1,2,0,3,4,5,4,6,4] * - * @param nbOfOldTuples is the number of tuples in initial array. - * @param arr is the list of tuples ids grouped by 'arrI' array - * @param arrIBg is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple. - * @param arrIEnd is the entry point of 'arr' array (end not included) - * @param newNbOfTuples output parameter that retrieves the new number of tuples after surjection application + * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr. + * \param [in] arr - the array of tuple indices grouped by \a arrIBg array. + * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of + * (indices of) equal values. Its every element (except the last one) points to + * the first element of a group of equal values. + * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a + * arrIBg is \a arrIEnd[ -1 ]. + * \param [out] newNbOfTuples - number of tuples after surjection application. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ). */ DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception) { @@ -4585,14 +6386,18 @@ DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTu } /*! - * This method expects that 'this' is allocated and with only one component. If not an exception will be thrown. - * This method returns a newly created array with 'this->getNumberOfTuples()' tuples and 1 component. - * This methods returns an 'old2New' corresponding array that allows to follow the following rules : - * - Lower a value in tuple in 'this' is, higher is its priority. - * - If two tuples i and j have same value if igetNumberOfTuples()-1' - * - * Example if 'this' contains the following array : [2,0,1,1,0,1,2,0,1,1,0,0] this method returns [10,0,5,6,1,7,11,2,8,9,3,4] + * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode, + * which if applied to \a this array would make it sorted ascendingly. + * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
+ * \b Example:
+ * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0] + * - result: [10,0,5,6,1,7,11,2,8,9,3,4] + * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] + * + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. */ DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception) { @@ -4636,9 +6441,12 @@ DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Ex } /*! - * This method checks that 'this' is with numberofcomponents == 1 and that it is equal to - * stdext::iota() of size getNumberOfTuples. This method is particalary usefull for DataArrayInt instances - * that represents a renumbering array to check the real need in renumbering. + * Checks if contents of \a this array are equal to that of an array filled with + * iota(). This method is particularly useful for DataArrayInt instances that represent + * a renumbering array to check the real need in renumbering. + * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples()) + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. */ bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception) { @@ -4653,6 +6461,13 @@ bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception) return true; } +/*! + * Checks if all values in \a this array are equal to \a val. + * \param [in] val - value to check equality of array values to. + * \return bool - \a true if all values are \a val. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1 + */ bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -4667,6 +6482,11 @@ bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception) return true; } +/*! + * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this + * array to the new one. + * \return DataArrayDouble * - the new instance of DataArrayInt. + */ DataArrayDouble *DataArrayInt::convertToDblArr() const { checkAllocated(); @@ -4681,12 +6501,19 @@ DataArrayDouble *DataArrayInt::convertToDblArr() const } /*! - * This methods has a similar behaviour than std::string::substr. This method returns a newly created DataArrayInt that is part of this with same number of components. - * The intervall is specified by [tupleIdBg,tupleIdEnd) except if tupleIdEnd ==-1 in this case the [tupleIdBg,this->end()) will be kept. - * This method check that interval is valid regarding this, if not an exception will be thrown. - * This method is a specialization of method DataArrayInt::selectByTupleId2. - * - * \sa DataArrayInt::selectByTupleId2 + * Returns a shorten copy of \a this array. The new DataArrayInt contains all + * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before + * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr(). + * This method is a specialization of selectByTupleId2(). + * \param [in] tupleIdBg - index of the first tuple to copy from \a this array. + * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located. + * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a tupleIdBg < 0. + * \throw If \a tupleIdBg > \a this->getNumberOfTuples(). + \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples(). + * \sa DataArrayInt::selectByTupleId2 */ DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception) { @@ -4713,11 +6540,12 @@ DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(IN } /*! - * Contrary to DataArrayInt::changeNbOfComponents method this method is \b not const. The content - * This method \b do \b not change the content of data but changes the splitting of this data seen by the caller. - * This method makes the assumption that 'this' is already allocated. If not an exception will be thrown. - * This method checks that getNbOfElems()%newNbOfCompo==0. If not an exception will be throw ! - * This method erases all components info set before call ! + * Changes the number of components within \a this array so that its raw data **does + * not** change, instead splitting this data into tuples changes. + * \param [in] newNbOfComp - number of components for \a this array to have. + * \throw If \a this is not allocated + * \throw If getNbOfElems() % \a newNbOfCompo != 0. + * \warning This method erases all (name and unit) component info set before! */ void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception) { @@ -4731,9 +6559,14 @@ void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception) } /*! - * This method makes the assumption that \b this is allocated. If not an INTERP_KERNEL::Exception will be raised. - * This method does not echange the values stored in \b this. Simply, the number of components before the call becomes the number of - * tuples and inversely the number of tuples becomes the number of components. \b WARNING the info on components can be alterated by this method. + * Changes the number of components within \a this array to be equal to its number + * of tuples, and inversely its number of tuples to become equal to its number of + * components. So that its raw data **does not** change, instead splitting this + * data into tuples changes. + * \throw If \a this is not allocated. + * \warning This method erases all (name and unit) component info set before! + * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()! + * \sa rearrange() */ void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception) { @@ -4743,9 +6576,17 @@ void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception) } /*! - * This method builds a new instance of DataArrayInt (to deal with) that is reduction or an extension of 'this'. - * if 'newNbOfComp' < this->getNumberOfComponents() a reduction is done and for each tuple 'newNbOfComp' first components are kept. - * If 'newNbOfComp' > this->getNumberOfComponents() an extension is done, and for each components i such that i > getNumberOfComponents() 'dftValue' parameter is taken. + * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less + * than \a this->getNumberOfComponents() then the result array is shorten as each tuple + * is truncated to have \a newNbOfComp components, keeping first components. If \a + * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is + * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp + * components. + * \param [in] newNbOfComp - number of components for the new array to have. + * \param [in] dftValue - value assigned to new values added to the new array. + * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. */ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception) { @@ -4772,6 +6613,12 @@ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) return ret; } +/*! + * Changes number of tuples in the array. If the new number of tuples is smaller + * than the current number the array is truncated, otherwise the array is extended. + * \param [in] nbOfTuples - new number of tuples. + * \throw If \a this is not allocated. + */ void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -4779,6 +6626,22 @@ void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception) declareAsNew(); } + +/*! + * Returns a copy of \a this array composed of selected components. + * The new DataArrayInt has the same number of tuples but includes components + * specified by \a compoIds parameter. So that getNbOfElems() of the result array + * can be either less, same or more than \a this->getNbOfElems(). + * \param [in] compoIds - sequence of zero based indices of components to include + * into the new array. + * \return DataArrayInt * - the new instance of DataArrayInt that the caller + * is to delete using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If a component index (\a i) is not valid: + * \a i < 0 || \a i >= \a this->getNumberOfComponents(). + * + * \ref cpp_mcdataarrayint_keepselectedcomponents "Here is a Python example". + */ DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -4799,10 +6662,16 @@ DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compo } /*! - * This method melds the components of 'this' with components of 'other'. - * After this call in case of success, 'this' will contain a number of components equal to the sum of 'this' - * before the call and the number of components of 'other'. - * This method expects that 'this' and 'other' have exactly the same number of tuples. If not an exception is thrown. + * Appends components of another array to components of \a this one, tuple by tuple. + * So that the number of tuples of \a this array remains the same and the number of + * components increases. + * \param [in] other - the DataArrayInt to append to \a this one. + * \throw If \a this is not allocated. + * \throw If \a this and \a other arrays have different number of tuples. + * + * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example". + * + * \ref py_mcdataarrayint_meldwith "Here is a Python example". */ void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { @@ -4831,6 +6700,20 @@ void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exce copyPartOfStringInfoFrom2(compIds,*other); } +/*! + * Copy all components in a specified order from another DataArrayInt. + * The specified components become the first ones in \a this array. + * Both numerical and textual data is copied. The number of tuples in \a this and + * the other array can be different. + * \param [in] a - the array to copy data from. + * \param [in] compoIds - sequence of zero based indices of components, data of which is + * to be copied. + * \throw If \a a is NULL. + * \throw If \a compoIds.size() != \a a->getNumberOfComponents(). + * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). + * + * \ref cpp_mcdataarrayint_setselectedcomponents "Here is a Python example". + */ void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) { if(!a) @@ -4849,8 +6732,38 @@ void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vecto } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. - * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test. + * Copy all values from another DataArrayInt into specified tuples and components + * of \a this array. Textual data is not copied. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step). + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - index of the first tuple of \a this array to assign values to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \param [in] bgComp - index of the first component of \a this array to assign values to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() + * must be equal to the number of columns to assign to, else an + * exception is thrown; if \a false, then it is only required that \a + * a->getNbOfElems() equals to number of values to assign to (this condition + * must be respected even if \a strictCompoCompare is \a true). The number of + * values to assign to is given by following Python expression: + * \a nbTargetValues = + * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If parameters specifying tuples and components to assign to do not give a + * non-empty range of increasing indices. + * \throw If \a a->getNbOfElems() != \a nbTargetValues. + * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != + * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). + * + * \ref cpp_mcdataarrayint_setpartofvalues1 "Here is a Python example". */ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -4896,7 +6809,24 @@ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int end } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. + * Assign a given value to values at specified tuples and components of \a this array. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step).. + * \param [in] a - the value to assign. + * \param [in] bgTuples - index of the first tuple of \a this array to assign to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \throw If \a this is not allocated. + * \throw If parameters specifying tuples and components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref cpp_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example". */ void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception) { @@ -4914,9 +6844,44 @@ void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, in pt[j*stepComp]=a; } + /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. - * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test. + * Copy all values from another DataArrayInt (\a a) into specified tuples and + * components of \a this array. Textual data is not copied. + * The tuples and components to assign to are defined by C arrays of indices. + * There are two *modes of usage*: + * - If \a a->getNbOfElems() equals to number of values to assign to, then every value + * of \a a is assigned to its own location within \a this array. + * - If \a a includes one tuple, then all values of \a a are assigned to the specified + * components of every specified tuple of \a this array. In this mode it is required + * that \a a->getNumberOfComponents() equals to the number of specified components. + * + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign values of \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign values of \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \param [in] strictCompoCompare - this parameter is checked only if the + * *mode of usage* is the first; if it is \a true (default), + * then \a a->getNumberOfComponents() must be equal + * to the number of specified columns, else this is not required. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If any index of tuple/component given by bgTuples / bgComp is + * out of a valid range for \a this array. + * \throw In the first *mode of usage*, if strictCompoCompare == true and + * if a->getNumberOfComponents() != (endComp - bgComp) . + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * a->getNumberOfComponents() != (endComp - bgComp). + * + * \ref cpp_mcdataarrayint_setpartofvalues2 "Here is a Python example". */ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -4970,7 +6935,24 @@ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. + * Assign a given value to values at specified tuples and components of \a this array. + * The tuples and components to assign to are defined by C arrays of indices. + * \param [in] a - the value to assign. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (\a pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - pointer to an array of component indices of \a this array to + * assign \a a to. + * \param [in] endComp - specifies the end of the array \a bgTuples, so that + * pointer to a component index (\a pi) varies as this: + * \a bgComp <= \a pi < \a endComp. + * \throw If \a this is not allocated. + * \throw If any index of tuple/component given by bgTuples / bgComp is + * out of a valid range for \a this array. + * + * \ref cpp_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". */ void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception) { @@ -4989,8 +6971,48 @@ void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. - * 'strictCompoCompare' specifies if DataArray 'a' should have exactly same number of components and tuples than 'this' (true) or not (false). By default set to true with maximal test. + * Copy all values from another DataArrayInt (\a a) into specified tuples and + * components of \a this array. Textual data is not copied. + * The tuples to assign to are defined by a C array of indices. + * The components to assign to are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * There are two *modes of usage*: + * - If \a a->getNbOfElems() equals to number of values to assign to, then every value + * of \a a is assigned to its own location within \a this array. + * - If \a a includes one tuple, then all values of \a a are assigned to the specified + * components of every specified tuple of \a this array. In this mode it is required + * that \a a->getNumberOfComponents() equals to the number of specified components. + * + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign values of \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \param [in] strictCompoCompare - this parameter is checked only in the first + * *mode of usage*; if \a strictCompoCompare is \a true (default), + * then \a a->getNumberOfComponents() must be equal + * to the number of specified columns, else this is not required. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a this is not allocated. + * \throw If any index of tuple given by \a bgTuples is out of a valid range for + * \a this array. + * \throw In the first *mode of usage*, if strictCompoCompare == true and + * if a->getNumberOfComponents() is unequal to the number of components + * defined by (bgComp,endComp,stepComp). + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * a->getNumberOfComponents() is unequal to the number of components + * defined by (bgComp,endComp,stepComp). + * \throw If parameters specifying components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref cpp_mcdataarrayint_setpartofvalues3 "Here is a Python example". */ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) { @@ -5041,7 +7063,28 @@ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, } /*! - * This method performs a partial assignment of 'this' using 'a' as input. Other input parameters specifies the subpart being considered by the assignment. + * Assign a given value to values at specified tuples and components of \a this array. + * The tuples to assign to are defined by a C array of indices. + * The components to assign to are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * \param [in] a - the value to assign. + * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to + * assign \a a to. + * \param [in] endTuples - specifies the end of the array \a bgTuples, so that + * pointer to a tuple index (pi) varies as this: + * \a bgTuples <= \a pi < \a endTuples. + * \param [in] bgComp - index of the first component of \a this array to assign to. + * \param [in] endComp - index of the component before which the components to assign + * to are located. + * \param [in] stepComp - index increment to get index of the next component to assign to. + * \throw If \a this is not allocated. + * \throw If any index of tuple given by \a bgTuples is out of a valid range for + * \a this array. + * \throw If parameters specifying components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \this array. + * + * \ref cpp_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". */ void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception) { @@ -5121,9 +7164,25 @@ void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, in } /*! - * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown. - * @param a is an array having exactly the same number of components than 'this' - * @param tuplesSelec is an array having exactly 2 components. The first one refers to the tuple ids of 'this' that will be set. The second one refers to the tuple ids of 'a' that will be used for setting. + * Copy some tuples from another DataArrayInt into specified tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt. + * All components of selected tuples are copied. + * \param [in] a - the array to copy values from. + * \param [in] tuplesSelec - the array specifying both source tuples of \a a and + * target tuples of \a this. \a tuplesSelec has two components, and the + * first component specifies index of the source tuple and the second + * one specifies index of the target tuple. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a tuplesSelec is NULL. + * \throw If \a tuplesSelec is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a tuplesSelec->getNumberOfComponents() != 2. + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * the corresponding (\a this or \a a) array. */ void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) { @@ -5164,10 +7223,27 @@ void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt } /*! - * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown. - * This is a method that is a specialization to DataArrayInt::setPartOfValuesAdv method, except that here the tuple selection of 'a' is given by a range ('bg','end2' and 'step') - * rather than an explicite array of tuple ids (given by the 2nd component) and the feeding is done in 'this' contiguously starting from 'tupleIdStart'. - * @param a is an array having exactly the same number of components than 'this' + * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * The tuples to assign to are defined by index of the first tuple, and + * their number is defined by \a tuplesSelec->getNumberOfTuples(). + * The tuples to copy are defined by values of a DataArrayInt. + * All components of selected tuples are copied. + * \param [in] tupleIdStart - index of the first tuple of \a this array to assign + * values to. + * \param [in] a - the array to copy values from. + * \param [in] tuplesSelec - the array specifying tuples of \a a to copy. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If \a tuplesSelec is NULL. + * \throw If \a tuplesSelec is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a tuplesSelec->getNumberOfComponents() != 1. + * \throw If tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples(). + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * \a a array. */ void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArrayInt*a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) { @@ -5202,10 +7278,29 @@ void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArr } /*! - * 'this' and 'a' are expected to be defined. If not an exception will be thrown. - * This is a method that is a specialization to DataArrayInt::setContigPartOfSelectedValues method, except that here the tuple selection is givenin a is done by a range ('bg','end2' and 'step') - * rather than an explicite array of tuple ids. - * @param a is an array having exactly the same number of components than 'this' + * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * The tuples to copy are defined by three values similar to parameters of + * the Python function \c range(\c start,\c stop,\c step). + * The tuples to assign to are defined by index of the first tuple, and + * their number is defined by number of tuples to copy. + * All components of selected tuples are copied. + * \param [in] tupleIdStart - index of the first tuple of \a this array to assign + * values to. + * \param [in] a - the array to copy values from. + * \param [in] bg - index of the first tuple to copy of the array \a a. + * \param [in] end2 - index of the tuple of \a a before which the tuples to copy + * are located. + * \param [in] step - index increment to get index of the next tuple to copy. + * \throw If \a this is not allocated. + * \throw If \a a is NULL. + * \throw If \a a is not allocated. + * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples(). + * \throw If parameters specifying tuples to copy, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for the array \a a. */ void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArrayInt *a, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) { @@ -5231,9 +7326,16 @@ void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataAr } /*! - * This method is equivalent to DataArrayInt::getIJ except that here \b tupleId is checked to be in [0,this->getNumberOfTuples()) and compoId to be in [0,this->getNumberOfComponents()). - * If one of these check fails an INTERP_KERNEL::Exception will be thrown. - * So this method is safe but expensive if used to go through all data of \b this. + * Returns a value located at specified tuple and component. + * This method is equivalent to DataArrayInt::getIJ() except that validity of + * parameters is checked. So this method is safe but expensive if used to go through + * all values of \a this. + * \param [in] tupleId - index of tuple of interest. + * \param [in] compoId - index of component of interest. + * \return double - value located by \a tupleId and \a compoId. + * \throw If \a this is not allocated. + * \throw If condition ( 0 <= tupleId < this->getNumberOfTuples() ) is violated. + * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. */ int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) { @@ -5252,9 +7354,11 @@ int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL: } /*! - * This method returns the last element in 'this'. So this method makes the hypothesis that 'this' is allocated. - * This method works only for arrays that have exactly number of components equal to 1. If not an exception is thrown. - * And to finish this method works for arrays that have number of tuples >= 1. + * Returns the last value of \a this. + * \return double - the last value of \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 1. */ int DataArrayInt::back() const throw(INTERP_KERNEL::Exception) { @@ -5267,6 +7371,12 @@ int DataArrayInt::back() const throw(INTERP_KERNEL::Exception) return *(getConstPointer()+nbOfTuples-1); } +/*! + * Assign pointer to one array to a pointer to another appay. Reference counter of + * \a arrayToSet is incremented / decremented. + * \param [in] newArray - the pointer to array to assign to \a arrayToSet. + * \param [in,out] arrayToSet - the pointer to array to assign to. + */ void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet) { if(newArray!=arrayToSet) @@ -5284,6 +7394,15 @@ DataArrayIntIterator *DataArrayInt::iterator() return new DataArrayIntIterator(this); } +/*! + * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a + * given one. + * \param [in] val - the value to find within \a this. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5298,6 +7417,15 @@ DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exce return ret.retn(); } +/*! + * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not + * equal to a given one. + * \param [in] val - the value to ignore within \a this. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5312,11 +7440,15 @@ DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::E return ret.retn(); } + /*! - * This method expects that 'this' is allocated. If not an exception will be thrown. - * This method expect that the number of components is exactly equal to 1. If not an exception will be thrown. - * For each element in 'this' equal to 'oldValue' will take the value 'newValue'. - * @return number of elements impacted by the modification. + * Assigns \a newValue to all elements holding \a oldValue within \a this + * one-dimensional array. + * \param [in] oldValue - the value to replace. + * \param [in] newValue - the value to assign. + * \return int - number of replacements performed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. */ int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception) { @@ -5337,6 +7469,16 @@ int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::E return ret; } +/*! + * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to + * one of given values. + * \param [in] valsBg - an array of values to find within \a this array. + * \param [in] valsEnd - specifies the end of the array \a valsBg, so that + * the last value of \a valsBg is \a valsEnd[ -1 ]. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) @@ -5345,15 +7487,23 @@ DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEn const int *cptr=getConstPointer(); std::vector res; int nbOfTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); for(int i=0;ialloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } +/*! + * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not + * equal to any of given values. + * \param [in] valsBg - an array of values to ignore within \a this array. + * \param [in] valsEnd - specifies the end of the array \a valsBg, so that + * the last value of \a valsBg is \a valsEnd[ -1 ]. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this->getNumberOfComponents() != 1. + */ DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception) { if(getNumberOfComponents()!=1) @@ -5362,13 +7512,11 @@ DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *val const int *cptr=getConstPointer(); std::vector res; int nbOfTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); for(int i=0;ialloc((int)res.size(),1); - std::copy(res.begin(),res.end(),ret->getPointer()); - return ret; + ret->pushBackSilent(i); + return ret.retn(); } /*! @@ -5482,11 +7630,14 @@ bool DataArrayInt::presenceOfTuple(const std::vector& tupl) const throw(INT return locateTuple(tupl)!=-1; } + /*! - * This method expects to be called when number of components of this is equal to one. - * This method returns true if it exists a tuple equal to \b value. - * If not any tuple contains \b value false is returned. - * \sa DataArrayInt::locateValue + * Returns \a true if a given value is present within \a this one-dimensional array. + * \param [in] value - the value to find within \a this array. + * \return bool - \a true in case if \a value is present within \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \sa locateValue() */ bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception) { @@ -5504,7 +7655,13 @@ bool DataArrayInt::presenceOfValue(const std::vector& vals) const throw(INT return locateValue(vals)!=-1; } - +/*! + * Accumulates values of each component of \a this array. + * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated + * by the caller, that is filled by this method with sum value for each + * component. + * \throw If \a this is not allocated. + */ void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5530,6 +7687,23 @@ int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception) return ret; } +/*! + * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number + * of tuples in the result array is a1->getNumberOfTuples() + a2->getNumberOfTuples() - + * offsetA2 and (2) + * the number of component in the result array is same as that of each of given arrays. + * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] a1 - an array to include in the result array. + * \param [in] a2 - another array to include in the result array. + * \param [in] offsetA2 - number of tuples of \a a2 to skip. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents(). + */ DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2) { if(!a1 || !a2) @@ -5547,6 +7721,19 @@ DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt return ret; } +/*! + * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number + * of tuples in the result array is a sum of the number of tuples of given arrays and (2) + * the number of component in the result array is same as that of each of given arrays. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] arr - a sequence of arrays to include in the result array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arr are NULL. + * \throw If getNumberOfComponents() of arrays within \a arr. + */ DataArrayInt *DataArrayInt::Aggregate(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; @@ -5573,6 +7760,13 @@ DataArrayInt *DataArrayInt::Aggregate(const std::vector& a return ret; } +/*! + * Returns the maximal value and its location within \a this one-dimensional array. + * \param [out] tupleId - index of the tuple holding the maximal value. + * \return double - the maximal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5588,7 +7782,10 @@ int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception } /*! - * Idem to DataArrayInt::getMaxValue expect that here number of components can be >=1. + * Returns the maximal value within \a this array that is allowed to have more than + * one component. + * \return int - the maximal value among all values of \a this array. + * \throw If \a this is not allocated. */ int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception) { @@ -5597,6 +7794,13 @@ int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception) return *loc; } +/*! + * Returns the minimal value and its location within \a this one-dimensional array. + * \param [out] tupleId - index of the tuple holding the minimal value. + * \return int - the minimal value among all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5612,7 +7816,10 @@ int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception } /*! - * Idem to DataArrayInt::getMinValue expect that here number of components can be >=1. + * Returns the minimal value within \a this array that is allowed to have more than + * one component. + * \return int - the minimal value among all values of \a this array. + * \throw If \a this is not allocated. */ int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception) { @@ -5621,6 +7828,10 @@ int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception) return *loc; } +/*! + * Converts every value of \a this array to its absolute value. + * \throw If \a this is not allocated. + */ void DataArrayInt::abs() throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5630,6 +7841,14 @@ void DataArrayInt::abs() throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Apply a liner function to a given component of \a this array, so that + * an array element (x) becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \param [in] compoId - the index of component to modify. + * \throw If \a this is not allocated. + */ void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5641,6 +7860,13 @@ void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exce declareAsNew(); } +/*! + * Apply a liner function to all elements of \a this array, so that + * an element _x_ becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \throw If \a this is not allocated. + */ void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5652,8 +7878,12 @@ void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception) } /*! - * This method returns a newly allocated array containing the application of negate on \b this. - * This method throws an INTERP_KERNEL::Exception if \b this is not allocated. + * Returns a full copy of \a this array except that sign of all elements is reversed. + * \return DataArrayInt * - the new instance of DataArrayInt containing the + * same number of tuples and component as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. */ DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception) { @@ -5669,9 +7899,14 @@ DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception) } /*! - * This method applies the operation 'numerator/x' for each element 'x' in 'this'. - * If there is a value in 'this' exactly equal to 0. an exception is thrown. - * Warning if presence of null this is modified for each values previous than place where exception was thrown ! + * Modify all elements of \a this array, so that + * an element _x_ becomes \f$ numerator / x \f$. + * \param [in] numerator - the numerator used to modify array elements. + * \throw If \a this is not allocated. + * \throw If there is an element equal to 0 in \a this array. + * \warning If an exception is thrown because of presence of 0 element in \a this + * array, all elements processed before detection of the zero element remain + * modified. */ void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception) { @@ -5694,6 +7929,13 @@ void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes \f$ x / val \f$. + * \param [in] val - the denominator used to modify array elements. + * \throw If \a this is not allocated. + * \throw If \a val == 0. + */ void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception) { if(val==0) @@ -5705,6 +7947,13 @@ void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes x % val . + * \param [in] val - the divisor used to modify array elements. + * \throw If \a this is not allocated. + * \throw If \a val <= 0. + */ void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception) { if(val<=0) @@ -5743,9 +7992,14 @@ DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP } /*! - * This method applies the operation 'numerator%x' for each element 'x' in 'this'. - * If there is a value in 'this' exactly equals or lower than 0. an exception is thrown. - * Warning if presence of null this is modified for each values previous than place where exception was thrown ! + * Modify all elements of \a this array, so that + * an element _x_ becomes val % x . + * \param [in] val - the divident used to modify array elements. + * \throw If \a this is not allocated. + * \throw If there is an element equal to or less than 0 in \a this array. + * \warning If an exception is thrown because of presence of an element <= 0 in \a this + * array, all elements processed before detection of the zero element remain + * modified. */ void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception) { @@ -5768,6 +8022,22 @@ void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number + * of components in the result array is a sum of the number of components of given arrays + * and (2) the number of tuples in the result array is same as that of each of given + * arrays. In other words the i-th tuple of result array includes all components of + * i-th tuples of all given arrays. + * Number of tuples in the given arrays must be the same. + * \param [in] a1 - an array to include in the result array. + * \param [in] a2 - another array to include in the result array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If both \a a1 and \a a2 are NULL. + * \throw If any given array is not allocated. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + */ DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { std::vector arr(2); @@ -5775,6 +8045,21 @@ DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) return Meld(arr); } +/*! + * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number + * of components in the result array is a sum of the number of components of given arrays + * and (2) the number of tuples in the result array is same as that of each of given + * arrays. In other words the i-th tuple of result array includes all components of + * i-th tuples of all given arrays. + * Number of tuples in the given arrays must be the same. + * \param [in] arr - a sequence of arrays to include in the result array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arr are NULL. + * \throw If any given array is not allocated. + * \throw If getNumberOfTuples() of arrays within \a arr is different. + */ DataArrayInt *DataArrayInt::Meld(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; @@ -5817,13 +8102,28 @@ DataArrayInt *DataArrayInt::Meld(const std::vector& arr) t } /*! - * This method create a minimal partition of groups 'groups' the std::iota array of size 'newNb'. - * This method returns an array of size 'newNb' that specifies for each item at which familyId it owns to, and this method returns - * for each group the familyId it contains. If an id so that id + * and the result array contains IDs of families [ 1,3,3,0,2 ].
Note a family ID 0 which + * stands for the element #3 which is in none of groups. * - * @param groups in arrays specifying ids of each groups. - * @param newNb specifies size of whole set. Must be at least equal to max eltid in 'groups'. - * @return an array of size newNb specifying fid of each item. + * \param [in] groups - sequence of groups of element IDs. + * \param [in] newNb - total number of elements; it must be more than max ID of element + * in \a groups. + * \param [out] fidsOfGroups - IDs of families the elements of each group belong to. + * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families + * each element with ID from range [0, \a newNb ) belongs to. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ). */ DataArrayInt *DataArrayInt::MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups) throw(INTERP_KERNEL::Exception) { @@ -5880,6 +8180,17 @@ DataArrayInt *DataArrayInt::MakePartition(const std::vectorgetNumberOfComponents() != 1. + * \throw If any value of \a arr[i] is negative. + */ DataArrayInt *DataArrayInt::BuildUnion(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; @@ -5911,6 +8222,17 @@ DataArrayInt *DataArrayInt::BuildUnion(const std::vector& return ret; } +/*! + * Returns a new DataArrayInt which contains elements present in each of given one-dimensional + * not negative arrays. The result array does not contain any duplicates and its values + * are sorted in ascending order. + * \param [in] arr - sequence of DataArrayInt's to intersect. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If any \a arr[i] is not allocated. + * \throw If \a arr[i]->getNumberOfComponents() != 1. + * \throw If any value of \a arr[i] < 0. + */ DataArrayInt *DataArrayInt::BuildIntersection(const std::vector& arr) throw(INTERP_KERNEL::Exception) { std::vector a; @@ -5950,6 +8272,18 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vectorgetNumberOfComponents() != 1. + * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a + * nbOfElement ). + */ DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception) { checkAllocated(); @@ -5975,7 +8309,17 @@ DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_ } /*! - * \sa DataArrayInt::buildSubstractionOptimized + * Returns a new DataArrayInt containing elements of \a this one-dimensional missing + * from an \a other one-dimensional array. + * \param [in] other - a DataArrayInt containing elements not to include in the result array. + * \return DataArrayInt * - a new instance of DataArrayInt with one component. The + * caller is to delete this array using decrRef() as it is no more needed. + * \throw If \a other is NULL. + * \throw If \a other is not allocated. + * \throw If \a other->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \sa DataArrayInt::buildSubstractionOptimized() */ DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception) { @@ -6028,6 +8372,19 @@ DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other return ret.retn(); } + +/*! + * Returns a new DataArrayInt which contains all elements of \a this and a given + * one-dimensional not negative arrays. The result array does not contain any duplicates + * and its values are sorted in ascending order. + * \param [in] other - an array to unite with \a this one. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this or \a other is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a other->getNumberOfComponents() != 1. + * \throw If any value of \a this or \a other is negative. + */ DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception) { std::vectorarrs(2); @@ -6035,6 +8392,19 @@ DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(IN return BuildUnion(arrs); } + +/*! + * Returns a new DataArrayInt which contains elements present in both \a this and a given + * one-dimensional not negative arrays. The result array does not contain any duplicates + * and its values are sorted in ascending order. + * \param [in] other - an array to intersect with \a this one. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this or \a other is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a other->getNumberOfComponents() != 1. + * \throw If any value of \a this or \a other is negative. + */ DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception) { std::vectorarrs(2); @@ -6066,12 +8436,23 @@ DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception) } /*! - * This method could be usefull for returned DataArrayInt marked as index. Some methods that generate such DataArrayInt instances: - * - ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity - * - ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex - * This method makes the assumption that 'this' is allocated and has exactly one component and 2 or more tuples. If not an exception is thrown. - * This method retrives a newly created DataArrayInt instance with 1 component and this->getNumberOfTuples()-1 tuples. - * If this contains [1,3,6,7,7,9,15] -> returned array will contain [2,3,1,0,2,6]. + * Returns a new DataArrayInt which contains size of every of groups described by \a this + * "index" array. Such "index" array is returned for example by + * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity + * "MEDCouplingUMesh::buildDescendingConnectivity" and + * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex + * "MEDCouplingUMesh::getNodalConnectivityIndex" etc. + * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples + * equals to \a this->getNumberOfComponents() - 1, and number of components is 1. + * The caller is to delete this array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 2. + * + * \b Example:
+ * - this contains [1,3,6,7,7,9,15] + * - result array contains [2,3,1,0,2,6], + * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc. */ DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception) { @@ -6090,10 +8471,21 @@ DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Excepti } /*! - * This method performs the work on itself. This method works on array with number of component equal to one and allocated. If not an exception is thrown. - * This method conserves the number of tuples and number of components (1). No reallocation is done. - * For an array [3,5,1,2,0,8] it becomes [0,3,8,9,11,11]. For each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. - * This could be usefull for allToAllV in MPI with contiguous policy. + * Modifies \a this one-dimensional array so that value of each element \a x + * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$. + * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples + * and components remains the same.
+ * This method is useful for allToAllV in MPI with contiguous policy. This method + * differs from computeOffsets2() in that the number of tuples is \b not changed by + * this one. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * + * \b Example:
+ * - Before \a this contains [3,5,1,2,0,8] + * - After \a this contains [0,3,8,9,11,11]
+ * Note that the last element 19 = 11 + 8 is missing because size of \a this + * array is retained and thus there is no space to store the last element. */ void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception) { @@ -6115,12 +8507,20 @@ void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception) declareAsNew(); } + /*! - * Idem DataArrayInt::computeOffsets method execpt that 'this' changes its number of tuples. - * After the call in case of success new number of tuples is equal to old number of tuples +1. - * The content in 'this' for the first old number of tuples is exactly the same than those given by - * DataArrayInt::computeOffsets method. - * For an array [3,5,1,2,0,8] it becomes [0,3,8,9,11,11,19]. + * Modifies \a this one-dimensional array so that value of each element \a x + * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$. + * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number + * components remains the same and number of tuples is inceamented by one.
+ * This method is useful for allToAllV in MPI with contiguous policy. This method + * differs from computeOffsets() in that the number of tuples is changed by this one. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * + * \b Example:
+ * - Before \a this contains [3,5,1,2,0,8] + * - After \a this contains [0,3,8,9,11,11,19]
*/ void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception) { @@ -6139,11 +8539,29 @@ void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception) declareAsNew(); } + /*! - * This method works on array with number of component equal to one and allocated. If not an exception is thrown. - * 'offsets' should be monotic ascendently. If not, an exception will be thrown. - * This method retrives a newly created DataArrayInt instance with 1 component and this->getNumberOfTuples()-1 tuples. - * If 'this' contains [0,2,3] and 'offsets' [0,3,6,10,14,20] the returned array will contain [0,1,2,6,7,8,9,10,11,12,13] + * Returns a new DataArrayInt whose contents is computed from that of \a this and \a + * offsets arrays as follows. \a offsets is a one-dimensional array considered as an + * "index" array of a "iota" array, thus, whose each element gives an index of a group + * beginning within the "iota" array. And \a this is a one-dimensional array + * considered as a selector of groups described by \a offsets to include into the result array. + * \throw If \a offsets is NULL. + * \throw If \a offsets is not allocated. + * \throw If \a offsets->getNumberOfComponents() != 1. + * \throw If \a offsets is not monotonically increasing. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If any element of \a this is not a valid index for \a offsets array. + * + * \b Example:
+ * - \a this: [0,2,3] + * - \a offsets: [0,3,6,10,14,20] + * - result array: [0,1,2,6,7,8,9,10,11,12,13] ==
+ * \c range(0,3) + \c range(6,10) + \c range(10,14) ==
+ * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + + * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + + * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ]) */ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception) { @@ -6324,13 +8742,16 @@ DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(IN /*! * This method returns all different values found in \a this. This method throws if \a this has not been allocated. * But the number of components can be different from one. + * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this. */ -std::set DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception) +DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception) { checkAllocated(); std::set ret; ret.insert(begin(),end()); - return ret; + MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1); + std::copy(ret.begin(),ret.end(),ret2->getPointer()); + return ret2.retn(); } /*! @@ -6369,6 +8790,31 @@ std::vector DataArrayInt::partitionByDifferentValues(std::vector return ret; } +/*! + * Returns a new DataArrayInt that is a sum of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2, + * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - an array to sum up. + * \param [in] a2 - another array to sum up. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -6439,6 +8885,23 @@ DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) return ret.retn(); } +/*! + * Adds values of another DataArrayInt to values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is added to the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] += _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] += _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] += _a2_ [ 0, j ]. + * + * \param [in] other - an array to add to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { if(!other) @@ -6482,6 +8945,31 @@ void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exce declareAsNew(); } +/*! + * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a subtraction of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - an array to subtract from. + * \param [in] a2 - an array to subtract. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -6537,6 +9025,23 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt } } +/*! + * Subtract values of another DataArrayInt from values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is subtracted from the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] -= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] -= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] -= _a2_ [ 0, j ]. + * + * \param [in] other - an array to subtract from \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { if(!other) @@ -6575,6 +9080,31 @@ void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL declareAsNew(); } +/*! + * Returns a new DataArrayInt that is a product of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a product of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - a factor array. + * \param [in] a2 - another factor array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -6645,6 +9175,24 @@ DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt return ret.retn(); } + +/*! + * Multiply values of another DataArrayInt to values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is multiplied to the corresponding value of \a this array, i.e.: + * _a_ [ i, j ] *= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] *= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] *= _a2_ [ 0, j ]. + * + * \param [in] other - an array to multiply to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { if(!other) @@ -6688,6 +9236,33 @@ void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL: declareAsNew(); } + +/*! + * Returns a new DataArrayInt that is a division of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a division of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - a numerator array. + * \param [in] a2 - a denominator array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + * \warning No check of division by zero is performed! + */ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -6743,6 +9318,24 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a } } +/*! + * Divide values of \a this array by values of another DataArrayInt. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a this array is divided by the corresponding value of \a other one, i.e.: + * _a_ [ i, j ] /= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] /= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] /= _a2_ [ 0, j ]. + * + * \param [in] other - an array to divide \a this one by. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + * \warning No check of division by zero is performed! + */ void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { if(!other) @@ -6786,6 +9379,33 @@ void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::E declareAsNew(); } + +/*! + * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a division of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - a dividend array. + * \param [in] a2 - a divisor array. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + * \warning No check of division by zero is performed! + */ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) { if(!a1 || !a2) @@ -6841,6 +9461,24 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * } } +/*! + * Modify \a this array so that each value becomes a modulus of division of this value by + * a value of another DataArrayInt. There are 3 valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a this array is divided by the corresponding value of \a other one, i.e.: + * _a_ [ i, j ] %= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _a_ [ i, j ] %= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _a_ [ i, j ] %= _a2_ [ 0, j ]. + * + * \param [in] other - a divisor array. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + * \warning No check of division by zero is performed! + */ void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) { if(!other) @@ -6884,6 +9522,19 @@ void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL:: declareAsNew(); } +/*! + * Returns a C array which is a renumbering map in "Old to New" mode for the input array. + * This map, if applied to \a start array, would make it sorted. For example, if + * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is + * [5,6,0,3,2,7,1,4]. + * \param [in] start - pointer to the first element of the array for which the + * permutation map is computed. + * \param [in] end - pointer specifying the end of the array \a start, so that + * the last value of \a start is \a end[ -1 ]. + * \return int * - the result permutation array that the caller is to delete as it is no + * more needed. + * \throw If there are equal values in the input array. + */ int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end) { std::size_t sz=std::distance(start,end); @@ -6904,6 +9555,20 @@ int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end) return ret; } +/*! + * Returns a new DataArrayInt containing an arithmetic progression + * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step ) + * function. + * \param [in] begin - the start value of the result sequence. + * \param [in] end - limiting value, so that every value of the result array is less than + * \a end. + * \param [in] step - specifies the increment or decrement. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a step == 0. + * \throw If \a end < \a begin && \a step > 0. + * \throw If \a end > \a begin && \a step < 0. + */ DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception) { int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range"); diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 115ad548f..7f52b8ff0 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -25,9 +25,9 @@ #include "MEDCouplingTimeLabel.hxx" #include "MEDCouplingRefCountObject.hxx" #include "InterpKernelException.hxx" +#include "BBTreePts.txx" #include "BBTree.txx" -#include #include #include #include @@ -193,7 +193,6 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool isEqual(const DataArrayDouble& other, double prec) const; MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const; MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const; - //!alloc or useArray should have been called before. MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const; MEDCOUPLING_EXPORT DataArrayDouble *fromNoInterlace() const throw(INTERP_KERNEL::Exception); @@ -214,8 +213,10 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); @@ -306,7 +307,6 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayDouble *Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - //! nothing to do here because this class does not aggregate any TimeLabel instance. MEDCOUPLING_EXPORT void updateTime() const { } public: MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; @@ -317,6 +317,8 @@ namespace ParaMEDMEM template void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const; template + static void FindClosestTupleIdAlg(const BBTreePts& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res); + template static void FindTupleIdsNearTuplesAlg(const BBTree& myTree, const double *pos, int nbOfTuples, double eps, DataArrayInt *c, DataArrayInt *cI); private: @@ -411,7 +413,6 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const; MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const; MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception); - //!alloc or useArray should have been called before. MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const; MEDCOUPLING_EXPORT DataArrayInt *fromNoInterlace() const throw(INTERP_KERNEL::Exception); @@ -508,7 +509,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT std::set getDifferentValues() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *getDifferentValues() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::vector partitionByDifferentValues(std::vector& differentIds) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); void MEDCOUPLING_EXPORT useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo); @@ -525,7 +526,6 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - //! nothing to do here because this class does not aggregate any TimeLabel instance. MEDCOUPLING_EXPORT void updateTime() const { } public: MEDCOUPLING_EXPORT static int *CheckAndPreparePermutation(const int *start, const int *end); diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index 38e09721d..0f39cdfb5 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -110,6 +110,7 @@ bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const t * This method checks geo equivalence between two meshes : 'this' and 'other'. * If no exception is throw 'this' and 'other' are geometrically equivalent regarding 'levOfCheck' level. * This method is typically used to change the mesh of a field "safely" depending the 'levOfCheck' level considered. + * So in case of success cell \c other[i] is equal to cell \c this[cellCor[i]]. If \a cellCor is null it means that for all i cell \c other[i] is equal to cell \c this[i]. * * @param levOfCheck input that specifies the level of check specified. The possible values are listed below. * @param prec input that specifies precision for double float data used for comparison in meshes. diff --git a/src/MEDCoupling/MEDCouplingMultiFields.cxx b/src/MEDCoupling/MEDCouplingMultiFields.cxx index d26186768..5aab55dd3 100644 --- a/src/MEDCoupling/MEDCouplingMultiFields.cxx +++ b/src/MEDCoupling/MEDCouplingMultiFields.cxx @@ -342,8 +342,8 @@ MEDCouplingMultiFields::MEDCouplingMultiFields(const MEDCouplingMultiFields& oth { if((const MEDCouplingFieldDouble *)other._fs[i]) { - MEDCouplingFieldTemplate *tmp=MEDCouplingFieldTemplate::New(other._fs[i]); - _fs[i]=MEDCouplingFieldDouble::New(tmp,other._fs[i]->getTimeDiscretization()); + MEDCouplingFieldTemplate *tmp=MEDCouplingFieldTemplate::New(*other._fs[i]); + _fs[i]=MEDCouplingFieldDouble::New(*tmp,other._fs[i]->getTimeDiscretization()); tmp->decrRef(); if(refs[i]!=-1) _fs[i]->setMesh(ms2[refs[i]]); @@ -437,7 +437,7 @@ void MEDCouplingMultiFields::finishUnserialization(const std::vector& tinyI int offD=0; for(int i=0;i tmp(sz3); for(int j=0;j -MEDCouplingNormalizedCartesianMesh::MEDCouplingNormalizedCartesianMesh(ParaMEDMEM::MEDCouplingCMesh *mesh):_mesh(mesh) +MEDCouplingNormalizedCartesianMesh::MEDCouplingNormalizedCartesianMesh(const ParaMEDMEM::MEDCouplingCMesh *mesh):_mesh(mesh) { if(_mesh) _mesh->incrRef(); diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index 6a3f9df19..3f6886a53 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -400,6 +400,10 @@ void MEDCouplingPointSet::rotate(const double *center, const double *vector, dou */ void MEDCouplingPointSet::translate(const double *vector) { + if(!vector) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::translate : NULL input vector !"); + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::translate : no coordinates set !"); double *coords=_coords->getPointer(); int nbNodes=getNumberOfNodes(); int dim=getSpaceDimension(); @@ -417,6 +421,10 @@ void MEDCouplingPointSet::translate(const double *vector) */ void MEDCouplingPointSet::scale(const double *point, double factor) { + if(!point) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::scale : NULL input point !"); + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::scale : no coordinates set !"); double *coords=_coords->getPointer(); int nbNodes=getNumberOfNodes(); int dim=getSpaceDimension(); @@ -803,6 +811,8 @@ void MEDCouplingPointSet::Rotate3DAlg(const double *center, const double *vect, double matrix[9]; double matrixTmp[9]; double norm=sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]); + if(norm::min()) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::Rotate3DAlg : magnitude of input vector is too close of 0. !"); std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies(),1/norm)); //rotation matrix computation matrix[0]=cosa; matrix[1]=0.; matrix[2]=0.; matrix[3]=0.; matrix[4]=cosa; matrix[5]=0.; matrix[6]=0.; matrix[7]=0.; matrix[8]=cosa; @@ -843,7 +853,7 @@ MEDCouplingMesh *MEDCouplingPointSet::buildPart(const int *start, const int *end * This method build a part of 'this' by simply keeping cells whose ids are in ['start','end') \b and potentially reduces the nodes set * behind returned mesh. This cause an overhead but it is lesser in memory. * This method returns an array too. This array allows to the caller to know the mapping between nodeids in 'this' and nodeids in - * returned mesh. This is quite usefull for MEDCouplingFieldDouble on nodes for example... + * returned mesh. This is quite useful for MEDCouplingFieldDouble on nodes for example... * 'arr' is in old2New format of size ret->getNumberOfCells like MEDCouplingUMesh::zipCoordsTraducer is. * The returned mesh has to be managed by the caller. */ diff --git a/src/MEDCoupling/MEDCouplingRemapper.cxx b/src/MEDCoupling/MEDCouplingRemapper.cxx index 033fe91b2..09980fa17 100644 --- a/src/MEDCoupling/MEDCouplingRemapper.cxx +++ b/src/MEDCoupling/MEDCouplingRemapper.cxx @@ -40,7 +40,7 @@ using namespace ParaMEDMEM; -MEDCouplingRemapper::MEDCouplingRemapper():_src_mesh(0),_target_mesh(0),_nature_of_deno(NoNature),_time_deno_update(0) +MEDCouplingRemapper::MEDCouplingRemapper():_src_ft(0),_target_ft(0),_interp_matrix_pol(IK_ONLY_PREFERED),_nature_of_deno(NoNature),_time_deno_update(0) { } @@ -51,32 +51,66 @@ MEDCouplingRemapper::~MEDCouplingRemapper() int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const char *method) throw(INTERP_KERNEL::Exception) { + if(!srcMesh || !targetMesh) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepare : presence of NULL input pointer !"); + std::string srcMethod,targetMethod; + INTERP_KERNEL::Interpolation::CheckAndSplitInterpolationMethod(method,srcMethod,targetMethod); + MEDCouplingAutoRefCountObjectPtr src=MEDCouplingFieldTemplate::New(MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(srcMethod.c_str())); + src->setMesh(srcMesh); + MEDCouplingAutoRefCountObjectPtr target=MEDCouplingFieldTemplate::New(MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(targetMethod.c_str())); + target->setMesh(targetMesh); + return prepareEx(src,target); +} + +int MEDCouplingRemapper::prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) throw(INTERP_KERNEL::Exception) +{ + if(!src || !target) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareEx : presence of NULL input pointer !"); + if(!src->getMesh() || !target->getMesh()) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareEx : presence of NULL mesh pointer in given field template !"); releaseData(true); - _src_mesh=const_cast(srcMesh); _target_mesh=const_cast(targetMesh); - _src_mesh->incrRef(); _target_mesh->incrRef(); - int meshInterpType=((int)_src_mesh->getType()*16)+(int)_target_mesh->getType(); + _src_ft=const_cast(src); _src_ft->incrRef(); + _target_ft=const_cast(target); _target_ft->incrRef(); + if(isInterpKernelOnlyOrNotOnly()) + return prepareInterpKernelOnly(); + else + return prepareNotInterpKernelOnly(); +} + +int MEDCouplingRemapper::prepareInterpKernelOnly() throw(INTERP_KERNEL::Exception) +{ + int meshInterpType=((int)_src_ft->getMesh()->getType()*16)+(int)_target_ft->getMesh()->getType(); switch(meshInterpType) { case 85://Unstructured-Unstructured - return prepareUU(method); + return prepareInterpKernelOnlyUU(); case 87://Unstructured-Cartesian - return prepareUC(method); + return prepareInterpKernelOnlyUC(); case 117://Cartesian-Unstructured - return prepareCU(method); + return prepareInterpKernelOnlyCU(); case 119://Cartesian-Cartesian - return prepareCC(method); + return prepareInterpKernelOnlyCC(); case 136://Extruded-Extruded - return prepareEE(method); + return prepareInterpKernelOnlyEE(); default: - throw INTERP_KERNEL::Exception("Not managed type of meshes !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnly : Not managed type of meshes ! Dealt meshes type are : Unstructured<->Unstructured, Unstructured<->Cartesian, Cartesian<->Cartesian, Extruded<->Extruded !"); } } -int MEDCouplingRemapper::prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) throw(INTERP_KERNEL::Exception) +int MEDCouplingRemapper::prepareNotInterpKernelOnly() throw(INTERP_KERNEL::Exception) { - std::string meth(src->getDiscretization()->getStringRepr()); - meth+=target->getDiscretization()->getStringRepr(); - return prepare(src->getMesh(),target->getMesh(),meth.c_str()); + std::string srcm,trgm,method; + method=checkAndGiveInterpolationMethodStr(srcm,trgm); + switch(CheckInterpolationMethodManageableByNotOnlyInterpKernel(method)) + { + case 0: + return prepareNotInterpKernelOnlyGaussGauss(); + default: + { + std::ostringstream oss; oss << "MEDCouplingRemapper::prepareNotInterpKernelOnly : INTERNAL ERROR ! the method \"" << method << "\" declared as managed bu not implemented !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } } /*! @@ -107,9 +141,10 @@ void MEDCouplingRemapper::partialTransfer(const MEDCouplingFieldDouble *srcField void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception) { - if(_src_method!=srcField->getDiscretization()->getStringRepr()) + checkPrepare(); + if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - if(_target_method!=targetField->getDiscretization()->getStringRepr()) + if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); if(srcField->getNature()!=targetField->getNature()) throw INTERP_KERNEL::Exception("Natures of fields mismatch !"); @@ -135,48 +170,129 @@ void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, cons MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception) { - if(_src_method!=srcField->getDiscretization()->getStringRepr()) + checkPrepare(); + if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(MEDCouplingFieldDiscretization::getTypeOfFieldFromStringRepr(_target_method.c_str()),srcField->getTimeDiscretization()); - ret->copyAllTinyAttrFrom(srcField); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(*_target_ft,srcField->getTimeDiscretization()); ret->setNature(srcField->getNature()); - ret->setMesh(_target_mesh); transfer(srcField,ret,dftValue); + ret->copyAllTinyAttrFrom(srcField);//perform copy of tiny strings after and not before transfer because the array will be created on transfer return ret; } MEDCouplingFieldDouble *MEDCouplingRemapper::reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception) { - if(_target_method!=targetField->getDiscretization()->getStringRepr()) + checkPrepare(); + if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(MEDCouplingFieldDiscretization::getTypeOfFieldFromStringRepr(_src_method.c_str()),targetField->getTimeDiscretization()); - ret->copyAllTinyAttrFrom(targetField); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(*_src_ft,targetField->getTimeDiscretization()); ret->setNature(targetField->getNature()); - ret->setMesh(_src_mesh); reverseTransfer(ret,targetField,dftValue); + ret->copyAllTinyAttrFrom(targetField);//perform copy of tiny strings after and not before reverseTransfer because the array will be created on reverseTransfer return ret; } +/*! + * This method does nothing more than inherited INTERP_KERNEL::InterpolationOptions::setOptionInt method. This method + * is here only for automatic CORBA generators. + */ bool MEDCouplingRemapper::setOptionInt(const std::string& key, int value) { return INTERP_KERNEL::InterpolationOptions::setOptionInt(key,value); } +/*! + * This method does nothing more than inherited INTERP_KERNEL::InterpolationOptions::setOptionInt method. This method + * is here only for automatic CORBA generators. + */ bool MEDCouplingRemapper::setOptionDouble(const std::string& key, double value) { return INTERP_KERNEL::InterpolationOptions::setOptionDouble(key,value); } +/*! + * This method does nothing more than inherited INTERP_KERNEL::InterpolationOptions::setOptionInt method. This method + * is here only for automatic CORBA generators. + */ bool MEDCouplingRemapper::setOptionString(const std::string& key, const std::string& value) { return INTERP_KERNEL::InterpolationOptions::setOptionString(key,value); } -int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exception) +/*! + * This method returns the interpolation matrix policy. This policy specifies which interpolation matrix method to keep or prefered. + * If interpolation matrix policy is : + * + * - set to IK_ONLY_PREFERED (0) (the default) : the INTERP_KERNEL only method is prefered. That is to say, if it is possible to treat the case + * regarding spatial discretization of source and target with INTERP_KERNEL only method, INTERP_KERNEL only method will be performed. + * If not, the \b not only INTERP_KERNEL method will be attempt. + * + * - set to NOT_IK_ONLY_PREFERED (1) : the \b NOT only INTERP_KERNEL method is prefered. That is to say, if it is possible to treat the case + * regarding spatial discretization of source and target with \b NOT only INTERP_KERNEL method, \b NOT only INTERP_KERNEL method, will be performed. + * If not, the INTERP_KERNEL only method will be attempt. + * + * - IK_ONLY_FORCED (2) : Only INTERP_KERNEL only method will be launched. + * + * - NOT_IK_ONLY_FORCED (3) : Only \b NOT INTERP_KERNEL only method will be launched. + * + * \sa MEDCouplingRemapper::setInterpolationMatrixPolicy + */ +int MEDCouplingRemapper::getInterpolationMatrixPolicy() const +{ + return _interp_matrix_pol; +} + +/*! + * This method sets a new interpolation matrix policy. The default one is IK_PREFERED (0). The input is of type \c int to be dealt by standard Salome + * CORBA component generators. This method throws an INTERP_KERNEL::Exception if a the input integer is not in the available possibilities, that is to say not in + * [0 (IK_PREFERED) , 1 (NOT_IK_PREFERED), 2 (IK_ONLY_FORCED), 3 (NOT_IK_ONLY_FORCED)]. + * + * If interpolation matrix policy is : + * + * - set to IK_ONLY_PREFERED (0) (the default) : the INTERP_KERNEL only method is prefered. That is to say, if it is possible to treat the case + * regarding spatial discretization of source and target with INTERP_KERNEL only method, INTERP_KERNEL only method will be performed. + * If not, the \b not only INTERP_KERNEL method will be attempt. + * + * - set to NOT_IK_ONLY_PREFERED (1) : the \b NOT only INTERP_KERNEL method is prefered. That is to say, if it is possible to treat the case + * regarding spatial discretization of source and target with \b NOT only INTERP_KERNEL method, \b NOT only INTERP_KERNEL method, will be performed. + * If not, the INTERP_KERNEL only method will be attempt. + * + * - IK_ONLY_FORCED (2) : Only INTERP_KERNEL only method will be launched. + * + * - NOT_IK_ONLY_FORCED (3) : Only \b NOT INTERP_KERNEL only method will be launched. + * + * \input newInterpMatPol the new interpolation matrix method policy. This parameter is of type \c int and not of type \c ParaMEDMEM::InterpolationMatrixPolicy + * for automatic generation of CORBA component. + * + * \sa MEDCouplingRemapper::getInterpolationMatrixPolicy + */ +void MEDCouplingRemapper::setInterpolationMatrixPolicy(int newInterpMatPol) throw(INTERP_KERNEL::Exception) +{ + switch(newInterpMatPol) + { + case 0: + _interp_matrix_pol=IK_ONLY_PREFERED; + break; + case 1: + _interp_matrix_pol=NOT_IK_ONLY_PREFERED; + break; + case 2: + _interp_matrix_pol=IK_ONLY_FORCED; + break; + case 3: + _interp_matrix_pol=NOT_IK_ONLY_FORCED; + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::setInterpolationMatrixPolicy : invalid input integer value ! Should be in [0 (IK_PREFERED) , 1 (NOT_IK_PREFERED), 2 (IK_ONLY_FORCED), 3 (NOT_IK_ONLY_FORCED)] ! For information, the default is IK_PREFERED=0 !"); + } +} + +int MEDCouplingRemapper::prepareInterpKernelOnlyUU() throw(INTERP_KERNEL::Exception) { - MEDCouplingUMesh *src_mesh=(MEDCouplingUMesh *)_src_mesh; - MEDCouplingUMesh *target_mesh=(MEDCouplingUMesh *)_target_mesh; - INTERP_KERNEL::Interpolation::checkAndSplitInterpolationMethod(method,_src_method,_target_method); + const MEDCouplingUMesh *src_mesh=static_cast(_src_ft->getMesh()); + const MEDCouplingUMesh *target_mesh=static_cast(_target_ft->getMesh()); + std::string srcMeth,trgMeth; + std::string method=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); const int srcMeshDim=src_mesh->getMeshDimension(); int srcSpaceDim=-1; if(srcMeshDim!=-1) @@ -194,35 +310,35 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<1,1> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<1,1> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation1D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==1 && trgMeshDim==1 && srcSpaceDim==2) { MEDCouplingNormalizedUnstructuredMesh<2,1> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<2,1> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2DCurve interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==2 && trgMeshDim==2 && srcSpaceDim==2) { MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==3 && trgMeshDim==3 && srcSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==2 && trgMeshDim==2 && srcSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<3,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==3 && trgMeshDim==1 && srcSpaceDim==3) { @@ -231,7 +347,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else if(srcMeshDim==1 && trgMeshDim==3 && srcSpaceDim==3) { @@ -241,7 +357,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method.c_str()); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); } @@ -252,7 +368,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); } else { @@ -260,7 +376,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D1D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method.c_str()); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); @@ -284,7 +400,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method.c_str()); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); } @@ -293,7 +409,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D1D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); if(!duplicateFaces.empty()) { @@ -312,7 +428,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D2D interpolation(*this); - nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method.c_str()); INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); if(!duplicateFaces.empty()) { @@ -331,7 +447,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D2D interpolation(*this); std::vector > matrixTmp; - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method.c_str()); ReverseMatrix(matrixTmp,nbCols,_matrix); nbCols=matrixTmp.size(); INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); @@ -352,19 +468,19 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce { MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,_src_method.c_str()); + nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth.c_str()); } else if(srcMeshDim==3 && srcSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,_src_method.c_str()); + nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth.c_str()); } else if(srcMeshDim==2 && srcSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(src_mesh); INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,_src_method.c_str()); + nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth.c_str()); } else throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension of source mesh to -1D targetMesh"); @@ -375,19 +491,19 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce { MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,_target_method.c_str()); + nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth.c_str()); } else if(trgMeshDim==3 && trgSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3D interpolation(*this); - nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,_target_method.c_str()); + nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth.c_str()); } else if(trgMeshDim==2 && trgSpaceDim==3) { MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(target_mesh); INTERP_KERNEL::Interpolation3DSurf interpolation(*this); - nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,_target_method.c_str()); + nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth.c_str()); } else throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension of source mesh from -1D sourceMesh"); @@ -402,19 +518,19 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce return 1; } -int MEDCouplingRemapper::prepareEE(const char *method) throw(INTERP_KERNEL::Exception) +int MEDCouplingRemapper::prepareInterpKernelOnlyEE() throw(INTERP_KERNEL::Exception) { - MEDCouplingExtrudedMesh *src_mesh=(MEDCouplingExtrudedMesh *)_src_mesh; - MEDCouplingExtrudedMesh *target_mesh=(MEDCouplingExtrudedMesh *)_target_mesh; - std::string methC(method); + std::string srcMeth,trgMeth; + std::string methC=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); + const MEDCouplingExtrudedMesh *src_mesh=static_cast(_src_ft->getMesh()); + const MEDCouplingExtrudedMesh *target_mesh=static_cast(_target_ft->getMesh()); if(methC!="P0P0") - throw INTERP_KERNEL::Exception("Only P0P0 method implemented for Extruded/Extruded meshes !"); - INTERP_KERNEL::Interpolation::checkAndSplitInterpolationMethod(method,_src_method,_target_method); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyEE : Only P0P0 method implemented for Extruded/Extruded meshes !"); MEDCouplingNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(src_mesh->getMesh2D()); MEDCouplingNormalizedUnstructuredMesh<3,2> target_mesh_wrapper(target_mesh->getMesh2D()); INTERP_KERNEL::Interpolation3DSurf interpolation2D(*this); std::vector > matrix2D; - int nbCols2D=interpolation2D.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,matrix2D,method); + int nbCols2D=interpolation2D.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,matrix2D,methC.c_str()); MEDCouplingUMesh *s1D,*t1D; double v[3]; MEDCouplingExtrudedMesh::Project1DMeshes(src_mesh->getMesh1D(),target_mesh->getMesh1D(),getPrecision(),s1D,t1D,v); @@ -422,7 +538,7 @@ int MEDCouplingRemapper::prepareEE(const char *method) throw(INTERP_KERNEL::Exce MEDCouplingNormalizedUnstructuredMesh<1,1> t1DWrapper(t1D); std::vector > matrix1D; INTERP_KERNEL::Interpolation1D interpolation1D(*this); - int nbCols1D=interpolation1D.interpolateMeshes(s1DWrapper,t1DWrapper,matrix1D,method); + int nbCols1D=interpolation1D.interpolateMeshes(s1DWrapper,t1DWrapper,matrix1D,methC.c_str()); s1D->decrRef(); t1D->decrRef(); buildFinalInterpolationMatrixByConvolution(matrix1D,matrix2D,src_mesh->getMesh3DIds()->getConstPointer(),nbCols2D,nbCols1D, @@ -436,19 +552,19 @@ int MEDCouplingRemapper::prepareEE(const char *method) throw(INTERP_KERNEL::Exce return 1; } -int MEDCouplingRemapper::prepareUC(const char *method) throw(INTERP_KERNEL::Exception) +int MEDCouplingRemapper::prepareInterpKernelOnlyUC() throw(INTERP_KERNEL::Exception) { - std::string methodCpp(method); + std::string srcMeth,trgMeth; + std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); if(methodCpp!="P0P0") - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareUC : only P0P0 interpolation supported for the moment !"); - INTERP_KERNEL::Interpolation::checkAndSplitInterpolationMethod(method,_src_method,_target_method); - MEDCouplingUMesh *src_mesh=static_cast(_src_mesh); - MEDCouplingCMesh *target_mesh=static_cast(_target_mesh); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : only P0P0 interpolation supported for the moment !"); + const MEDCouplingUMesh *src_mesh=static_cast(_src_ft->getMesh()); + const MEDCouplingCMesh *target_mesh=static_cast(_target_ft->getMesh()); const int srcMeshDim=src_mesh->getMeshDimension(); const int srcSpceDim=src_mesh->getSpaceDimension(); const int trgMeshDim=target_mesh->getMeshDimension(); if(srcMeshDim!=srcSpceDim || srcMeshDim!=trgMeshDim) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareUC : space dim of src unstructured should be equal to mesh dim of src unstructured and should be equal also equal to trg cartesian dimension !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : space dim of src unstructured should be equal to mesh dim of src unstructured and should be equal also equal to trg cartesian dimension !"); std::vector > res; switch(srcMeshDim) { @@ -477,7 +593,7 @@ int MEDCouplingRemapper::prepareUC(const char *method) throw(INTERP_KERNEL::Exce break; } default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareUC : only dimension 1 2 or 3 supported !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : only dimension 1 2 or 3 supported !"); } ReverseMatrix(res,target_mesh->getNumberOfCells(),_matrix); nullifiedTinyCoeffInCrudeMatrixAbs(0.); @@ -490,19 +606,19 @@ int MEDCouplingRemapper::prepareUC(const char *method) throw(INTERP_KERNEL::Exce return 1; } -int MEDCouplingRemapper::prepareCU(const char *method) throw(INTERP_KERNEL::Exception) +int MEDCouplingRemapper::prepareInterpKernelOnlyCU() throw(INTERP_KERNEL::Exception) { - std::string methodCpp(method); + std::string srcMeth,trgMeth; + std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); if(methodCpp!="P0P0") - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCU : only P0P0 interpolation supported for the moment !"); - INTERP_KERNEL::Interpolation::checkAndSplitInterpolationMethod(method,_src_method,_target_method); - MEDCouplingCMesh *src_mesh=static_cast(_src_mesh); - MEDCouplingUMesh *target_mesh=static_cast(_target_mesh); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only P0P0 interpolation supported for the moment !"); + const MEDCouplingCMesh *src_mesh=static_cast(_src_ft->getMesh()); + const MEDCouplingUMesh *target_mesh=static_cast(_target_ft->getMesh()); const int srcMeshDim=src_mesh->getMeshDimension(); const int trgMeshDim=target_mesh->getMeshDimension(); const int trgSpceDim=target_mesh->getSpaceDimension(); if(trgMeshDim!=trgSpceDim || trgMeshDim!=srcMeshDim) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCU : space dim of target unstructured should be equal to mesh dim of target unstructured and should be equal also equal to source cartesian dimension !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : space dim of target unstructured should be equal to mesh dim of target unstructured and should be equal also equal to source cartesian dimension !"); switch(srcMeshDim) { case 1: @@ -530,7 +646,7 @@ int MEDCouplingRemapper::prepareCU(const char *method) throw(INTERP_KERNEL::Exce break; } default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCU : only dimension 1 2 or 3 supported !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only dimension 1 2 or 3 supported !"); } nullifiedTinyCoeffInCrudeMatrixAbs(0.); // @@ -542,18 +658,18 @@ int MEDCouplingRemapper::prepareCU(const char *method) throw(INTERP_KERNEL::Exce return 1; } -int MEDCouplingRemapper::prepareCC(const char *method) throw(INTERP_KERNEL::Exception) +int MEDCouplingRemapper::prepareInterpKernelOnlyCC() throw(INTERP_KERNEL::Exception) { - std::string methodCpp(method); + std::string srcMeth,trgMeth; + std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); if(methodCpp!="P0P0") - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCC : only P0P0 interpolation supported for the moment !"); - INTERP_KERNEL::Interpolation::checkAndSplitInterpolationMethod(method,_src_method,_target_method); - MEDCouplingCMesh *src_mesh=static_cast(_src_mesh); - MEDCouplingCMesh *target_mesh=static_cast(_target_mesh); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only P0P0 interpolation supported for the moment !"); + const MEDCouplingCMesh *src_mesh=static_cast(_src_ft->getMesh()); + const MEDCouplingCMesh *target_mesh=static_cast(_target_ft->getMesh()); const int srcMeshDim=src_mesh->getMeshDimension(); const int trgMeshDim=target_mesh->getMeshDimension(); if(trgMeshDim!=srcMeshDim) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCC : dim of target cartesian should be equal to dim of source cartesian dimension !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : dim of target cartesian should be equal to dim of source cartesian dimension !"); switch(srcMeshDim) { case 1: @@ -581,7 +697,7 @@ int MEDCouplingRemapper::prepareCC(const char *method) throw(INTERP_KERNEL::Exce break; } default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCC : only dimension 1 2 or 3 supported !"); + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only dimension 1 2 or 3 supported !"); } nullifiedTinyCoeffInCrudeMatrixAbs(0.); // @@ -593,18 +709,162 @@ int MEDCouplingRemapper::prepareCC(const char *method) throw(INTERP_KERNEL::Exce return 1; } +int MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss() throw(INTERP_KERNEL::Exception) +{ + if(getIntersectionType()!=INTERP_KERNEL::PointLocator) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss : The intersection type is not supported ! Only PointLocator is supported for Gauss->Gauss interpolation ! Please invoke setIntersectionType(PointLocator) on the MEDCouplingRemapper instance !"); + MEDCouplingAutoRefCountObjectPtr trgLoc=_target_ft->getLocalizationOfDiscr(); + const double *trgLocPtr=trgLoc->begin(); + int trgSpaceDim=trgLoc->getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr srcOffsetArr=_src_ft->getDiscretization()->getOffsetArr(_src_ft->getMesh()); + if(trgSpaceDim!=_src_ft->getMesh()->getSpaceDimension()) + { + std::ostringstream oss; oss << "MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss : space dimensions mismatch between source and target !"; + oss << " Target discretization localization has dimension " << trgSpaceDim << ", whereas the space dimension of source is equal to "; + oss << _src_ft->getMesh()->getSpaceDimension() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const int *srcOffsetArrPtr=srcOffsetArr->begin(); + MEDCouplingAutoRefCountObjectPtr srcLoc=_src_ft->getLocalizationOfDiscr(); + const double *srcLocPtr=srcLoc->begin(); + std::vector elts,eltsIndex; + int trgNbOfGaussPts=trgLoc->getNumberOfTuples(); + _matrix.resize(trgNbOfGaussPts); + _src_ft->getMesh()->getCellsContainingPoints(trgLoc->begin(),trgNbOfGaussPts,getPrecision(),elts,eltsIndex); + MEDCouplingAutoRefCountObjectPtr eltsIndex2=DataArrayInt::New(); eltsIndex2->useArray(&eltsIndex[0],false,CPP_DEALLOC,(int)eltsIndex.size(),1); + MEDCouplingAutoRefCountObjectPtr nbOfSrcCellsShTrgPts=eltsIndex2->deltaShiftIndex(); + MEDCouplingAutoRefCountObjectPtr ids0=nbOfSrcCellsShTrgPts->getIdsNotEqual(0); + for(const int *trgId=ids0->begin();trgId!=ids0->end();trgId++) + { + const double *ptTrg=trgLocPtr+trgSpaceDim*(*trgId); + int srcCellId=elts[eltsIndex[*trgId]]; + double dist=std::numeric_limits::max(); + int srcEntry=-1; + for(int srcId=srcOffsetArrPtr[srcCellId];srcIdgetNumberOfTuples()!=trgNbOfGaussPts) + { + MEDCouplingAutoRefCountObjectPtr orphanTrgIds=nbOfSrcCellsShTrgPts->getIdsEqual(0); + MEDCouplingAutoRefCountObjectPtr orphanTrg=trgLoc->selectByTupleId(orphanTrgIds->begin(),orphanTrgIds->end()); + MEDCouplingAutoRefCountObjectPtr srcIdPerTrg=srcLoc->findClosestTupleId(orphanTrg); + const int *srcIdPerTrgPtr=srcIdPerTrg->begin(); + for(const int *orphanTrgId=orphanTrgIds->begin();orphanTrgId!=orphanTrgIds->end();orphanTrgId++,srcIdPerTrgPtr++) + _matrix[*orphanTrgId][*srcIdPerTrgPtr]=2.; + } + _deno_multiply.clear(); + _deno_multiply.resize(_matrix.size()); + _deno_reverse_multiply.clear(); + _deno_reverse_multiply.resize(srcLoc->getNumberOfTuples()); + declareAsNew(); + return 1; +} + +/*! + * This method checks that the input interpolation \a method is managed by not INTERP_KERNEL only methods. + * If no an INTERP_KERNEL::Exception will be thrown. If yes, a magic number will be returned to switch in the MEDCouplingRemapper::prepareNotInterpKernelOnly method. + */ +int MEDCouplingRemapper::CheckInterpolationMethodManageableByNotOnlyInterpKernel(const std::string& method) throw(INTERP_KERNEL::Exception) +{ + if(method=="GAUSSGAUSS") + return 0; + std::ostringstream oss; oss << "MEDCouplingRemapper::CheckInterpolationMethodManageableByNotOnlyInterpKernel : "; + oss << "The method \"" << method << "\" is not manageable by not INTERP_KERNEL only method."; + oss << " Not only INTERP_KERNEL methods dealed are : GAUSSGAUSS !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +/*! + * This method determines regarding \c _interp_matrix_pol attribute ( set by MEDCouplingRemapper::setInterpolationMatrixPolicy and by default equal + * to IK_ONLY_PREFERED = 0 ) , which method will be applied. If \c true is returned the INTERP_KERNEL only method should be applied to \c false the \b not + * only INTERP_KERNEL method should be applied. + */ +bool MEDCouplingRemapper::isInterpKernelOnlyOrNotOnly() const throw(INTERP_KERNEL::Exception) +{ + std::string srcm,trgm,method; + method=checkAndGiveInterpolationMethodStr(srcm,trgm); + switch(_interp_matrix_pol) + { + case IK_ONLY_PREFERED: + { + try + { + std::string tmp1,tmp2; + INTERP_KERNEL::Interpolation::CheckAndSplitInterpolationMethod(method.c_str(),tmp1,tmp2); + return true; + } + catch(INTERP_KERNEL::Exception& e) + { + return false; + } + } + case NOT_IK_ONLY_PREFERED: + { + try + { + CheckInterpolationMethodManageableByNotOnlyInterpKernel(method); + return false; + } + catch(INTERP_KERNEL::Exception& e) + { + return true; + } + } + case IK_ONLY_FORCED: + return true; + case NOT_IK_ONLY_FORCED: + return false; + default: + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::isInterpKernelOnlyOrNotOnly : internal error ! The interpolation matrix policy is not managed ! Try to change it using MEDCouplingRemapper::setInterpolationMatrixPolicy !"); + } +} + void MEDCouplingRemapper::updateTime() const { } +void MEDCouplingRemapper::checkPrepare() const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingFieldTemplate *s(_src_ft),*t(_target_ft); + if(!s || !t) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkPrepare : it appears that MEDCouplingRemapper::prepare(Ex) has not been called !"); + if(!s->getMesh() || !t->getMesh()) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkPrepare : it appears that no all field templates have their mesh set !"); +} + +/*! + * This method builds a code considering already set field discretization int \a this : \a _src_ft and \a _target_ft. + * This method returns 3 informations (2 in ouput parameters and 1 in return). + * + * \param [out] srcMeth the string code of the discretization of source field template + * \param [out] trgMeth the string code of the discretization of target field template + * \return the standardized string code (compatible with INTERP_KERNEL) for matrix of numerators (in \a _matrix) + */ +std::string MEDCouplingRemapper::checkAndGiveInterpolationMethodStr(std::string& srcMeth, std::string& trgMeth) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingFieldTemplate *s(_src_ft),*t(_target_ft); + if(!s || !t) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkAndGiveInterpolationMethodStr : it appears that no all field templates have been set !"); + if(!s->getMesh() || !t->getMesh()) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::checkAndGiveInterpolationMethodStr : it appears that no all field templates have their mesh set !"); + srcMeth=_src_ft->getDiscretization()->getRepr(); + trgMeth=_target_ft->getDiscretization()->getRepr(); + std::string method(srcMeth); method+=trgMeth; + return method; +} + void MEDCouplingRemapper::releaseData(bool matrixSuppression) { - if(_src_mesh) - _src_mesh->decrRef(); - if(_target_mesh) - _target_mesh->decrRef(); - _src_mesh=0; - _target_mesh=0; + _src_ft=0; + _target_ft=0; if(matrixSuppression) { _matrix.clear(); @@ -615,9 +875,10 @@ void MEDCouplingRemapper::releaseData(bool matrixSuppression) void MEDCouplingRemapper::transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue) throw(INTERP_KERNEL::Exception) { - if(_src_method!=srcField->getDiscretization()->getStringRepr()) + checkPrepare(); + if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - if(_target_method!=targetField->getDiscretization()->getStringRepr()) + if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); if(srcField->getNature()!=targetField->getNature()) throw INTERP_KERNEL::Exception("Natures of fields mismatch !"); diff --git a/src/MEDCoupling/MEDCouplingRemapper.hxx b/src/MEDCoupling/MEDCouplingRemapper.hxx index 41948c2fb..114a3f4e3 100644 --- a/src/MEDCoupling/MEDCouplingRemapper.hxx +++ b/src/MEDCoupling/MEDCouplingRemapper.hxx @@ -25,6 +25,8 @@ #include "MEDCouplingTimeLabel.hxx" #include "InterpolationOptions.hxx" #include "MEDCouplingNatureOfField.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + #include "InterpKernelException.hxx" #include @@ -33,13 +35,20 @@ namespace ParaMEDMEM { class MEDCouplingMesh; - class MEDCouplingUMesh; class MEDCouplingFieldDouble; class MEDCouplingFieldTemplate; } namespace ParaMEDMEM { + typedef enum + { + IK_ONLY_PREFERED = 0, + NOT_IK_ONLY_PREFERED = 1, + IK_ONLY_FORCED = 2, + NOT_IK_ONLY_FORCED =3 + } InterpolationMatrixPolicy; + class MEDCouplingRemapper : public TimeLabel, public INTERP_KERNEL::InterpolationOptions { public: @@ -55,6 +64,8 @@ namespace ParaMEDMEM MEDCOUPLINGREMAPPER_EXPORT bool setOptionInt(const std::string& key, int value); MEDCOUPLINGREMAPPER_EXPORT bool setOptionDouble(const std::string& key, double value); MEDCOUPLINGREMAPPER_EXPORT bool setOptionString(const std::string& key, const std::string& value); + MEDCOUPLINGREMAPPER_EXPORT int getInterpolationMatrixPolicy() const; + MEDCOUPLINGREMAPPER_EXPORT void setInterpolationMatrixPolicy(int newInterpMatPol) throw(INTERP_KERNEL::Exception); // MEDCOUPLINGREMAPPER_EXPORT int nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs) throw(INTERP_KERNEL::Exception); MEDCOUPLINGREMAPPER_EXPORT int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) throw(INTERP_KERNEL::Exception); @@ -63,12 +74,22 @@ namespace ParaMEDMEM MEDCOUPLINGREMAPPER_EXPORT const std::vector >& getCrudeMatrix() const; MEDCOUPLINGREMAPPER_EXPORT static void PrintMatrix(const std::vector >& m); private: - int prepareUU(const char *method) throw(INTERP_KERNEL::Exception); - int prepareEE(const char *method) throw(INTERP_KERNEL::Exception); - int prepareUC(const char *method) throw(INTERP_KERNEL::Exception); - int prepareCU(const char *method) throw(INTERP_KERNEL::Exception); - int prepareCC(const char *method) throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnly() throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnlyUU() throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnlyEE() throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnlyUC() throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnlyCU() throw(INTERP_KERNEL::Exception); + int prepareInterpKernelOnlyCC() throw(INTERP_KERNEL::Exception); + // + int prepareNotInterpKernelOnly() throw(INTERP_KERNEL::Exception); + int prepareNotInterpKernelOnlyGaussGauss() throw(INTERP_KERNEL::Exception); + // + static int CheckInterpolationMethodManageableByNotOnlyInterpKernel(const std::string& method) throw(INTERP_KERNEL::Exception); + // + bool isInterpKernelOnlyOrNotOnly() const throw(INTERP_KERNEL::Exception); void updateTime() const; + void checkPrepare() const throw(INTERP_KERNEL::Exception); + std::string checkAndGiveInterpolationMethodStr(std::string& srcMeth, std::string& trgMeth) const throw(INTERP_KERNEL::Exception); void releaseData(bool matrixSuppression); void transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue) throw(INTERP_KERNEL::Exception); void computeDeno(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField); @@ -86,10 +107,9 @@ namespace ParaMEDMEM static void ComputeColSumAndRowSum(const std::vector >& matrixDeno, std::vector >& deno, std::vector >& denoReverse); private: - MEDCouplingMesh *_src_mesh; - MEDCouplingMesh *_target_mesh; - std::string _src_method; - std::string _target_method; + MEDCouplingAutoRefCountObjectPtr _src_ft; + MEDCouplingAutoRefCountObjectPtr _target_ft; + InterpolationMatrixPolicy _interp_matrix_pol; NatureOfField _nature_of_deno; unsigned int _time_deno_update; std::vector > _matrix; diff --git a/src/MEDCoupling/MEDCouplingTimeLabel.cxx b/src/MEDCoupling/MEDCouplingTimeLabel.cxx index 9c2716c1e..166ca8fd9 100644 --- a/src/MEDCoupling/MEDCouplingTimeLabel.cxx +++ b/src/MEDCoupling/MEDCouplingTimeLabel.cxx @@ -48,3 +48,12 @@ void TimeLabel::updateTimeWith(const TimeLabel& other) const if(_time MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const throw(INTERP_KERNEL::Exception) { + if(!desc || !descIndx || !revDesc || !revDescIndx) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildDescendingConnectivityGen : present of a null pointer in input !"); checkConnectivityFullyDefined(); int nbOfCells=getNumberOfCells(); int nbOfNodes=getNumberOfNodes(); @@ -939,7 +952,7 @@ void MEDCouplingUMesh::convertAllToPoly() * When called 'this' is an invalid mesh on MED sense. This method will correct that for polyhedra. * In case of presence of polyhedron that has not the extruded aspect (2 faces with the same number of nodes) an exception is thrown and 'this' * remains unchanged. - * This method is usefull only for users that wants to build extruded unstructured mesh. + * This method is useful only for users that wants to build extruded unstructured mesh. * This method is a convenient one that avoids boring polyhedra setting during insertNextCell process. * In case of success, 'this' has be corrected contains the same number of cells and is valid in MED sense. */ @@ -2830,8 +2843,9 @@ void MEDCouplingUMesh::computeTypes() const int *conn=_nodal_connec->getConstPointer(); const int *connIndex=_nodal_connec_index->getConstPointer(); int nbOfElem=_nodal_connec_index->getNbOfElems()-1; - for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++) - _types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]); + if (nbOfElem > 0) + for(const int *pt=connIndex;pt !=connIndex+nbOfElem;pt++) + _types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]); } } @@ -3129,7 +3143,7 @@ DataArrayDouble *MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *be } /*! - * This methods returns a field on nodes and no time. This method is usefull to check "P1*" conservative interpolators. + * This methods returns a field on nodes and no time. This method is useful to check "P1*" conservative interpolators. * This field returns the getMeasureField of the dualMesh in P1 sens of 'this'. */ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) const @@ -4452,21 +4466,40 @@ DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic(int conversionType case 1: ret=convertLinearCellsToQuadratic1D0(conn,connI,coords,types); connSafe=conn; connISafe=connI; coordsSafe=coords; - break; + break; case 2: ret=convertLinearCellsToQuadratic2D0(conn,connI,coords,types); connSafe=conn; connISafe=connI; coordsSafe=coords; - break; + break; case 3: ret=convertLinearCellsToQuadratic3D0(conn,connI,coords,types); connSafe=conn; connISafe=connI; coordsSafe=coords; - break; + break; default: throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion of type 0 mesh dimensions available are [1,2,3] !"); } break; - //case 1: - //return convertLinearCellsToQuadratic1(); + case 1: + { + switch(meshDim) + { + case 1: + ret=convertLinearCellsToQuadratic1D0(conn,connI,coords,types);//it is not a bug. In 1D policy 0 and 1 are equals + connSafe=conn; connISafe=connI; coordsSafe=coords; + break; + case 2: + ret=convertLinearCellsToQuadratic2D1(conn,connI,coords,types); + connSafe=conn; connISafe=connI; coordsSafe=coords; + break; + case 3: + ret=convertLinearCellsToQuadratic3D1(conn,connI,coords,types); + connSafe=conn; connISafe=connI; coordsSafe=coords; + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion of type 1 mesh dimensions available are [1,2,3] !"); + } + break; + } default: throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion type available are 0 (default, the simplest) and 1 (the most complex) !"); } @@ -4501,7 +4534,7 @@ DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *& newConn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG3); newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[0]+3); newConn->pushBackSilent(offset++); - lastVal+=4; + lastVal+=4; newConnI->pushBackSilent(lastVal); ret->pushBackSilent(i); } @@ -4514,7 +4547,7 @@ DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *& } } MEDCouplingAutoRefCountObjectPtr tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); - conn=newConn.retn(); connI=newConnI.retn(); coords=DataArrayDouble::Aggregate(getCoords(),tmp); + coords=DataArrayDouble::Aggregate(getCoords(),tmp); conn=newConn.retn(); connI=newConnI.retn(); return ret.retn(); } @@ -4548,8 +4581,8 @@ DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDC newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); - lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0]); - newConnI->pushBackSilent(lastVal); + lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0]); + newConnI->pushBackSilent(lastVal); ret->pushBackSilent(i); } else @@ -4577,6 +4610,58 @@ DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *& return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types); } +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0; + // + MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); + // + MEDCouplingAutoRefCountObjectPtr bary=getBarycenterAndOwner(); + const int *descPtr(desc->begin()),*descIPtr(descI->begin()); + DataArrayInt *conn1D=0,*conn1DI=0; + std::set types1D; + DataArrayDouble *coordsTmp=0; + MEDCouplingAutoRefCountObjectPtr ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0; + MEDCouplingAutoRefCountObjectPtr coordsTmpSafe(coordsTmp); + MEDCouplingAutoRefCountObjectPtr conn1DSafe(conn1D),conn1DISafe(conn1DI); + const int *c1DPtr=conn1D->begin(); + const int *c1DIPtr=conn1DI->begin(); + int nbOfCells=getNumberOfCells(); + const int *cPtr=_nodal_connec->getConstPointer(); + const int *icPtr=_nodal_connec_index->getConstPointer(); + int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples(); + for(int i=0;ipushBackSilent(typ2); + newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); + for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) + newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); + newConn->pushBackSilent(offset+ret->getNumberOfTuples()); + lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+1; + newConnI->pushBackSilent(lastVal); + ret->pushBackSilent(i); + } + else + { + types.insert(typ); + lastVal+=(icPtr[1]-icPtr[0]); + newConnI->pushBackSilent(lastVal); + newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); + } + } + MEDCouplingAutoRefCountObjectPtr tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); + coords=DataArrayDouble::Aggregate(coordsTmpSafe,tmp); conn=newConn.retn(); connI=newConnI.retn(); + return ret.retn(); +} + /*! * Implementes \a conversionType 0 for meshes with meshDim = 3, of MEDCouplingUMesh::convertLinearCellsToQuadratic method. * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. @@ -4589,6 +4674,85 @@ DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *& return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types); } +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr desc2(DataArrayInt::New()),desc2I(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr m2D=buildDescendingConnectivityGen(desc2,desc2I,tmp2,tmp3,MEDCouplingFastNbrer); tmp2=0; tmp3=0; + MEDCouplingAutoRefCountObjectPtr desc1(DataArrayInt::New()),desc1I(DataArrayInt::New()),tmp4(DataArrayInt::New()),tmp5(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr m1D=explode3DMeshTo1D(desc1,desc1I,tmp4,tmp5); tmp4=0; tmp5=0; + // + MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(),ret2=DataArrayInt::New(); ret->alloc(0,1); ret2->alloc(0,1); + // + MEDCouplingAutoRefCountObjectPtr bary=getBarycenterAndOwner(); + const int *descPtr(desc1->begin()),*descIPtr(desc1I->begin()),*desc2Ptr(desc2->begin()),*desc2IPtr(desc2I->begin()); + DataArrayInt *conn1D=0,*conn1DI=0,*conn2D=0,*conn2DI=0; + std::set types1D,types2D; + DataArrayDouble *coordsTmp=0,*coordsTmp2=0; + MEDCouplingAutoRefCountObjectPtr ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=DataArrayInt::New(); ret1D->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr conn1DSafe(conn1D),conn1DISafe(conn1DI); + MEDCouplingAutoRefCountObjectPtr coordsTmpSafe(coordsTmp); + MEDCouplingAutoRefCountObjectPtr ret2D=m2D->convertLinearCellsToQuadratic2D1(conn2D,conn2DI,coordsTmp2,types2D); ret2D=DataArrayInt::New(); ret2D->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr coordsTmp2Safe(coordsTmp2); + MEDCouplingAutoRefCountObjectPtr conn2DSafe(conn2D),conn2DISafe(conn2DI); + const int *c1DPtr=conn1D->begin(),*c1DIPtr=conn1DI->begin(),*c2DPtr=conn2D->begin(),*c2DIPtr=conn2DI->begin(); + int nbOfCells=getNumberOfCells(); + const int *cPtr=_nodal_connec->getConstPointer(); + const int *icPtr=_nodal_connec_index->getConstPointer(); + int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples(); + for(int i=0;ipushBackSilent(typ2); + newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); + for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) + newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); + for(const int *d=desc2Ptr+desc2IPtr[0];d!=desc2Ptr+desc2IPtr[1];d++) + { + int nodeId2=c2DPtr[c2DIPtr[(*d)+1]-1]; + int tmpPos=newConn->getNumberOfTuples(); + newConn->pushBackSilent(nodeId2); + ret2D->pushBackSilent(nodeId2); ret1D->pushBackSilent(tmpPos); + } + newConn->pushBackSilent(offset+ret->getNumberOfTuples()); + lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+(desc2IPtr[1]-desc2IPtr[0])+1; + newConnI->pushBackSilent(lastVal); + ret->pushBackSilent(i); + } + else + { + types.insert(typ); + lastVal+=(icPtr[1]-icPtr[0]); + newConnI->pushBackSilent(lastVal); + newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); + } + } + MEDCouplingAutoRefCountObjectPtr diffRet2D=ret2D->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr o2nRet2D=diffRet2D->invertArrayN2O2O2N(coordsTmp2Safe->getNumberOfTuples()); + coordsTmp2Safe=coordsTmp2Safe->selectByTupleId(diffRet2D->begin(),diffRet2D->end()); + MEDCouplingAutoRefCountObjectPtr tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); + std::vector v(3); v[0]=coordsTmpSafe; v[1]=coordsTmp2Safe; v[2]=tmp; + int *c=newConn->getPointer(); + const int *cI(newConnI->begin()); + for(const int *elt=ret1D->begin();elt!=ret1D->end();elt++) + c[*elt]=o2nRet2D->getIJ(c[*elt],0)+offset; + offset=coordsTmp2Safe->getNumberOfTuples(); + for(const int *elt=ret->begin();elt!=ret->end();elt++) + c[cI[(*elt)+1]-1]+=offset; + coords=DataArrayDouble::Aggregate(v); conn=newConn.retn(); connI=newConnI.retn(); + return ret.retn(); +} + /*! * This method tessallates 'this' so that the number of cells remains the same. * This method works only for meshes with spaceDim equal to 2 and meshDim equal to 2. @@ -5038,7 +5202,7 @@ void MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeI * nodal connectivity will be transform to a NORM_TRI3 cell. * This method works \b only \b on \b linear cells. * This method works on nodes ids, that is to say a call to ParaMEDMEM::MEDCouplingUMesh::mergeNodes - * method could be usefull before calling this method in case of presence of several pair of nodes located on same position. + * method could be useful before calling this method in case of presence of several pair of nodes located on same position. * This method throws an exception if 'this' is not fully defined (connectivity). * This method throws an exception too if a "too" degenerated cell is detected. For example a NORM_TRI3 with 3 times the same node id. */ @@ -5824,7 +5988,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::emulateMEDMEMBDC(const MEDCouplingUMesh *nM1 /*! * This method sorts cell in this so that cells are sorted by cell type specified by MEDMEM and so for MED file. - * It avoids to deal with renum in MEDLoader so it is usefull for MED file R/W with multi types. + * It avoids to deal with renum in MEDLoader so it is useful for MED file R/W with multi types. * This method returns a newly allocated array old2New. * This method expects that connectivity of this is set. If not an exception will be thrown. Coordinates are not taken into account. */ @@ -5871,7 +6035,9 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const throw(INT /*! * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check - * that the order is specified in array defined by [orderBg,orderEnd). + * that the order is specified in array defined by [orderBg,orderEnd). + * If there is some geo types in \a this \b NOT in [ \a orderBg, \a orderEnd ) it is OK (return true) if contiguous. + * If there is some geo types in [ \a orderBg, \a orderEnd ) \b NOT in \a this it is OK too (return true) if contiguous. */ bool MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const { @@ -5879,15 +6045,32 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::No const int *conn=_nodal_connec->getConstPointer(); const int *connI=_nodal_connec_index->getConstPointer(); int nbOfCells=getNumberOfCells(); + if(nbOfCells==0) + return true; int lastPos=-1; + std::set sg; for(const int *i=connI;i!=connI+nbOfCells;) { INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - int pos=(int)std::distance(orderBg,std::find(orderBg,orderEnd,curType)); - if(pos<=lastPos) - return false; - lastPos=pos; - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); + const INTERP_KERNEL::NormalizedCellType *isTypeExists=std::find(orderBg,orderEnd,curType); + if(isTypeExists!=orderEnd) + { + int pos=(int)std::distance(orderBg,isTypeExists); + if(pos<=lastPos) + return false; + lastPos=pos; + i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); + } + else + { + if(sg.find(curType)==sg.end()) + { + i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); + sg.insert(curType); + } + else + return false; + } } return true; } @@ -6493,7 +6676,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector\n"; ofs << " \n"; ofs << " \n" << pointData << std::endl; @@ -7907,7 +8090,7 @@ void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, c * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 regarding arrIn[arrIndxIn[0]:arrIndxIn[0+1]]. * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step. * A negative value in \b arrIn means that it is ignored. - * This method is usefull to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1. + * This method is useful to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1. * * \param [in] arrIn arr origin array from which the extraction will be done. * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn @@ -7926,7 +8109,7 @@ DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *a * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 regarding arrIn[arrIndxIn[0]:arrIndxIn[0+1]]. * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step. * A negative value in \b arrIn means that it is ignored. - * This method is usefull to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1. + * This method is useful to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1. * \param [in] seedBg the begin pointer (included) of an array containing the seed of the search zone * \param [in] seedEnd the end pointer (not included) of an array containing the seed of the search zone * \param [in] arrIn arr origin array from which the extraction will be done. diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index 5ada04133..7a85e35b8 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -275,7 +275,9 @@ namespace ParaMEDMEM DataArrayInt *convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception); DataArrayInt *convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception); DataArrayInt *convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception); + DataArrayInt *convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception); DataArrayInt *convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception); + DataArrayInt *convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const throw(INTERP_KERNEL::Exception); template void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx index b3904a716..bd251da7d 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx @@ -2664,3 +2664,15 @@ void MEDCouplingBasicsTest1::testChangeSpaceDimension() m1->decrRef(); m2->decrRef(); } + +void MEDCouplingBasicsTest1::testSetConnectivity() +{ + MEDCouplingUMesh *m1 = build1DTargetMesh_1(); + + DataArrayInt * conn = DataArrayInt::New(); + DataArrayInt * connI = DataArrayInt::New(); + m1->setConnectivity(conn, connI, true); // was SEG-Faulting with empty arrays + conn->decrRef(); + connI->decrRef(); + m1->decrRef(); +} diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx index 9e0082458..c128f5f93 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx @@ -91,6 +91,7 @@ namespace ParaMEDMEM CPPUNIT_TEST( testFindNodeOnPlane ); CPPUNIT_TEST( testRenumberCells ); CPPUNIT_TEST( testChangeSpaceDimension ); + CPPUNIT_TEST( testSetConnectivity ); CPPUNIT_TEST_SUITE_END(); public: void testArray(); @@ -148,6 +149,7 @@ namespace ParaMEDMEM void testFindNodeOnPlane(); void testRenumberCells(); void testChangeSpaceDimension(); + void testSetConnectivity(); }; } diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx index cfc4f7ec6..f441cbffe 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx @@ -49,6 +49,7 @@ void MEDCouplingBasicsTest2::testGaussPointField1() // MEDCouplingUMesh *m=build2DTargetMesh_1(); MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME); + CPPUNIT_ASSERT_THROW(f->getNumberOfTuples(), INTERP_KERNEL::Exception); // Sanity check! f->setMesh(m); CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected()); CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); @@ -1093,7 +1094,7 @@ void MEDCouplingBasicsTest2::testGetMaxValue1() CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,f->getMaxValue(),1e-14); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,f->getAverageValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.125,f->getWeightedAverageValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.125,f->getWeightedAverageValue(0),1e-14); a1->setIJ(0,2,9.5); CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx index 230547686..8f89644c2 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx @@ -2190,11 +2190,12 @@ void MEDCouplingBasicsTest3::testGetDifferentValues1() const int arr[12]={1,2,3,2,2,3,5,1,5,5,2,2}; da1->alloc(4,3); std::copy(arr,arr+12,da1->getPointer()); - std::set s=da1->getDifferentValues(); + DataArrayInt *s=da1->getDifferentValues(); const int expected1[4]={1,2,3,5}; - CPPUNIT_ASSERT_EQUAL(4,(int)s.size()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+4,s.begin())); + CPPUNIT_ASSERT_EQUAL(4,s->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+4,s->begin())); da1->decrRef(); + s->decrRef(); } void MEDCouplingBasicsTest3::testDAIBuildPermutationArr1() diff --git a/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx b/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx index 635f91789..649fae28c 100644 --- a/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx +++ b/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx @@ -26,6 +26,157 @@ #include "MEDCouplingMemArray.hxx" #include "MEDCouplingMultiFields.hxx" +void CppExample_DataArrayInt_buildPermutationArr() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayInt_buildPermutationArr_1] + DataArrayInt *a=DataArrayInt::New(); + const int vala[5]={4,5,6,7,8}; + a->alloc(5,1); + std::copy(vala,vala+5,a->getPointer()); + DataArrayInt *b=DataArrayInt::New(); + const int valb[5]={5,4,8,6,7}; + b->alloc(5,1); + std::copy(valb,valb+5,b->getPointer()); + DataArrayInt *c=a->buildPermutationArr(*b); + //! [CppSnippet_DataArrayInt_buildPermutationArr_1] + const int expect1[5]={1,0,4,2,3}; + CPPUNIT_ASSERT_EQUAL(5,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,c->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expect1,expect1+5,c->getConstPointer())); + CPPUNIT_ASSERT(a->isEqualWithoutConsideringStrAndOrder(*b)); + a->decrRef(); + b->decrRef(); + c->decrRef(); +} + +void CppExample_DataArrayInt_invertArrayO2N2N2O() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayInt_invertArrayO2N2N2O_1] + const int arr1[6]={2,0,4,1,5,3}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(6,1); + std::copy(arr1,arr1+6,da->getPointer()); + DataArrayInt *da2=da->invertArrayO2N2N2O(6); + const int expected1[6]={1,3,0,5,2,4}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); + //! [CppSnippet_DataArrayInt_invertArrayO2N2N2O_1] + da->decrRef(); + da2->decrRef(); +} + +void CppExample_DataArrayInt_invertArrayN2O2O2N() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayInt_invertArrayN2O2O2N_1] + const int arr1[6]={2,0,4,1,5,3}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(6,1); + std::copy(arr1,arr1+6,da->getPointer()); + DataArrayInt *da2=da->invertArrayN2O2O2N(6); + const int expected1[6]={1,3,0,5,2,4}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); + //! [CppSnippet_DataArrayInt_invertArrayN2O2O2N_1] + da->decrRef(); + da2->decrRef(); +} + +void CppExample_DataArrayDouble_getIdsInRange() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayDouble_getIdsInRange_1] + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(10,1); + da->iota(); + + DataArrayInt* da2 = da->getIdsInRange( 2.5, 6 ); + //! [CppSnippet_DataArrayDouble_getIdsInRange_1] + da->decrRef(); + da2->decrRef(); +} + +void CppExample_DataArrayDouble_findCommonTuples() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayDouble_findCommonTuples1] + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(6,2); + const double array2[12]={2.3,2.3, // 0 + 1.2,1.2, // 1 + 1.3,1.3, // 2 + 2.3,2.3, // 3 + 2.301, // 4 + 2.301, // 5 + 0.8,0.8};// 6 + std::copy(array2,array2+12,da->getPointer()); + //! [CppSnippet_DataArrayDouble_findCommonTuples1] + //! [CppSnippet_DataArrayDouble_findCommonTuples2] + DataArrayInt *c=0,*cI=0; + da->findCommonTuples(1e-1,-1,c,cI); + + const int expected3[5]={0,3,4,1,2}; + const int expected4[3]={0,3,5}; + CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); + c->decrRef(); + cI->decrRef(); + da->decrRef(); + //! [CppSnippet_DataArrayDouble_findCommonTuples2] +} + +void CppExample_DataArrayDouble_Meld1() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayDouble_Meld1_1] + const int sameNbTuples = 7; + + DataArrayDouble *da1=DataArrayDouble::New(); + da1->alloc(sameNbTuples,2); + da1->fillWithValue(7.); + da1->setInfoOnComponent(0,"c0da1"); + da1->setInfoOnComponent(1,"c1da1"); + + DataArrayDouble *da2=DataArrayDouble::New(); + da2->alloc(sameNbTuples,1); + da2->iota(0.); + da2->setInfoOnComponent(0,"c0da2"); + + da1->meldWith(da2); + //! [CppSnippet_DataArrayDouble_Meld1_1] + //! [CppSnippet_DataArrayDouble_Meld1_2] + da1->decrRef(); + da2->decrRef(); + //! [CppSnippet_DataArrayDouble_Meld1_2] +} + +void CppExample_DataArrayInt_Meld1() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayInt_Meld1_1] + const int sameNbTuples = 7; + + DataArrayInt *da1=DataArrayInt::New(); + da1->alloc(sameNbTuples,2); + da1->fillWithValue(7); + da1->setInfoOnComponent(0,"c0da1"); + da1->setInfoOnComponent(1,"c1da1"); + + DataArrayInt *da2=DataArrayInt::New(); + da2->alloc(sameNbTuples,1); + da2->iota(0); + da2->setInfoOnComponent(0,"c0da2"); + + da1->meldWith(da2); + //! [CppSnippet_DataArrayInt_Meld1_1] + //! [CppSnippet_DataArrayInt_Meld1_2] + da1->decrRef(); + da2->decrRef(); + //! [CppSnippet_DataArrayInt_Meld1_2] +} + void CppExampleFieldDoubleBuildSubPart1() { //! [CppSnippetFieldDoubleBuildSubPart1_1] @@ -221,7 +372,7 @@ void CppSnippetDataArrayBuild1() myCoords->useArray(coords,false,ParaMEDMEM::CPP_DEALLOC,nbOfNodes,3); //now use myCoords as you need //... - //myCoords is no more usefully here : release it + //myCoords is no more useful here : release it myCoords->decrRef(); //! [CppSnippetDataArrayBuild1_1] //! [CppSnippetDataArrayBuild1_2] @@ -231,7 +382,7 @@ void CppSnippetDataArrayBuild1() myCoords->useArray(tmp,true,ParaMEDMEM::CPP_DEALLOC,nbOfNodes,3); //now use myCoords as you need //... - //myCoords is no more usefully, release it + //myCoords is no more useful, release it myCoords->decrRef(); //! [CppSnippetDataArrayBuild1_2] //! [CppSnippetDataArrayBuild1_3] @@ -241,7 +392,7 @@ void CppSnippetDataArrayBuild1() myCoords->useArray(tmp,true,ParaMEDMEM::C_DEALLOC,nbOfNodes,3); //now use myCoords as you need //... - //myCoords is no more usefully here : release it + //myCoords is no more useful here : release it myCoords->decrRef(); //! [CppSnippetDataArrayBuild1_3] //! [CppSnippetDataArrayBuild1_4] @@ -252,7 +403,7 @@ void CppSnippetDataArrayBuild1() myCoords->declareAsNew();//you have modified data pointed by internal pointer notify object //now use myCoords as you need //... - //myCoords is no more usefully here : release it + //myCoords is no more useful here : release it myCoords->decrRef(); //! [CppSnippetDataArrayBuild1_4] myCoords=ParaMEDMEM::DataArrayDouble::New(); @@ -304,6 +455,7 @@ void CppSnippetDataArrayBuild1() myCoordsCpy->decrRef(); //! [CppSnippetDataArrayBuild1_14] myCoords->decrRef(); + //! [CppSnippetDataArrayBuild1_14] } void CppSnippetFieldDoubleBuild1() @@ -326,7 +478,7 @@ void CppSnippetFieldDoubleBuild1() array->decrRef(); // fieldOnCells is now usable // ... - // fieldOnCells is no more usefully here : release it + // fieldOnCells is no more useful here : release it fieldOnCells->decrRef(); //! [CppSnippetFieldDoubleBuild1_1] arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); @@ -348,7 +500,7 @@ void CppSnippetFieldDoubleBuild1() //! [CppSnippetFieldDoubleBuild1_2] mesh->decrRef(); //! [CppSnippetFieldDoubleBuild1_3] - // f1, f2, f2bis, f3, f4, f5 are no more usefully here : release them + // f1, f2, f2bis, f3, f4, f5 are no more useful here : release them f1->decrRef(); f2->decrRef(); f2bis->decrRef(); @@ -378,7 +530,7 @@ void CppSnippetFieldDoubleBuild2() array->decrRef(); // fieldOnNodes is now usable // ... - // fieldOnNodes is no more usefully here : release it + // fieldOnNodes is no more useful here : release it fieldOnNodes->decrRef(); //! [CppSnippetFieldDoubleBuild2_1] } @@ -405,7 +557,7 @@ void CppSnippetFieldDoubleBuild3() array->decrRef(); // fieldOnCells is now usable // ... - // fieldOnCells is no more usefully here : release it + // fieldOnCells is no more useful here : release it fieldOnCells->decrRef(); //! [CppSnippetFieldDoubleBuild3_1] } @@ -433,13 +585,19 @@ void CppSnippetFieldDoubleBuild4() array->decrRef(); // fieldOnNodes is now usable // ... - // fieldOnNodes is no more usefully here : release it + // fieldOnNodes is no more useful here : release it fieldOnNodes->decrRef(); //! [CppSnippetFieldDoubleBuild4_1] } int main(int argc, char *argv[]) { + CppExample_DataArrayInt_buildPermutationArr(); + CppExample_DataArrayInt_invertArrayO2N2N2O(); + CppExample_DataArrayInt_invertArrayN2O2O2N(); + CppExample_DataArrayDouble_getIdsInRange(); + CppExample_DataArrayDouble_findCommonTuples(); + CppExample_DataArrayDouble_Meld1(); CppExampleFieldDoubleBuildSubPart1(); CppSnippetUMeshStdBuild1(); CppSnippetUMeshAdvBuild1(); diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 310f5cbe6..06111e164 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -2898,7 +2898,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertAlmostEqual(8.,f.getMaxValue(),14); self.assertAlmostEqual(0.,f.getMinValue(),14); self.assertAlmostEqual(5.,f.getAverageValue(),14); - self.assertAlmostEqual(5.125,f.getWeightedAverageValue(),14); + self.assertAlmostEqual(5.125,f.getWeightedAverageValue(0,True),14); a1.setIJ(0,2,9.5); self.assertAlmostEqual(9.5,f.getMaxValue(),14); self.assertAlmostEqual(0.,f.getMinValue(),14); @@ -5729,8 +5729,8 @@ class MEDCouplingBasicsTest(unittest.TestCase): arr=[1,2,3,2,2,3,5,1,5,5,2,2] da1.setValues(arr,4,3); s=da1.getDifferentValues(); - expected1=[1,2,3,5] - self.assertEqual(expected1,s); + expected1=DataArrayInt([1,2,3,5]) + self.assertTrue(expected1.isEqual(s)); pass def testSwigErrorProtection3(self): @@ -11310,6 +11310,141 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertTrue(a.getCoords().isEqual(DataArrayDouble([-0.3,-0.3,0.0,0.2,-0.3,0.0,0.7,-0.3,0.0,-0.3,0.2,0.0,0.2,0.2,0.0,0.7,0.2,0.0,-0.3,0.7,0.0,0.2,0.7,0.0,0.7,0.7,0.0,-0.3,-0.3,1.0,0.2,-0.3,1.0,0.7,-0.3,1.0,-0.3,0.2,1.0,0.2,0.2,1.0,0.7,0.2,1.0,-0.3,0.7,1.0,0.2,0.7,1.0,0.7,0.7,1.0,-0.3,-0.05,0.0,-0.05,0.2,0.0,0.2,-0.05,0.0,-0.05,-0.3,0.0,-0.3,-0.05,1.0,-0.05,0.2,1.0,0.2,-0.05,1.0,-0.05,-0.3,1.0,-0.3,-0.3,0.5,-0.3,0.2,0.5,0.2,0.2,0.5,0.2,-0.3,0.5,0.45,-0.05,0.0,0.45,-0.3,0.0,0.45,-0.05,1.0,0.45,-0.3,1.0,0.7,-0.3,0.5,0.45,0.2,0.0,0.7,-0.05,0.0,0.45,0.2,1.0,0.7,-0.05,1.0,0.7,0.2,0.5,-0.05,0.7,0.0,0.2,0.45,0.0,-0.3,0.45,0.0,-0.05,0.7,1.0,0.2,0.45,1.0,-0.3,0.45,1.0,-0.3,0.7,0.5,0.2,0.7,0.5,0.45,0.7,0.0,0.7,0.45,0.0,0.45,0.7,1.0,0.7,0.45,1.0,0.7,0.7,0.5],53,3),1e-14)) pass + def testSwig2DataArrayPushBackValsSilent1(self): + d=DataArrayDouble() + d.pushBackValsSilent([4,5,6]) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.]),1e-14)) + e=DataArrayDouble([1,2,3],1,3) + for t in e: d.pushBackValsSilent(t) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.]),1e-14)) + d.pushBackValsSilent(DataArrayDouble([9,10.])) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.]),1e-14)) + d.pushBackValsSilent(DataArrayDouble(0,1)) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.]),1e-14)) + e=DataArrayDouble([1,2,3],3,1) + for t in e: d.pushBackValsSilent(t) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.,1.,2.,3.]),1e-14)) + d.pushBackValsSilent(77) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.,1.,2.,3.,77.]),1e-14)) + # + d=DataArrayInt() + d.pushBackValsSilent([4,5,6]) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6]))) + e=DataArrayInt([1,2,3],1,3) + for t in e: d.pushBackValsSilent(t) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3]))) + d.pushBackValsSilent(DataArrayInt([9,10])) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10]))) + d.pushBackValsSilent(DataArrayInt(0,1)) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10]))) + e=DataArrayInt([1,2,3],3,1) + for t in e: d.pushBackValsSilent(t) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10,1,2,3]))) + d.pushBackValsSilent(77) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10,1,2,3,77]))) + pass + + def testSwig2ConvertLinearCellsToQuadratic2(self): + m2D=MEDCouplingDataForTest.build2DTargetMesh_1() + ret=m2D.convertLinearCellsToQuadratic(1) + self.assertTrue(ret.isIdentity()) + self.assertEqual(5,len(ret)) + m2D.checkCoherency1() + coordsExp=DataArrayDouble([-0.3,-0.3,0.2,-0.3,0.7,-0.3,-0.3,0.2,0.2,0.2,0.7,0.2,-0.3,0.7,0.2,0.7,0.7,0.7,-0.3,-0.05,-0.05,0.2,0.2,-0.05,-0.05,-0.3,0.45,-0.05,0.45,-0.3,0.45,0.2,0.7,-0.05,-0.05,0.7,0.2,0.45,-0.3,0.45,0.45,0.7,0.7,0.45,-0.05,-0.05,0.3666666666666667,-0.1333333333333333,0.5333333333333332,0.03333333333333334,-0.05,0.45,0.45,0.45],27,2) + self.assertTrue(m2D.getCoords().isEqual(coordsExp,1e-14)) + self.assertTrue(m2D.getNodalConnectivity().isEqual(DataArrayInt([9,0,3,4,1,9,10,11,12,22,7,1,4,2,11,13,14,23,7,4,5,2,15,16,13,24,9,6,7,4,3,17,18,10,19,25,9,7,8,5,4,20,21,15,18,26]))) + self.assertTrue(m2D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,10,18,26,36,46]))) + # + m2D=MEDCouplingDataForTest.build2DTargetMesh_1()[(0,3)] ; m2D.zipCoords() + m2D.changeSpaceDimension(3) + arr=DataArrayDouble(3); arr.iota(0) ; z=MEDCouplingCMesh() ; z.setCoords(arr) + m1D=z.buildUnstructured() ; m1D.setCoords(arr.changeNbOfComponents(3,0.)) + m1D.getCoords()[:]=m1D.getCoords()[:,[1,2,0]] + cooTmp=m2D.getCoords()[:] + m3D=m2D.buildExtrudedMesh(m1D,0) + ret=m3D.convertLinearCellsToQuadratic(1) + m3D.writeVTK("m3D.vtu") + self.assertTrue(ret.isIdentity()) + self.assertEqual(4,len(ret)) + m3D.checkCoherency1() + coordsExp2=DataArrayDouble([-0.3,-0.3,0.0,0.2,-0.3,0.0,-0.3,0.2,0.0,0.2,0.2,0.0,-0.3,0.7,0.0,0.2,0.7,0.0,-0.3,-0.3,1.0,0.2,-0.3,1.0,-0.3,0.2,1.0,0.2,0.2,1.0,-0.3,0.7,1.0,0.2,0.7,1.0,-0.3,-0.3,2.0,0.2,-0.3,2.0,-0.3,0.2,2.0,0.2,0.2,2.0,-0.3,0.7,2.0,0.2,0.7,2.0,-0.3,-0.05,0.0,-0.05,0.2,0.0,0.2,-0.05,0.0,-0.05,-0.3,0.0,-0.3,-0.05,1.0,-0.05,0.2,1.0,0.2,-0.05,1.0,-0.05,-0.3,1.0,-0.3,-0.3,0.5,-0.3,0.2,0.5,0.2,0.2,0.5,0.2,-0.3,0.5,-0.05,0.7,0.0,0.2,0.45,0.0,-0.3,0.45,0.0,-0.05,0.7,1.0,0.2,0.45,1.0,-0.3,0.45,1.0,-0.3,0.7,0.5,0.2,0.7,0.5,-0.3,-0.05,2.0,-0.05,0.2,2.0,0.2,-0.05,2.0,-0.05,-0.3,2.0,-0.3,-0.3,1.5,-0.3,0.2,1.5,0.2,0.2,1.5,0.2,-0.3,1.5,-0.05,0.7,2.0,0.2,0.45,2.0,-0.3,0.45,2.0,-0.3,0.7,1.5,0.2,0.7,1.5,-0.05,-0.05,0.0,-0.3,-0.05,0.5,-0.05,0.2,0.5,0.2,-0.05,0.5,-0.05,-0.05,1.0,-0.05,0.45,0.0,-0.05,0.7,0.5,0.2,0.45,0.5,-0.05,0.45,1.0,-0.3,-0.05,1.5,-0.05,0.2,1.5,0.2,-0.05,1.5,-0.05,-0.05,2.0,-0.05,0.7,1.5,0.2,0.45,1.5,-0.05,0.45,2.0,-0.05,-0.05,0.5,-0.05,0.45,0.5,-0.05,-0.05,1.5,-0.05,0.45,1.5],71,3) + self.assertTrue(m3D.getCoords().isEqual(coordsExp2,1e-14)) + self.assertTrue(m3D.getNodalConnectivity().isEqual(DataArrayInt([27,0,2,3,1,6,8,9,7,18,19,20,21,22,23,24,25,26,27,28,29,51,52,53,54,55,51,67,27,4,5,3,2,10,11,9,8,30,31,19,32,33,34,23,35,36,37,28,27,56,57,58,53,59,56,68,27,6,8,9,7,12,14,15,13,22,23,24,25,38,39,40,41,42,43,44,45,55,60,61,62,63,55,69,27,10,11,9,8,16,17,15,14,33,34,23,35,46,47,39,48,49,50,44,43,59,64,65,61,66,59,70]))) + self.assertTrue(m3D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,28,56,84,112]))) + pass + + def testSwig2GaussNEIntegral1(self): + m2D=MEDCouplingDataForTest.build2DTargetMesh_1() + m0=m2D[0] ; m0.zipCoords() + m1=m2D[[1,2]] ; m1.zipCoords() + m2=m2D[[3,4]] ; m2.zipCoords() + m0.convertLinearCellsToQuadratic(1) + m1.convertLinearCellsToQuadratic(0) + m2.convertLinearCellsToQuadratic(1) + m=MEDCouplingUMesh.MergeUMeshes([m0,m1,m2]) + m.mergeNodes(1e-12) + f=MEDCouplingFieldDouble(ON_GAUSS_NE) + f.setMesh(m) + arr=DataArrayDouble([1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9, + 11.1,12.2,13.3,14.4,15.5,16.6, + 21.1,22.2,23.3,24.4,25.5,26.6, + 31.1,32.2,33.3,34.4,35.5,36.6,37.7,38.8,39.9, + 41.1,42.2,43.3,44.4,45.5,46.6,47.7,48.8,49.9]) + arr2=DataArrayDouble(len(arr),2) + arr2[:,0]=arr ; arr2[:,1]=arr+100 + f.setArray(arr2) + f.checkCoherency() + res=f.integral(False) + # a=25./81 ; b=40./81 ; c=64./81 + # p1=0.11169079483905 ; p2=0.0549758718227661 + # 1st compo + # c0=(a*(1.1+2.2+3.3+4.4)+b*(5.5+6.6+7.7+8.8)+c*9.9)*0.25/3.9999999999999978 ; c0=1.5837962962962973 + # c1=(p2*(11.1+12.2+13.3)+p1*(14.4+15.5+16.6))*0.125/0.4999999999854482 ; c1=1.8014347172346943 + # c2=(p2*(21.1+22.2+23.3)+p1*(24.4+25.5+26.6))*0.125/0.4999999999854482 ; c2=3.0514347172346943 + # c3=(a*(31.1+32.2+33.3+34.4)+b*(35.5+36.6+37.7+38.8)+c*39.9)*0.25/3.9999999999999978 ; c3=9.0837962962963 + # c4=(a*(41.1+42.2+43.3+44.4)+b*(45.5+46.6+47.7+48.8)+c*49.9)*0.25/3.9999999999999978 ; c4=11.583796296296303 + # c0+c1+c2+c3+c4=27.104258323358287 + integExp0=27.104258323358287 + self.assertAlmostEqual(res[0],integExp0,13) + # 2nd compo + # c0=(a*(101.1+102.2+103.3+104.4)+b*(105.5+106.6+107.7+108.8)+c*109.9)*0.25/3.9999999999999978 ; c0=26.58379629629631 + # c1=(p2*(111.1+112.2+113.3)+p1*(114.4+115.5+116.6))*0.125/0.4999999999854482 ; c1=14.301434717234699 + # c2=(p2*(121.1+122.2+123.3)+p1*(124.4+125.5+126.6))*0.125/0.4999999999854482 ; c2=15.5514347172347 + # c3=(a*(131.1+132.2+133.3+134.4)+b*(135.5+136.6+137.7+138.8)+c*139.9)*0.25/3.9999999999999978 ; c3=34.08379629629631 + # c4=(a*(141.1+142.2+143.3+144.4)+b*(145.5+146.6+147.7+148.8)+c*149.9)*0.25/3.9999999999999978 ; c4=36.58379629629632 + # c0+c1+c2+c3+c4=127.10425832335835 + integExp1=127.10425832335835 + self.assertAlmostEqual(res[1],integExp1,12) + meas=f.getDiscretization().getMeasureField(f.getMesh(),False) + intPerTuple=meas*f + res2=intPerTuple.accumulate() + self.assertAlmostEqual(res2[0],integExp0,13) + self.assertAlmostEqual(res2[1],integExp1,12) + # + meas2=f.buildMeasureField(False) + intPerTuple=meas2*f + res3=intPerTuple.accumulate() + self.assertAlmostEqual(res3[0],integExp0,13) + self.assertAlmostEqual(res3[1],integExp1,12) + # + res4=f.getWeightedAverageValue(False) # res4==res2 because sum of area of mesh is equal to 1 + self.assertAlmostEqual(res4[0],integExp0,13) + self.assertAlmostEqual(res4[1],integExp1,12) + # + m.scale([0,0],2.) + # + res5=f.getWeightedAverageValue() # res4==res4 because weighted average is not sensitive to the scaling + self.assertAlmostEqual(res5[0],integExp0,13) + self.assertAlmostEqual(res5[1],integExp1,12) + meas3=f.buildMeasureField(False) + delta=4*meas2.getArray()-meas3.getArray() + delta.abs() + self.assertTrue(delta.isUniform(0.,1e-16)) + res6=f.integral(False) + self.assertAlmostEqual(res6[0],4.*integExp0,12) + self.assertAlmostEqual(res6[1],4.*integExp1,11) + pass + def setUp(self): pass pass diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index 179790356..933b2f829 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -86,6 +86,12 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getOffsetArr; %newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clone; %newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clonePart; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getMeasureField; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getOffsetArr; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getLocalizationOfDiscValues; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getValueOnMulti; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::computeTupleIdsToSelectFromCellIds; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::buildSubMeshData; %newobject ParaMEDMEM::MEDCouplingField::buildMeasureField; %newobject ParaMEDMEM::MEDCouplingField::getLocalizationOfDiscr; %newobject ParaMEDMEM::MEDCouplingField::computeTupleIdsToSelectFromCellIds; @@ -180,6 +186,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayInt::duplicateEachTupleNTimes; %newobject ParaMEDMEM::DataArrayInt::buildPermutationArr; %newobject ParaMEDMEM::DataArrayInt::buildPermArrPerLevel; +%newobject ParaMEDMEM::DataArrayInt::getDifferentValues; %newobject ParaMEDMEM::DataArrayInt::__neg__; %newobject ParaMEDMEM::DataArrayInt::__add__; %newobject ParaMEDMEM::DataArrayInt::__radd__; @@ -238,6 +245,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::DataArrayDouble::fromCylToCart; %newobject ParaMEDMEM::DataArrayDouble::fromSpherToCart; %newobject ParaMEDMEM::DataArrayDouble::getDifferentValues; +%newobject ParaMEDMEM::DataArrayDouble::findClosestTupleId; %newobject ParaMEDMEM::DataArrayDouble::duplicateEachTupleNTimes; %newobject ParaMEDMEM::DataArrayDouble::__neg__; %newobject ParaMEDMEM::DataArrayDouble::__add__; @@ -903,10 +911,12 @@ namespace ParaMEDMEM %extend ParaMEDMEM::DataArrayInt { - PyObject *getDifferentValues() const throw(INTERP_KERNEL::Exception) + void pushBackValsSilent(PyObject *li) throw(INTERP_KERNEL::Exception) { - std::set ret=self->getDifferentValues(); - return convertIntArrToPyList3(ret); + int szArr,sw,iTypppArr; + std::vector stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->pushBackValsSilent(tmp,tmp+szArr); } PyObject *partitionByDifferentValues() const throw(INTERP_KERNEL::Exception) @@ -951,7 +961,6 @@ namespace ParaMEDMEM } %ignore ParaMEDMEM::DataArray::getInfoOnComponents; -%ignore ParaMEDMEM::DataArrayInt::getDifferentValues; %ignore ParaMEDMEM::DataArrayInt::partitionByDifferentValues; %ignore ParaMEDMEM::MEDCouplingFieldDiscretizationPerCell::getArrayOfDiscIds; %ignore ParaMEDMEM::MEDCouplingFieldDiscretization::clonePart; @@ -960,8 +969,8 @@ namespace ParaMEDMEM %include "NormalizedUnstructuredMesh.hxx" %include "MEDCouplingNatureOfField.hxx" %include "MEDCouplingTimeDiscretization.hxx" -%include "MEDCouplingFieldDiscretization.hxx" %include "MEDCouplingGaussLocalization.hxx" +%include "MEDCouplingFieldDiscretization.hxx" namespace ParaMEDMEM { @@ -2954,6 +2963,16 @@ namespace ParaMEDMEM return ParaMEDMEM_DataArrayDouble_New__SWIG_1(elt0,nbOfTuples,elt2); } + void pushBackValsSilent(PyObject *li) throw(INTERP_KERNEL::Exception) + { + double val; + std::vector bb; + int sw,nbTuples=-1; + const char msg[]="Python wrap of DataArrayDouble::pushBackValsSilent : "; + const double *tmp=convertObjToPossibleCpp5_SingleCompo(li,sw,val,bb,msg,true,nbTuples); + self->pushBackValsSilent(tmp,tmp+nbTuples); + } + std::string __str__() const { return self->repr(); @@ -3238,6 +3257,17 @@ namespace ParaMEDMEM } } + PyObject *minimalDistanceTo(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception) + { + int thisTupleId,otherTupleId; + double r0=self->minimalDistanceTo(other,thisTupleId,otherTupleId); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r0)); + PyTuple_SetItem(ret,1,PyInt_FromLong(thisTupleId)); + PyTuple_SetItem(ret,2,PyInt_FromLong(otherTupleId)); + return ret; + } + PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) { int tmp; @@ -6494,7 +6524,7 @@ namespace ParaMEDMEM { public: static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); - static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=ONE_TIME); + static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); void setTimeUnit(const char *unit); const char *getTimeUnit() const; void synchronizeTimeWithSupport() throw(INTERP_KERNEL::Exception); @@ -6564,7 +6594,8 @@ namespace ParaMEDMEM double getAverageValue() const throw(INTERP_KERNEL::Exception); double norm2() const throw(INTERP_KERNEL::Exception); double normMax() const throw(INTERP_KERNEL::Exception); - double getWeightedAverageValue() const throw(INTERP_KERNEL::Exception); + //do not put a default value to isWAbs because confusion in python with overloaded getWeightedAverageValue method + double getWeightedAverageValue(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); double integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); double normL1(int compId) const throw(INTERP_KERNEL::Exception); double normL2(int compId) const throw(INTERP_KERNEL::Exception); @@ -6593,7 +6624,7 @@ namespace ParaMEDMEM return MEDCouplingFieldDouble::New(type,td); } - MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td=ONE_TIME) + MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME) { return MEDCouplingFieldDouble::New(ft,td); } @@ -6786,32 +6817,35 @@ namespace ParaMEDMEM int sz=self->getNumberOfComponents(); INTERP_KERNEL::AutoPtr tmp=new double[sz]; self->accumulate(tmp); - PyObject *ret=convertDblArrToPyList(tmp,sz); - return ret; + return convertDblArrToPyList(tmp,sz); } PyObject *integral(bool isWAbs) const throw(INTERP_KERNEL::Exception) { int sz=self->getNumberOfComponents(); INTERP_KERNEL::AutoPtr tmp=new double[sz]; self->integral(isWAbs,tmp); - PyObject *ret=convertDblArrToPyList(tmp,sz); - return ret; + return convertDblArrToPyList(tmp,sz); + } + PyObject *getWeightedAverageValue(bool isWAbs=true) const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr tmp=new double[sz]; + self->getWeightedAverageValue(tmp,isWAbs); + return convertDblArrToPyList(tmp,sz); } PyObject *normL1() const throw(INTERP_KERNEL::Exception) { int sz=self->getNumberOfComponents(); INTERP_KERNEL::AutoPtr tmp=new double[sz]; self->normL1(tmp); - PyObject *ret=convertDblArrToPyList(tmp,sz); - return ret; + return convertDblArrToPyList(tmp,sz); } PyObject *normL2() const throw(INTERP_KERNEL::Exception) { int sz=self->getNumberOfComponents(); INTERP_KERNEL::AutoPtr tmp=new double[sz]; self->normL2(tmp); - PyObject *ret=convertDblArrToPyList(tmp,sz); - return ret; + return convertDblArrToPyList(tmp,sz); } void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) { @@ -7014,14 +7048,14 @@ namespace ParaMEDMEM class MEDCouplingFieldTemplate : public ParaMEDMEM::MEDCouplingField { public: - static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception); static MEDCouplingFieldTemplate *New(TypeOfField type); std::string simpleRepr() const throw(INTERP_KERNEL::Exception); std::string advancedRepr() const throw(INTERP_KERNEL::Exception); void updateTime() const; %extend { - MEDCouplingFieldTemplate(const MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception) + MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception) { return MEDCouplingFieldTemplate::New(f); } diff --git a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py index bb865d3cb..af3fb6f09 100644 --- a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py @@ -576,6 +576,54 @@ class MEDCouplingDataForTest: mesh2.insertNextCell(NORM_QUAD4,4,conn2[16:20]) mesh2.finishInsertingCells(); return [mesh,mesh2] + + def buildFieldOnGauss_1(self): + coo=DataArrayDouble([1.0,0.0,1.33333333333333,0.0,1.66666666666667,0.0,0.923879532511287,0.38268343236509006,1.23183937668172,0.510244576486786,1.53979922085214,0.6378057206084831,2.0,0.0,1.8477590650225701,0.7653668647301801,0.9428090415820631,0.9428090415820631,1.1785113019775801,1.1785113019775801,1.4142135623731,1.41421356237309,0.707106781186548,0.707106781186547,0.38268343236509006,0.923879532511287,0.510244576486786,1.23183937668172,0.6378057206084831,1.53979922085214,0.7653668647301801,1.8477590650225701,3.1550283219328204e-17,1.33333333333333,1.16009632455949e-17,1.66666666666667,-2.7620050344068196e-16,2.0,-1.3810025172034098e-16,1.0,-2.0,0.0,-1.53979922085214,0.6378057206084831,-1.66666666666667,0.0,-1.33333333333333,0.0,-0.923879532511287,0.38268343236509006,-1.8477590650225701,0.7653668647301801,-0.9428090415820631,0.9428090415820631,-1.23183937668172,0.510244576486786,-1.83333333333333,0.0,-1.6937791429373599,0.701586292669331,-1.5,0.0,-1.30771370720431,0.26012042935483803,-1.16666666666667,0.0,-1.0778594545965,0.44646400442593803,-1.38578268717091,0.9259503883660041,-1.38581929876693,0.574025148547635,-1.06066017177982,1.06066017177982,-0.8314696123025451,0.5555702330196021,-1.0,0.0,-1.1785113019775801,1.1785113019775801,-0.707106781186548,0.707106781186547,-1.63464213400538,0.325150536693547,-1.9615705608064598,0.390180644032256,-1.47117792060485,0.292635483024192,-0.9807852804032301,0.19509032201612803,-1.524360955888,1.0185454272026,-1.2963624321753402,1.2963624321753402,-1.10862614973673,0.740760310692803,-0.970047881019636,0.6481652718562021,-0.824957911384305,0.824957911384305,-1.4142135623731,1.41421356237309,-1.7981063474059198,0.357665590362902,-1.1442494938037702,0.227605375685483,-1.66293922460509,1.1111404660392,-1.24720441845382,0.833355349529403,-0.7653668647301801,1.8477590650225701,-0.6378057206084831,1.53979922085214,-0.510244576486786,1.23183937668172,-0.701586292669331,1.6937791429373599,-0.574025148547635,1.38581929876693,-0.44646400442593803,1.0778594545965,-0.38268343236509006,0.923879532511287,-0.9259503883660041,1.38578268717091,-0.740760310692803,1.10862614973673,-0.5555702330196021,0.8314696123025451,-0.325150536693547,1.63464213400538,-0.26012042935483803,1.30771370720431,-0.19509032201612803,0.9807852804032301,1.6805133673525298e-18,1.83333333333333,-2.4643915380595496e-16,1.5,-1.4799359654427099e-16,1.16666666666667,-1.1111404660392,1.66293922460509,-0.39018064403225705,1.9615705608064598],73,2) + coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]"]) + m=MEDCouplingUMesh("MA1",2) + m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) + m.setCoords(coo) + m.allocateCells(0) + conn=[[0,1,4,3],[1,2,5,4],[2,6,7,5],[3,4,8,11],[4,5,9,8],[5,7,10,9],[20,22,21,28,41,51],[21,25,20,29,42,51],[22,23,21,30,43,41],[23,27,21,31,35,43],[23,38,24,32,44,52],[24,27,23,33,31,52],[25,21,50,29,45,53],[21,39,50,34,46,45],[21,27,26,35,47,54],[26,39,21,36,34,54],[27,24,26,33,48,47],[24,40,26,37,49,48],[50,39,56,55,46,62,58,71],[39,26,57,56,36,63,59,62],[26,40,61,57,49,64,60,63],[55,56,17,18,58,65,68,72],[56,57,16,17,59,66,69,65],[57,61,19,16,60,67,70,66]] + for i in xrange(0,6): + m.insertNextCell(NORM_QUAD4,conn[i]) + pass + for i in xrange(6,18): + m.insertNextCell(NORM_TRI6,conn[i]) + pass + for i in xrange(18,24): + m.insertNextCell(NORM_QUAD8,conn[i]) + pass + fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH13") ; fff.setNature(ConservativeVolumic) + fff.setMesh(m) + fff.setGaussLocalizationOnCells(range(0,6),[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626],[1.,1.,1.,1.]) + fff.setGaussLocalizationOnCells(range(6,18),[0.,0.,1.,0.,0.,1.,0.5, 0.,0.5, 0.5, 0.,0.5],[0.16666666666666666,0.16666666666666666,0.6666666666666666,0.16666666666666666,0.16666666666666666,0.6666666666666666],[0.16666666666666666,0.16666666666666666,0.16666666666666666]) + fff.setGaussLocalizationOnCells(range(18,24),[-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.],[-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,-0.774596669241483,0.0,0.0,0.0],[0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234]) + return fff + + def buildFieldOnGauss_2(self): + coo=DataArrayDouble([1.0,0.0,1.24068268955165,0.15233667925643402,1.25,0.0,1.5,0.0,1.73695576537231,0.21327135095900804,1.75,0.0,2.0,0.0,0.9925461516413221,0.12186934340514702,1.212869657845,0.302402369499585,1.48881922746198,0.182804015107721,1.6980175209829897,0.423363317299419,1.9850923032826397,0.243738686810295,0.9702957262759959,0.241921895599668,1.1669755331215,0.447959936931625,1.4554435894139899,0.362882843399502,1.6337657463701,0.627143911704275,1.94059145255199,0.483843791199335,0.9335804264972021,0.35836794954530005,1.10368449107366,0.586839453482364,1.4003706397458,0.5375519243179501,1.5451582875031202,0.8215752348753091,1.8671608529944002,0.716735899090601,0.882947592858927,0.46947156278589103,1.02394005536124,0.716970545438808,1.32442138928839,0.704207344178836,1.43351607750574,1.00375876361433,1.76589518571785,0.9389431255717821,1.125,0.0,1.11661442059649,0.137103011330791,1.375,0.0,1.4972021976328,0.09157280930228531,1.625,0.0,1.61288749641715,0.198037683033365,1.875,0.0,1.9962695968437298,0.12209707906971401,1.0915826920605,0.272162132549626,1.36475095850682,0.167570347182078,1.47488236134593,0.27335328823822097,1.5767305551984903,0.39312308034946003,1.8610240343274802,0.228505018884652,1.96650981512791,0.364471050984295,1.05027797980935,0.403163943238463,1.3341566236295,0.332642606449543,1.43057542612234,0.45105869925641007,1.5170681930579497,0.5823479180111131,1.8193044867674901,0.45360355424937704,1.9074339014964499,0.601411599008546,0.993316041966293,0.528155508134127,1.28367308643365,0.492755930624788,1.36494190631481,0.6220398639843591,1.43478983839576,0.7628912895270731,1.7504632996822498,0.671939905397438,1.81992254175309,0.8293864853124782,0.921546049825116,0.645273490894927,1.21405294018102,0.6455233988306001,1.27896024653114,0.783747847073923,1.33112207196961,0.93206170907045,1.65552673661049,0.8802591802235451,1.70528032870818,1.0449971294319,0.8191520442889921,0.5735764363510459,1.22872806643349,0.8603646545265691,1.6383040885779798,1.14715287270209,1.24766849802733,0.0763106744185711,0.9981347984218671,0.0610485395348569,1.37243534783007,0.0839417418604282,1.74673589723827,0.106834944186,1.871502747041,0.114466011627857,1.22906863445494,0.227794406865184,0.9832549075639551,0.18223552549214703,1.3519754979004401,0.25057384755170303,1.7206960882369198,0.318912169611258,1.84360295168241,0.341691610297777,1.19214618843528,0.37588224938034104,0.953716950748227,0.300705799504273,1.31136080727881,0.413470474318376,1.6690046638094,0.526235149132478,1.7882192826529297,0.563823374070512,1.13745158859568,0.518366553320299,0.9099612708765431,0.4146932426562391,1.25119674745525,0.570203208652329,1.5924322240339497,0.725713174648418,1.7061773828935198,0.777549829980448,1.06580020544262,0.6531232058949361,0.8526401643540921,0.522498564715949,1.17238022598688,0.7184355264844301,1.12633406089736,0.7886675999826881,1.49212028761966,0.91437248825291,1.59870030816392,0.979684808842404,1.53591008304186,1.07545581815821,1.1229016482246,0.068679606976714,1.6219690474355302,0.0992038767441424,1.10616177100945,0.205014966178666,1.59778922479143,0.29613272892474,1.07293156959176,0.338294024442307,1.5497900449658701,0.488646924194444,1.02370642973611,0.466529897988269,1.47868706517438,0.673876519316388,0.9592201848983541,0.587810885305442,1.3855402670754,0.8490601676634171,0.743144825477394,0.669130606358858,0.9289310318467431,0.836413257948573,1.11471723821609,1.00369590953829,1.30050344458544,1.170978561128,0.656059028990507,0.7547095802227721,0.820073786238134,0.943386975278465,0.984088543485761,1.13206437033416,1.14810330073339,1.32074176538985,0.559192903470747,0.8290375725550421,0.6989911293384331,1.0362969656938,0.8387893552061201,1.24355635883256,0.978587581073807,1.45081575197132,0.453990499739547,0.8910065241883681,0.567488124674433,1.11375815523546,0.6809857496093201,1.3365097862825501,0.794483374544207,1.55926141732964,0.8360379286620679,0.7527719321537151,1.0218241350314199,0.92005458374343,1.20761034140077,1.08733723533314,1.39339654777011,1.25461988692286,0.7380664076143211,0.8490482777506181,0.902081164861948,1.03772567280631,1.06609592210957,1.226403067862,1.2301106793572,1.4150804629177,0.6290920164045901,0.932667269124422,0.7688902422722771,1.13992666226318,0.9086884681399641,1.34718605540194,1.04848669400765,1.5544454485407,0.51073931220699,1.00238233971191,0.624236937141877,1.22513397075901,0.737734562076764,1.4478856018061,0.85123218701165,1.6706372328531902,1.48628965095479,1.33826121271772,1.31211805798101,1.5094191604455398,1.11838580694149,1.6580751451100801,0.907980999479094,1.7820130483767398,0.978260196065517,0.778143295797024,1.17391223527862,0.9337719549564292,1.36956427449172,1.08940061411583,1.56521631370483,1.24502927327524,0.876136580374814,0.891563061442727,1.05136389644978,1.06987567373127,1.22659121252474,1.2481882860198201,1.4018185285997,1.42650089830836,0.7609517862609011,0.991691675364044,0.913142143513081,1.19003001043685,1.06533250076526,1.38836834550966,1.21752285801744,1.5867066805824699,0.6344229537008801,1.07703645055191,0.7613075444410561,1.29244374066229,0.8881921351812321,1.50785103077267,1.01507672592141,1.7232583208830499,0.498436336156558,1.1463250929814,0.5981236033878691,1.37559011157769,0.697810870619181,1.60485513017397,0.7974981378504931,1.8341201487702499,0.42752517915708604,1.17461577598239,0.513030214988503,1.4095389311788602,0.59853525081992,1.6444620863753399,0.6840402866513371,1.87938524157182,0.38477266124137705,1.05715419838415,0.470277697072795,1.29207735358062,0.5557827329042121,1.5270005087771,0.6412877687356291,1.76192366397358,0.34202014332566905,0.9396926207859091,0.782608156852414,0.6225146366376201,0.7009092642998511,0.713250449154182,0.608761429008721,0.7933533402912349,0.507538362960704,0.861629160441526,0.398749068925246,0.917060074385124,-2.0,0.0,-1.75,0.0,-1.5,0.0,-1.25,0.0,-1.9632543668953297,0.38161799075309005,-1.71784757103341,0.333915741908953,-1.4724407751715,0.286213493064817,-1.22703397930958,0.23851124422068104,-1.85436770913357,0.749213186831824,-1.62257174549188,0.655561538477846,-1.39077578185018,0.561909890123868,-1.15897981820848,0.46825824176988995,-1.6773411358908499,1.08927807003005,-1.4676734939044902,0.953118311276297,-1.25800585191814,0.816958552522541,-1.04833820993178,0.680798793768784,-1.4386796006773,1.38931674091799,-1.25884465059264,1.21565214830325,-1.07900970050798,1.0419875556885,-0.8991747504233141,0.868322963073747,-1.0,0.0,-0.981627183447664,0.19080899537654503,-0.9271838545667871,0.374606593415912,-0.838670567945424,0.544639035015027,-0.7193398003386511,0.694658370458997,-1.00375876361433,1.43351607750574,-0.8603646545265691,1.22872806643349,-0.716970545438808,1.02394005536124,-0.5735764363510459,0.8191520442889921,-1.14715287270209,1.6383040885779798,-0.8134732861516011,1.8270909152852002,-0.71178912538265,1.59870455087455,-0.6101049646137,1.3703181864639,-0.50842080384475,1.14193182205325,-0.4067366430758,0.9135454576426011,-0.44990210868773,1.9487401295704703,-0.39366434510176407,1.70514761337416,-0.337426581515798,1.4615550971778501,-0.281188817929831,1.21796258098154,-0.224951054343865,0.974370064785235,-0.06979899340500181,1.9987816540381902,-0.0610741192293767,1.74893394728342,-0.0523492450537515,1.49908624052864,-0.0436243708781263,1.24923853377387,-0.03489949670250091,0.9993908270190961,0.312868930080462,1.97537668119028,0.27376031382040406,1.72845459604149,0.23465169756034704,1.48153251089271,0.19554308130028902,1.23461042574392,0.156434465040231,0.9876883405951381],219,2) + coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]"]) + m=MEDCouplingUMesh("MA2",2) + m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) + m.setCoords(coo) + m.allocateCells(0) + conn=[[169,170,174,173],[170,171,175,174],[171,172,176,175],[172,189,190,176],[173,174,178,177],[174,175,179,178],[175,176,180,179],[176,190,191,180],[177,178,182,181],[178,179,183,182],[179,180,184,183],[180,191,192,184],[181,182,186,185],[182,183,187,186],[183,184,188,187],[184,192,193,188],[185,186,194,198],[186,187,195,194],[187,188,196,195],[188,193,197,196],[0,2,1,27,62,89],[1,7,0,28,63,89],[2,3,1,29,64,62],[3,9,1,30,36,64],[3,5,4,31,65,90],[4,9,3,32,30,90],[5,6,4,33,66,65],[6,11,4,34,39,66],[7,1,8,28,67,91],[8,12,7,35,68,91],[1,9,8,36,69,67],[9,14,8,37,42,69],[9,4,10,32,70,92],[10,14,9,38,37,92],[4,11,10,39,71,70],[11,16,10,40,45,71],[12,8,13,35,72,93],[13,17,12,41,73,93],[8,14,13,42,74,72],[14,19,13,43,48,74],[14,10,15,38,75,94],[15,19,14,44,43,94],[10,16,15,45,76,75],[16,21,15,46,51,76],[17,13,18,41,77,95],[18,22,17,47,78,95],[13,19,18,48,79,77],[19,24,18,49,54,79],[19,15,20,44,80,96],[20,24,19,50,49,96],[15,21,20,51,81,80],[21,26,20,52,57,81],[22,18,23,47,82,97],[23,59,22,53,83,97],[18,24,23,54,84,82],[24,60,23,55,85,84],[24,20,25,50,86,98],[25,60,24,56,55,98],[20,26,25,57,87,86],[26,61,25,58,88,87],[59,23,100,99,53,135,115,164],[23,60,101,100,85,136,116,135],[60,25,102,101,56,137,117,136],[25,61,131,102,88,138,118,137],[99,100,104,103,115,139,119,165],[100,101,105,104,116,140,120,139],[101,102,106,105,117,141,121,140],[102,131,132,106,118,142,122,141],[103,104,108,107,119,143,123,166],[104,105,109,108,120,144,124,143],[105,106,110,109,121,145,125,144],[106,132,133,110,122,146,126,145],[107,108,112,111,123,147,127,167],[108,109,113,112,124,148,128,147],[109,110,114,113,125,149,129,148],[110,133,134,114,126,150,130,149],[111,112,155,163,127,151,159,168],[112,113,156,155,128,152,160,151],[113,114,157,156,129,153,161,152],[114,134,158,157,130,154,162,153]] + for i in xrange(0,20): + m.insertNextCell(NORM_QUAD4,conn[i]) + pass + for i in xrange(20,60): + m.insertNextCell(NORM_TRI6,conn[i]) + pass + for i in xrange(60,80): + m.insertNextCell(NORM_QUAD8,conn[i]) + pass + fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH23") ; fff.setNature(NoNature) + fff.setMesh(m) + fff.setGaussLocalizationOnCells(range(0,20),[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626],[1.,1.,1.,1.]) + fff.setGaussLocalizationOnCells(range(20,60),[0.,0.,1.,0.,0.,1.,0.5, 0.,0.5, 0.5, 0.,0.5],[0.16666666666666666,0.16666666666666666,0.6666666666666666,0.16666666666666666,0.16666666666666666,0.6666666666666666],[0.16666666666666666,0.16666666666666666,0.16666666666666666]) + fff.setGaussLocalizationOnCells(range(60,80),[-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.],[-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,-0.774596669241483,0.0,0.0,0.0],[0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234]) + return fff build2DTargetMesh_1=classmethod(build2DTargetMesh_1) build2DSourceMesh_1=classmethod(build2DSourceMesh_1) @@ -601,4 +649,6 @@ class MEDCouplingDataForTest: buildCoordsForMultiTypes_1=classmethod(buildCoordsForMultiTypes_1) buildHexa8Mesh_1=classmethod(buildHexa8Mesh_1) buildPointe_1=classmethod(buildPointe_1) + buildFieldOnGauss_1=classmethod(buildFieldOnGauss_1) + buildFieldOnGauss_2=classmethod(buildFieldOnGauss_2) pass diff --git a/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py b/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py index 5d15b1181..1a5bd6264 100644 --- a/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py @@ -22,6 +22,536 @@ from MEDCoupling import * import unittest class MEDCouplingBasicsTest(unittest.TestCase): + def testExample_DataArrayInt_(self): +#! [PySnippet_DataArrayInt__1] + pass + + def testExample_DataArrayInt_getTuple(self): +#! [Snippet_DataArrayInt_getTuple_1] + dv=DataArrayInt.New(); + dv.alloc( 6, 1 ) + dv.iota(7) + dv.rearrange( 2 ) + print dv.getTuple( 1 ) +#! [Snippet_DataArrayInt_getTuple_1] +#! [Snippet_DataArrayInt_getTuple_2] + for tpl in dv: + print tpl +#! [Snippet_DataArrayInt_getTuple_2] + pass + + def testExample_DataArrayInt_buildPermutationArr(self): +#! [PySnippet_DataArrayInt_buildPermutationArr_1] + a=DataArrayInt.New() + a.setValues([4,5,6,7,8],5,1) + b=DataArrayInt.New() + b.setValues([5,4,8,6,7],5,1) + c=a.buildPermutationArr(b) +#! [PySnippet_DataArrayInt_buildPermutationArr_1] + self.assertEqual([1,0,4,2,3],c.getValues()) + pass + + def testExample_DataArrayInt_invertArrayO2N2N2O(self): +#! [PySnippet_DataArrayInt_invertArrayO2N2N2O_1] + arr1=[2,0,4,1,5,3] + da=DataArrayInt.New(); + da.setValues(arr1,6,1); + da2=da.invertArrayO2N2N2O(6); + expected1=[1,3,0,5,2,4] + for i in xrange(6): + self.assertEqual(expected1[i],da2.getIJ(i,0)); + pass +#! [PySnippet_DataArrayInt_invertArrayO2N2N2O_1] + pass + + def testExample_DataArrayInt_invertArrayN2O2O2N(self): +#! [PySnippet_DataArrayInt_invertArrayN2O2O2N_1] + arr1=[2,0,4,1,5,3] + da=DataArrayInt.New(); + da.setValues(arr1,6,1); + da2=da.invertArrayN2O2O2N(7); + expected1=[1,3,0,5,2,4,-1] + for i in xrange(6): + self.assertEqual(expected1[i],da2.getIJ(i,0)); + pass +#! [PySnippet_DataArrayInt_invertArrayN2O2O2N_1] + pass + + + def testExample_DataArrayDouble_getIdsInRange(self): +#! [PySnippet_DataArrayDouble_getIdsInRange_1] + da=DataArrayDouble.New() + da.alloc( 10, 1 ) + da[ :, :] = range(10) + da2 = da.getIdsInRange( 2.5, 6 ) +#! [PySnippet_DataArrayDouble_getIdsInRange_1] + pass + + def testExample_DataArrayDouble_setPartOfValues2(self): +#! [Snippet_DataArrayDouble_setPartOfValues2_1] + da=DataArrayDouble.New() + da.alloc( 4, 7 ) + # + dv=DataArrayDouble.New(); + dv.alloc( 6, 1 ) + dv.iota(7) + dv.rearrange( 2 ) +#! [Snippet_DataArrayDouble_setPartOfValues2_1] +#! [Snippet_DataArrayDouble_setPartOfValues2_2] + da.fillWithZero() + da[ [0,1,2], [1,3] ] = dv +#! [Snippet_DataArrayDouble_setPartOfValues2_2] +#! [Snippet_DataArrayDouble_setPartOfValues2_3] + da.fillWithZero() + dv.rearrange( 6 ) + da[ [0,2,3], [0,2,3,4,5,6]] = dv +#! [Snippet_DataArrayDouble_setPartOfValues2_3] + pass + + def testExample_DataArrayInt_setPartOfValues2(self): +#! [Snippet_DataArrayInt_setPartOfValues2_1] + da=DataArrayInt.New() + da.alloc( 4, 7 ) + # + dv=DataArrayInt.New(); + dv.alloc( 6, 1 ) + dv.iota(7) + dv.rearrange( 2 ) +#! [Snippet_DataArrayInt_setPartOfValues2_1] +#! [Snippet_DataArrayInt_setPartOfValues2_2] + da.fillWithZero() + da[ [0,1,2], [1,3] ] = dv +#! [Snippet_DataArrayInt_setPartOfValues2_2] +#! [Snippet_DataArrayInt_setPartOfValues2_3] + da.fillWithZero() + dv.rearrange( 6 ) + da[ [0,2,3], [0,2,3,4,5,6]] = dv +#! [Snippet_DataArrayInt_setPartOfValues2_3] + pass + + def testExample_DataArrayDouble_setPartOfValues3(self): +#! [Snippet_DataArrayDouble_setPartOfValues3_1] + da=DataArrayDouble.New() + da.alloc( 4, 7 ) + # + dv=DataArrayDouble.New(); + dv.alloc( 6, 1 ) + dv.iota(7) + dv.rearrange( 2 ) +#! [Snippet_DataArrayDouble_setPartOfValues3_1] +#! [Snippet_DataArrayDouble_setPartOfValues3_2] + da.fillWithZero() + da[ 0:3, [1,3] ] = dv +#! [Snippet_DataArrayDouble_setPartOfValues3_2] +#! [Snippet_DataArrayDouble_setPartOfValues3_3] + da.fillWithZero() + dv.rearrange( 6 ) + da[ 0:4:2, [0,2,3,4,5,6]] = dv +#! [Snippet_DataArrayDouble_setPartOfValues3_3] + pass + + def testExample_DataArrayInt_setPartOfValues3(self): +#! [Snippet_DataArrayInt_setPartOfValues3_1] + da=DataArrayInt.New() + da.alloc( 4, 7 ) + # + dv=DataArrayInt.New(); + dv.alloc( 6, 1 ) + dv.iota(7) + dv.rearrange( 2 ) +#! [Snippet_DataArrayInt_setPartOfValues3_1] +#! [Snippet_DataArrayInt_setPartOfValues3_2] + da.fillWithZero() + da[ 0:3, [1,3] ] = dv +#! [Snippet_DataArrayInt_setPartOfValues3_2] +#! [Snippet_DataArrayInt_setPartOfValues3_3] + da.fillWithZero() + dv.rearrange( 6 ) + da[ 0:4:2, [0,2,3,4,5,6]] = dv +#! [Snippet_DataArrayInt_setPartOfValues3_3] + pass + + def testExample_DataArrayDouble_setPartOfValues1(self): +#! [Snippet_DataArrayDouble_setPartOfValues1_1] + da=DataArrayDouble.New() + da.alloc( 4, 4 ) + da.setInfoOnComponents( ["v1","v2","v3","v4"]) + # + dv=DataArrayDouble.New(); + dv.alloc( 4, 1 ) + dv.iota(7) + dv.rearrange( 2 ) + dv.setInfoOnComponents( ["a1","a2"]) +#! [Snippet_DataArrayDouble_setPartOfValues1_1] +#! [Snippet_DataArrayDouble_setPartOfValues1_2] + da.fillWithZero() + da.setPartOfValues1( dv, 1,3,1, 1,3,1, True ) +#! [Snippet_DataArrayDouble_setPartOfValues1_2] +#! [Snippet_DataArrayDouble_setPartOfValues1_3] + da.fillWithZero() + da.setPartOfValues1( dv, 0,4,1, 1,2,1, False ) +#! [Snippet_DataArrayDouble_setPartOfValues1_3] +#! [Snippet_DataArrayDouble_setPartOfValues1_4] + da.fillWithZero() + da.setPartOfValues1( dv, 1,2,1, 0,4,1, False ) +#! [Snippet_DataArrayDouble_setPartOfValues1_4] +#! [Snippet_DataArrayDouble_setPartOfValues1_5] + da.fillWithZero() + da.setPartOfValues1( dv, 0,3,2, 1,4,2, True ) +#! [Snippet_DataArrayDouble_setPartOfValues1_5] +#! [Snippet_DataArrayDouble_setPartOfValues1_6] + da2 = da.deepCpy() + da2.fillWithZero() + da2[ 0:3:2, 1:4:2 ] = dv + self.assertTrue( da.isEqual( da2, 1e-20 )) +#! [Snippet_DataArrayDouble_setPartOfValues1_6] + pass + + def testExample_DataArrayInt_setPartOfValues1(self): +#! [Snippet_DataArrayInt_setPartOfValues1_1] + da=DataArrayInt.New() + da.alloc( 4, 4 ) + da.setInfoOnComponents( ["v1","v2","v3","v4"]) + # + dv=DataArrayInt.New(); + dv.alloc( 4, 1 ) + dv.iota(7) + dv.rearrange( 2 ) + dv.setInfoOnComponents( ["a1","a2"]) +#! [Snippet_DataArrayInt_setPartOfValues1_1] +#! [Snippet_DataArrayInt_setPartOfValues1_2] + da.fillWithZero() + da.setPartOfValues1( dv, 1,3,1, 1,3,1, True ) +#! [Snippet_DataArrayInt_setPartOfValues1_2] +#! [Snippet_DataArrayInt_setPartOfValues1_3] + da.fillWithZero() + da.setPartOfValues1( dv, 0,4,1, 1,2,1, False ) +#! [Snippet_DataArrayInt_setPartOfValues1_3] +#! [Snippet_DataArrayInt_setPartOfValues1_4] + da.fillWithZero() + da.setPartOfValues1( dv, 1,2,1, 0,4,1, False ) +#! [Snippet_DataArrayInt_setPartOfValues1_4] +#! [Snippet_DataArrayInt_setPartOfValues1_5] + da.fillWithZero() + da.setPartOfValues1( dv, 0,3,2, 1,4,2, True ) +#! [Snippet_DataArrayInt_setPartOfValues1_5] +#! [Snippet_DataArrayInt_setPartOfValues1_6] + da2 = da.deepCpy() + da2.fillWithZero() + da2[ 0:3:2, 1:4:2 ] = dv + self.assertTrue( da.isEqual( da2 )) +#! [Snippet_DataArrayInt_setPartOfValues1_6] + pass + + def testExample_DataArrayDouble_setPartOfValuesSimple1(self): +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_1] + da=DataArrayDouble.New() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_1] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_2] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 ) +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_2] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_3] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 ) +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_3] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_4] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 ) +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_4] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_5] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 ) +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_5] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_6] + da2 = da.deepCpy() + da2.fillWithZero() + da2[ 0:3:2, 1:4:2 ] = dv + self.assertTrue( da.isEqual( da2, 1e-20 )) +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_6] + pass + + def testExample_DataArrayInt_setPartOfValuesSimple1(self): +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_1] + da=DataArrayInt.New() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_1] +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_2] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 ) +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_2] +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_3] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 ) +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_3] +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_4] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 ) +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_4] +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_5] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 ) +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_5] +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_6] + da2 = da.deepCpy() + da2.fillWithZero() + da2[ 0:3:2, 1:4:2 ] = dv + self.assertTrue( da.isEqual( da2 )) +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_6] + pass + + def testExample_DataArrayDouble_setPartOfValuesSimple2(self): +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_1] + da=DataArrayDouble.New() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_1] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_2] + da.fillWithZero() + da[[1,2], [1,2]] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_2] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_3] + da.fillWithZero() + da[[0,1,2,3], [1]] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_3] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_4] + da.fillWithZero() + da[[1], [0,1,2,3]] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_4] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_5] + da.fillWithZero() + da[[0,2], [1,3]] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_5] + pass + + def testExample_DataArrayInt_setPartOfValuesSimple2(self): +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_1] + da=DataArrayInt.New() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_1] +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_2] + da.fillWithZero() + da[[1,2], [1,2]] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_2] +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_3] + da.fillWithZero() + da[[0,1,2,3], [1]] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_3] +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_4] + da.fillWithZero() + da[[1], [0,1,2,3]] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_4] +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_5] + da.fillWithZero() + da[[0,2], [1,3]] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_5] + pass + + def testExample_DataArrayDouble_setPartOfValuesSimple3(self): +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_1] + da=DataArrayDouble.New() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_1] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_2] + da.fillWithZero() + da[[1,2], 1:3] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_2] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_3] + da.fillWithZero() + da[[0,1,2,3], 1:2] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_3] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_4] + da.fillWithZero() + da[[1], 0:4] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_4] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_5] + da.fillWithZero() + da[[0,2], 1:4:2] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_5] + pass + + def testExample_DataArrayInt_setPartOfValuesSimple3(self): +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_1] + da=DataArrayInt.New() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_1] +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_2] + da.fillWithZero() + da[[1,2], 1:3] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_2] +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_3] + da.fillWithZero() + da[[0,1,2,3], 1:2] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_3] +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_4] + da.fillWithZero() + da[[1], 0:4] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_4] +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_5] + da.fillWithZero() + da[[0,2], 1:4:2] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_5] + pass + + def testExample_DataArrayDouble_setSelectedComponents(self): +#! [Snippet_DataArrayDouble_setSelectedComponents1] + da=DataArrayDouble.New(); + array1=[1.,2., 3.,4., 5.,6.] + da.setValues(array1,3,2) + da.setInfoOnComponents( ["a1","a2"]) +#! [Snippet_DataArrayDouble_setSelectedComponents1] +#! [Snippet_DataArrayDouble_setSelectedComponents2] + dv=DataArrayDouble.New(); + dv.alloc( 4, 4 ) + dv.fillWithZero() + dv.setInfoOnComponents( ["v1","v2","v3","v4"]) + dv2 = dv.deepCpy() + dv.setSelectedComponents( da, [1,0] ) +#! [Snippet_DataArrayDouble_setSelectedComponents2] +#! [Snippet_DataArrayDouble_setSelectedComponents3] + dv2[:3,[1,0]] = da + self.assertTrue( dv.isEqualWithoutConsideringStr( dv2, 1e-20 )) +#! [Snippet_DataArrayDouble_setSelectedComponents3] + pass + + def testExample_DataArrayInt_setSelectedComponents(self): +#! [Snippet_DataArrayInt_setSelectedComponents1] + da=DataArrayInt.New(); + array1=[1,2, 3,4, 5,6] + da.setValues(array1,3,2) + da.setInfoOnComponents( ["a1","a2"]) +#! [Snippet_DataArrayInt_setSelectedComponents1] +#! [Snippet_DataArrayInt_setSelectedComponents2] + dv=DataArrayInt.New(); + dv.alloc( 4, 4 ) + dv.fillWithZero() + dv.setInfoOnComponents( ["v1","v2","v3","v4"]) + dv2 = dv.deepCpy() + dv.setSelectedComponents( da, [1,0] ) +#! [Snippet_DataArrayInt_setSelectedComponents2] +#! [Snippet_DataArrayInt_setSelectedComponents3] + dv2[:3,[1,0]] = da + self.assertTrue( dv.isEqualWithoutConsideringStr( dv2 )) +#! [Snippet_DataArrayInt_setSelectedComponents3] + pass + + def testExample_DataArrayDouble_getDifferentValues(self): +#! [Snippet_DataArrayDouble_getDifferentValues1] + da=DataArrayDouble.New(); + array1=[2.3,1.2,1.3,2.3,2.301,0.8] + da.setValues(array1,6,1) + # + dv=da.getDifferentValues(2e-1); + expected2=[2.301,1.3,0.8] + self.assertEqual(3,dv.getNbOfElems()); + for i in xrange(3): + self.assertAlmostEqual(expected2[i],dv.getIJ(i,0),14); + pass +#! [Snippet_DataArrayDouble_getDifferentValues1] + pass + + def testExample_DataArrayDouble_findCommonTuples1(self): +#! [PySnippet_DataArrayDouble_findCommonTuples1] + da=DataArrayDouble.New(); + array2=[2.3,2.3, 1.2,1.2, 1.3,1.3, 2.3,2.3, 2.301,2.301, 0.8,0.8] + da.setValues(array2,6,2) +#! [PySnippet_DataArrayDouble_findCommonTuples1] +#! [PySnippet_DataArrayDouble_findCommonTuples2] + c,cI=da.findCommonTuples(1e-1); + expected3=[0,3,4,1,2] + expected4=[0,3,5] + self.assertEqual(expected3,c.getValues()) + self.assertEqual(expected4,cI.getValues()) +#! [PySnippet_DataArrayDouble_findCommonTuples2] + pass + + def testExampleDataArrayDoubleMeldWith(self): +#! [PySnippet_DataArrayDouble_Meld1_1] + da1=DataArrayDouble.New(); + da1.alloc(7,2); + da2=DataArrayDouble.New(); + da2.alloc(7,1); + # + da1.fillWithValue(7.); + da2.iota(0.); + da3=da2.applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec"); + # + da1.setInfoOnComponent(0,"c0da1"); + da1.setInfoOnComponent(1,"c1da1"); + da3.setInfoOnComponent(0,"c0da3"); + da3.setInfoOnComponent(1,"c1da3"); + da3.setInfoOnComponent(2,"c2da3"); + # + da1C=da1.deepCpy(); + da1.meldWith(da3); +#! [PySnippet_DataArrayDouble_Meld1_1] + + def testExampleDataArrayIntMeldWith(self): +#! [PySnippet_DataArrayInt_Meld1_1] + da1=DataArrayInt.New(); + da1.alloc(7,2); + da2=DataArrayInt.New(); + da2.alloc(7,1); + # + da1.fillWithValue(7); + da2.iota(0); + # + da1.setInfoOnComponent(0,"c0da1"); + da1.setInfoOnComponent(1,"c1da1"); + da2.setInfoOnComponent(0,"c0da2"); + # + da1.meldWith(da2); +#! [PySnippet_DataArrayInt_Meld1_1] + + def testExampleDataArrayDoubleKeepSelectedComponents1(self): +#! [SnippeDataArrayDoubleKeepSelectedComponents1_1] + arr1=[1.,2.,3.,4., # tuple 0 + 11.,12.,13.,14., # tuple 1 + 21.,22.,23.,24., # ... + 31.,32.,33.,34., + 41.,42.,43.,44.] + a1=DataArrayDouble.New() + a1.setValues(arr1,5,4) + a1.setInfoOnComponent(0,"a"); + a1.setInfoOnComponent(1,"b"); + a1.setInfoOnComponent(2,"c"); + a1.setInfoOnComponent(3,"d"); +#! [SnippeDataArrayDoubleKeepSelectedComponents1_1] +#! [SnippeDataArrayDoubleKeepSelectedComponents1_2] + arr2V=[1,2,1,2,0,0] + a2=a1.keepSelectedComponents(arr2V) +#! [SnippeDataArrayDoubleKeepSelectedComponents1_2] + pass + + def testExampleDataArrayIntKeepSelectedComponents1(self): +#! [SnippeDataArrayIntKeepSelectedComponents1_1] + arr1=[1,2,3,4, # tuple 0 + 11,12,13,14, # tuple 1 + 21,22,23,24, # + 31,32,33,34, + 41,42,43,44] + a1=DataArrayInt.New() + a1.setValues(arr1,5,4) + a1.setInfoOnComponent(0,"a"); + a1.setInfoOnComponent(1,"b"); + a1.setInfoOnComponent(2,"c"); + a1.setInfoOnComponent(3,"d"); +#! [SnippeDataArrayIntKeepSelectedComponents1_1] +#! [SnippeDataArrayIntKeepSelectedComponents1_2] + arr2V=[1,2,1,2,0,0] + a2=a1.keepSelectedComponents(arr2V) +#! [SnippeDataArrayIntKeepSelectedComponents1_2] +#! [SnippeDataArrayIntKeepSelectedComponents1_3] + a3=a1[:,arr2V ] +#! [SnippeDataArrayIntKeepSelectedComponents1_3] + pass + def testExampleFieldDoubleBuildSubPart1(self): from MEDCouplingDataForTest import MEDCouplingDataForTest #! [PySnippetFieldDoubleBuildSubPart1_1] diff --git a/src/MEDCoupling_Swig/MEDCouplingRemapper.i b/src/MEDCoupling_Swig/MEDCouplingRemapper.i index 3b2359a61..489c9e565 100644 --- a/src/MEDCoupling_Swig/MEDCouplingRemapper.i +++ b/src/MEDCoupling_Swig/MEDCouplingRemapper.i @@ -42,6 +42,14 @@ using namespace INTERP_KERNEL; namespace ParaMEDMEM { + typedef enum + { + IK_ONLY_PREFERED = 0, + NOT_IK_ONLY_PREFERED = 1, + IK_ONLY_FORCED = 2, + NOT_IK_ONLY_FORCED =3 + } InterpolationMatrixPolicy; + class MEDCouplingRemapper : public TimeLabel, public INTERP_KERNEL::InterpolationOptions { private: @@ -56,16 +64,18 @@ namespace ParaMEDMEM void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); - bool setOptionInt(const std::string& key, int value); - bool setOptionDouble(const std::string& key, double value); - bool setOptionString(const std::string& key, const std::string& value); + bool setOptionInt(const std::string& key, int value) throw(INTERP_KERNEL::Exception); + bool setOptionDouble(const std::string& key, double value) throw(INTERP_KERNEL::Exception); + bool setOptionString(const std::string& key, const std::string& value) throw(INTERP_KERNEL::Exception); + int getInterpolationMatrixPolicy() const throw(INTERP_KERNEL::Exception); + void setInterpolationMatrixPolicy(int newInterpMatPol) throw(INTERP_KERNEL::Exception); // int nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs) throw(INTERP_KERNEL::Exception); int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) throw(INTERP_KERNEL::Exception); double getMaxValueInCrudeMatrix() const throw(INTERP_KERNEL::Exception); %extend { - PyObject *getCrudeMatrix() const + PyObject *getCrudeMatrix() const throw(INTERP_KERNEL::Exception) { const std::vector >& m=self->getCrudeMatrix(); std::size_t sz=m.size(); diff --git a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i index faac75832..7a1a8eb01 100644 --- a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i +++ b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i @@ -1454,7 +1454,7 @@ static const double *convertObjToPossibleCpp5_Safe2(PyObject *value, int& sw, do throw INTERP_KERNEL::Exception(oss.str().c_str()); } else - return 0; + { nbTuples=0; return 0; } } } status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); @@ -1462,15 +1462,152 @@ static const double *convertObjToPossibleCpp5_Safe2(PyObject *value, int& sw, do { e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); sw=3; - if(e->getNumberOfCompo()==nbCompExpected) + if(e) + { + if(e->getNumberOfCompo()==nbCompExpected) + { + nbTuples=1; + return e->getConstPointer(); + } + else + { + std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input DataArrayDoubleTuple has " << e->getNumberOfCompo() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + if(throwIfNullPt) + { + std::ostringstream oss; oss << msg << " null pointer not accepted!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + { nbTuples=0; return 0; } + } + } + throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); +} + +/*! + * if value int -> cpp val sw=1 + * if value double -> cpp val sw=1 + * if value DataArrayDouble -> cpp DataArrayDouble sw=2 + * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 + * if value list[int,double] -> cpp std::vector sw=4 + * if value tuple[int,double] -> cpp std::vector sw=4 + */ +static const double *convertObjToPossibleCpp5_SingleCompo(PyObject *value, int& sw, double& val, std::vector& f, + const char *msg, bool throwIfNullPt, int& nbTuples) throw(INTERP_KERNEL::Exception) +{ + ParaMEDMEM::DataArrayDouble *d=0; + ParaMEDMEM::DataArrayDoubleTuple *e=0; + sw=-1; + if(PyFloat_Check(value)) + { + val=PyFloat_AS_DOUBLE(value); + sw=1; + nbTuples=1; + return &val; + } + if(PyInt_Check(value)) + { + val=(double)PyInt_AS_LONG(value); + sw=1; + nbTuples=1; + return &val; + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + f.resize(size); + for(int i=0;i(argp); + sw=2; + if(d) + { + if(d->getNumberOfComponents()==1) + { + nbTuples=d->getNumberOfTuples(); + return d->getConstPointer(); + } + else + { + std::ostringstream oss; oss << msg << "nb of components expected to be one, and input has " << d->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + if(throwIfNullPt) + { + std::ostringstream oss; oss << msg << " null pointer not accepted!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + { nbTuples=0; return 0; } + } + } + status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); + if(SWIG_IsOK(status)) + { + e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); + sw=3; + if(e) + { + nbTuples=e->getNumberOfCompo(); return e->getConstPointer(); } else { - std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input DataArrayDoubleTuple has " << e->getNumberOfCompo() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); + if(throwIfNullPt) + { + std::ostringstream oss; oss << msg << " null pointer not accepted!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + { nbTuples=0; return 0; } } } throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx index e0bb931f4..d1da7a2b8 100644 --- a/src/MEDLoader/MEDFileField.cxx +++ b/src/MEDLoader/MEDFileField.cxx @@ -831,7 +831,7 @@ bool MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(int offset, const std::ve } MEDCouplingAutoRefCountObjectPtr newGeoTypesEltIdsAllGather=DataArrayInt::Aggregate(newGeoTypesPerChunk2); newGeoTypesPerChunk.clear(); newGeoTypesPerChunk2.clear(); MEDCouplingAutoRefCountObjectPtr newGeoTypesEltIdsAllGather2=DataArrayInt::Aggregate(newGeoTypesPerChunk3); newGeoTypesPerChunk_bis.clear(); newGeoTypesPerChunk3.clear(); - std::set diffVals=newGeoTypesEltIdsAllGather->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr diffVals=newGeoTypesEltIdsAllGather->getDifferentValues(); MEDCouplingAutoRefCountObjectPtr renumEltIds=newGeoTypesEltIdsAllGather->buildPermArrPerLevel(); // MEDCouplingAutoRefCountObjectPtr renumTupleIds=newGeoTypesPerChunk4->buildPermArrPerLevel(); @@ -840,10 +840,10 @@ bool MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(int offset, const std::ve arrPart->renumberInPlace(renumTupleIds->begin()); arr->setPartOfValues1(arrPart,offset,offset+szTuples,1,0,arrPart->getNumberOfComponents(),1); bool ret=false; - std::set::const_iterator idIt=diffVals.begin(); + const int *idIt=diffVals->begin(); std::list li(entriesOnSameDisc.begin(),entriesOnSameDisc.end()); int offset2=0; - for(std::size_t i=0;igetNumberOfTuples();i++,idIt++) { MEDCouplingAutoRefCountObjectPtr ids=newGeoTypesEltIdsAllGather->getIdsEqual(*idIt); MEDCouplingAutoRefCountObjectPtr subIds=newGeoTypesEltIdsAllGather2->selectByTupleId(ids->begin(),ids->end()); @@ -1064,10 +1064,10 @@ std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const M throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); const DataArrayInt *da=disc2->getArrayOfDiscIds(); MEDCouplingAutoRefCountObjectPtr da2=da->selectByTupleId2(offset,offset+nbOfCells,1); - std::set retTmp=da2->getDifferentValues(); - if(retTmp.find(-1)!=retTmp.end()) + MEDCouplingAutoRefCountObjectPtr retTmp=da2->getDifferentValues(); + if(retTmp->presenceOfValue(-1)) throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !"); - std::vector ret(retTmp.begin(),retTmp.end()); + std::vector ret(retTmp->begin(),retTmp->end()); return ret; } @@ -1134,10 +1134,10 @@ std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const M throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); const DataArrayInt *da=disc2->getArrayOfDiscIds(); MEDCouplingAutoRefCountObjectPtr da2=da->selectByTupleIdSafe(subCells->getConstPointer(),subCells->getConstPointer()+subCells->getNumberOfTuples()); - std::set retTmp=da2->getDifferentValues(); - if(retTmp.find(-1)!=retTmp.end()) + MEDCouplingAutoRefCountObjectPtr retTmp=da2->getDifferentValues(); + if(retTmp->presenceOfValue(-1)) throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !"); - std::vector ret(retTmp.begin(),retTmp.end()); + std::vector ret(retTmp->begin(),retTmp->end()); return ret; } diff --git a/src/MEDLoader/MEDFileField.hxx b/src/MEDLoader/MEDFileField.hxx index cf17442a7..fc98cbcda 100644 --- a/src/MEDLoader/MEDFileField.hxx +++ b/src/MEDLoader/MEDFileField.hxx @@ -35,6 +35,7 @@ #include #include #include +#include #include "med.h" diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx index 987e61bd0..fe3be7088 100644 --- a/src/MEDLoader/MEDFileMesh.cxx +++ b/src/MEDLoader/MEDFileMesh.cxx @@ -660,9 +660,9 @@ void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt); if(fieldFamIds==0) throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !"); - std::set famIds=fieldFamIds->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr famIds=fieldFamIds->getDifferentValues(); std::vector familiesOnWholeGroup; - for(std::set::const_iterator it=famIds.begin();it!=famIds.end();it++) + for(const int *it=famIds->begin();it!=famIds->end();it++) { bool tmp; familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp)); @@ -694,9 +694,9 @@ bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it); if(fieldFamIds) { - std::set famIds3=fieldFamIds->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr famIds3=fieldFamIds->getDifferentValues(); std::vector tmp; - std::set_intersection(famIds3.begin(),famIds3.end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector >(tmp)); + std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector >(tmp)); for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) { ret=false; @@ -940,13 +940,13 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception const DataArrayInt *fam=getFamilyFieldAtLevel(*it); if(fam) { - std::set tmp=fam->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); std::set r2; - std::set_intersection(tmp.begin(),tmp.end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end())); + std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end())); if(!r2.empty()) famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end()); std::set r3; - std::set_union(tmp.begin(),tmp.end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end())); + std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end())); } } if(famIdsToRenum.empty()) @@ -999,15 +999,15 @@ void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception) if(fam) { int refId=1; - std::set tmp=fam->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); std::map ren; - for(std::set::const_iterator it=tmp.begin();it!=tmp.end();it++,refId++) + for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) ren[*it]=refId; int nbOfTuples=fam->getNumberOfTuples(); int *start=const_cast(fam)->getPointer(); for(int *w=start;w!=start+nbOfTuples;w++) *w=ren[*w]; - for(std::set::const_iterator it=tmp.begin();it!=tmp.end();it++) + for(const int *it=tmp->begin();it!=tmp->end();it++) { if(allIds->presenceOfValue(*it)) { @@ -1025,15 +1025,15 @@ void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception) if(fam) { int refId=-1; - std::set tmp=fam->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); std::map ren; - for(std::set::const_iterator it=tmp.begin();it!=tmp.end();it++,refId--) + for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) ren[*it]=refId; int nbOfTuples=fam->getNumberOfTuples(); int *start=const_cast(fam)->getPointer(); for(int *w=start;w!=start+nbOfTuples;w++) *w=ren[*w]; - for(std::set::const_iterator it=tmp.begin();it!=tmp.end();it++) + for(const int *it=tmp->begin();it!=tmp->end();it++) { if(allIds->presenceOfValue(*it)) { @@ -1049,9 +1049,9 @@ void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception) DataArrayInt *fam=const_cast(getFamilyFieldAtLevel(*it2)); if(fam) { - std::set tmp=fam->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); fam->fillWithZero(); - for(std::set::const_iterator it3=tmp.begin();it3!=tmp.end();it3++) + for(const int *it3=tmp->begin();it3!=tmp->end();it3++) if(allIds->presenceOfValue(*it3)) { std::string famName=getFamilyNameGivenId(*it3); @@ -1091,15 +1091,15 @@ void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception) const DataArrayInt *fam=getFamilyFieldAtLevel(1); if(fam) { - std::set tmp=fam->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); std::map ren; - for(std::set::const_iterator it=tmp.begin();it!=tmp.end();it++,refId++) + for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) ren[*it]=refId; int nbOfTuples=fam->getNumberOfTuples(); int *start=const_cast(fam)->getPointer(); for(int *w=start;w!=start+nbOfTuples;w++) *w=ren[*w]; - for(std::set::const_iterator it=tmp.begin();it!=tmp.end();it++) + for(const int *it=tmp->begin();it!=tmp->end();it++) { if(allIds->presenceOfValue(*it)) { @@ -1116,15 +1116,15 @@ void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception) const DataArrayInt *fam=getFamilyFieldAtLevel(1); if(fam) { - std::set tmp=fam->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); std::map ren; - for(std::set::const_iterator it=tmp.begin();it!=tmp.end();it++,refId--) + for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) ren[*it]=refId; int nbOfTuples=fam->getNumberOfTuples(); int *start=const_cast(fam)->getPointer(); for(int *w=start;w!=start+nbOfTuples;w++) *w=ren[*w]; - for(std::set::const_iterator it=tmp.begin();it!=tmp.end();it++) + for(const int *it=tmp->begin();it!=tmp->end();it++) { if(allIds->presenceOfValue(*it)) { @@ -1257,7 +1257,7 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector ids=fam->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr ids=fam->getDifferentValues(); appendFamilyEntries(ids,fidsOfGroups,grpsName2); setFamilyFieldArr(meshDimRelToMaxExt,fam); } @@ -1267,10 +1267,10 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames) +void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames) { std::map famInv; - for(std::set::const_iterator it=famIds.begin();it!=famIds.end();it++) + for(const int *it=famIds->begin();it!=famIds->end();it++) { std::ostringstream oss; oss << "Family_" << (*it); @@ -2175,9 +2175,9 @@ void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception) for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) { const DataArrayInt *ffield=getFamilyFieldAtLevel(*it); - std::set ids=ffield->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr ids=ffield->getDifferentValues(); std::set res; - std::set_union(ids.begin(),ids.end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin())); + std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin())); allFamsIds=res; } std::set famNamesToKill; @@ -2474,7 +2474,7 @@ void MEDFileUMesh::addGroupUnderground(const DataArrayInt *ids, DataArrayInt *fa std::list< MEDCouplingAutoRefCountObjectPtr > allFamIds=getAllNonNullFamilyIds(); allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp)); MEDCouplingAutoRefCountObjectPtr famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end()); - std::set diffFamIds=famIds->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr diffFamIds=famIds->getDifferentValues(); std::vector familyIds; std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerfamiliyIds; int maxVal=getTheMaxFamilyId()+1; @@ -2482,7 +2482,7 @@ void MEDFileUMesh::addGroupUnderground(const DataArrayInt *ids, DataArrayInt *fa std::map > groups(_groups); std::vector fams; bool created(false); - for(std::set::const_iterator famId=diffFamIds.begin();famId!=diffFamIds.end();famId++) + for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++) { MEDCouplingAutoRefCountObjectPtr ids2Tmp=famIds->getIdsEqual(*famId); MEDCouplingAutoRefCountObjectPtr ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end()); diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx index eb1e5bb37..b8656a6b7 100644 --- a/src/MEDLoader/MEDFileMesh.hxx +++ b/src/MEDLoader/MEDFileMesh.hxx @@ -138,7 +138,7 @@ namespace ParaMEDMEM void dealWithTinyInfo(const MEDCouplingMesh *m) throw(INTERP_KERNEL::Exception); virtual void synchronizeTinyInfoOnLeaves() const = 0; void getFamilyRepr(std::ostream& oss) const; - virtual void appendFamilyEntries(const std::set& famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames); + virtual void appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames); virtual void changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception) = 0; static void TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp); static void ChangeAllGroupsContainingFamily(std::map >& groups, const char *familyNameToChange, const std::vector& newFamiliesNames) throw(INTERP_KERNEL::Exception); diff --git a/src/MEDLoader/MEDFileParameter.cxx b/src/MEDLoader/MEDFileParameter.cxx index e9c3c9abf..a0ecb8f53 100644 --- a/src/MEDLoader/MEDFileParameter.cxx +++ b/src/MEDLoader/MEDFileParameter.cxx @@ -24,6 +24,8 @@ #include "InterpKernelAutoPtr.hxx" +#include + using namespace ParaMEDMEM; MEDFileParameter1TS::MEDFileParameter1TS(int iteration, int order, double time):_iteration(iteration),_order(order),_time(time) diff --git a/src/MEDLoader/Swig/MEDLoaderExamplesTest.py b/src/MEDLoader/Swig/MEDLoaderExamplesTest.py index 24ee31a8c..db4b25406 100644 --- a/src/MEDLoader/Swig/MEDLoaderExamplesTest.py +++ b/src/MEDLoader/Swig/MEDLoaderExamplesTest.py @@ -167,7 +167,7 @@ class MEDLoaderBasicsTest(unittest.TestCase): #! [PySnippetMeshAdvAPI1_2] self.assertTrue(isinstance(myMesh,MEDCouplingUMesh)) myMesh.setName(meshName) - MEDLoader.WriteUMesh("wFile1.med",myMesh,True) + MEDLoader.WriteUMesh("wFile1.med",myMesh,False) #! [PySnippetMeshAdvAPI1_2] f=myMesh.getMeasureField(ON_CELLS) f=f.buildNewTimeReprFromThis(ONE_TIME,False) diff --git a/src/MEDLoader/Swig/MEDLoaderTest.py b/src/MEDLoader/Swig/MEDLoaderTest.py index 42f11222e..e80c1f46f 100644 --- a/src/MEDLoader/Swig/MEDLoaderTest.py +++ b/src/MEDLoader/Swig/MEDLoaderTest.py @@ -545,6 +545,22 @@ class MEDLoaderTest(unittest.TestCase): self.assertTrue(fs[2]=="Field3"); self.assertTrue(fs[3]=="Field8"); pass + + def testBigNbOfCompoNonReg(self): + fileName="Pyfile57.med" + m=MEDLoader.MEDCouplingCMesh() ; m.setCoords(MEDLoader.DataArrayDouble([0,1,2,3]),MEDLoader.DataArrayDouble([0,1]),MEDLoader.DataArrayDouble([0,1])) + m=m.buildUnstructured() ; m.setName("TinyMesh") + f=MEDLoader.MEDCouplingFieldDouble(MEDLoader.ON_CELLS) ; f.setMesh(m) + nbOfCompo=4100 + arr=MEDLoader.DataArrayDouble(nbOfCompo*3) ; arr.iota() + arr.rearrange(nbOfCompo) + arr.setInfoOnComponents(["c%i"%(i) for i in xrange(nbOfCompo)]) + f.setArray(arr) + f.setName("FieldBigCompo") + MEDLoader.MEDLoader.WriteField(fileName,f,True) + f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,m.getName(),0,f.getName(),-1,-1) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + pass pass unittest.main()
Intensive extensive