return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(_bl_tr);
}
+/*!
+ * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter
+ * the must be >= 0.
+ *
+ * \param [in] other - The other patch
+ * \param [in] ghostLev - The size of the neighborhood zone.
+ *
+ * \throw if \a this or \a other are invalid (end before start).
+ * \throw if \a ghostLev is \b not >= 0 .
+ * \throw if \a this and \a other have not the same space dimension.
+ */
+bool MEDCouplingCartesianAMRPatch::isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const
+{
+ if(ghostLev<0)
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the size of the neighborhood must be >= 0 !");
+ if(!other)
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the input patch is NULL !");
+ const std::vector< std::pair<int,int> >& thisp(getBLTRRange());
+ const std::vector< std::pair<int,int> >& otherp(other->getBLTRRange());
+ std::size_t thispsize(thisp.size());
+ if(thispsize!=otherp.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the dimensions must be the same !");
+ for(std::size_t i=0;i<thispsize;i++)
+ {
+ const std::pair<int,int>& thispp(thisp[i]);
+ const std::pair<int,int>& otherpp(otherp[i]);
+ if(thispp.second<thispp.first)
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : this patch is invalid !");
+ if(otherpp.second<otherpp.first)
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : this patch is invalid !");
+ if(otherpp.first==thispp.second+ghostLev-1)
+ continue;
+ if(otherpp.second+ghostLev-1==thispp.first)
+ continue;
+ return false;
+ }
+ return true;
+}
+
std::size_t MEDCouplingCartesianAMRPatch::getHeapMemorySizeWithoutChildren() const
{
std::size_t ret(sizeof(MEDCouplingCartesianAMRPatch));
return _patches[patchId];
}
+/*!
+ * This method states if patch2 (with id \a patchId2) is in the neighborhood of patch1 (with id \a patchId1).
+ * The neighborhood size is defined by \a ghostLev in the reference of \a this ( \b not in the reference of patches !).
+ */
+bool MEDCouplingCartesianAMRMesh::isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const
+{
+ if(ghostLev<0)
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::isPatchInNeighborhoodOf : the ghost size must be >=0 !");
+ const MEDCouplingCartesianAMRPatch *p1(getPatch(patchId1)),*p2(getPatch(patchId2));
+ if(_factors.empty())
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::isPatchInNeighborhoodOf : no factors defined !");
+ int ghostLevInPatchRef;
+ if(ghostLev==0)
+ ghostLevInPatchRef=0;
+ else
+ {
+ ghostLevInPatchRef=(ghostLev-1)/_factors[0]+1;
+ for(std::size_t i=0;i<_factors.size();i++)
+ ghostLevInPatchRef=std::max(ghostLevInPatchRef,_factors[i]/ghostLev+1);
+ }
+ return p1->isInMyNeighborhood(p2,ghostLevInPatchRef);
+}
+
/*!
* This method creates a new cell field array on given \a patchId patch in \a this starting from a coarse cell field on \a this \a cellFieldOnThis.
* This method can be seen as a fast projection from the cell field \a cellFieldOnThis on \c this->getImageMesh() to a refined part of \a this
}
/*!
- * This method is equivalent to MEDCouplingCartesianAMRMesh::createCellFieldOnPatch except that here instead of
+ * This method is equivalent to MEDCouplingCartesianAMRMesh::createCellFieldOnPatch except that here instead of creating a new instance
+ * it fills the value into the \a cellFieldOnPatch data.
*
* \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
* \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors());
}
+/*!
+ * This method is the generalization of fillCellFieldOnPatch method. This method only projects coarse to fine without considering the
+ * potential neighbor patches covered by the ghost cells of patch with id \a patchId.
+ *
+ * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
+ * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
+ * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
+ * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
+ *
+ * \sa fillCellFieldOnPatch, fillCellFieldOnPatchGhostAdv
+ */
+void MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const
+{
+ if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatchGhost : the input cell field array is NULL or not allocated !");
+ const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
+ MEDCouplingIMesh::SpreadCoarseToFineGhost(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev);
+}
+
+/*!
+ * This method is a refinement of fillCellFieldOnPatchGhost. fillCellFieldOnPatchGhost is first called.
+ * Then for all other patches than those pointed by \a patchId that overlap the ghost zone of the patch impact the ghost zone adequately.
+ *
+ * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
+ * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId.
+ * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled.
+ * \param [in] ghostLev - The size of the ghost zone (must be >=0 !)
+ * \param [in] arrsOnPatches - \b WARNING arrsOnPatches[patchId] is \b NOT \b const. All others are const.
+ */
+void MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const
+{
+ int nbp(getNumberOfPatches());
+ if(nbp!=(int)arrsOnPatches.size())
+ {
+ std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ // first, do as usual
+ fillCellFieldOnPatchGhost(patchId,cellFieldOnThis,const_cast<DataArrayDouble *>(arrsOnPatches[patchId]),ghostLev);
+ //
+ const MEDCouplingCartesianAMRPatch *refP(getPatch(patchId));
+ const std::vector< std::pair<int,int> >& refBLTR(refP->getBLTRRange());
+ for(int i=0;i<nbp;i++)
+ {
+ if(i!=patchId)
+ if(isPatchInNeighborhoodOf(i,patchId,ghostLev))
+ {
+ const MEDCouplingCartesianAMRPatch *otherP(getPatch(i));
+ const std::vector< std::pair<int,int> >& otherBLTR(otherP->getBLTRRange());
+ std::vector< std::pair<int,int> > tmp0;
+ MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(refBLTR,otherBLTR,tmp0);
+ ApplyFactorsOnCompactFrmt(tmp0,_factors);
+ ApplyGhostOnCompactFrmt(tmp0,ghostLev);
+ //std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ }
+ }
+}
+
/*!
* This method updates \a cellFieldOnThis part of values coming from the cell field \a cellFieldOnPatch lying on patch having id \a patchId.
*
*
* \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
* \throw if \a cellFieldOnPatch is NULL or not allocated
- * \sa createCellFieldOnPatch, MEDCouplingIMesh::CondenseFineToCoarse
+ * \sa createCellFieldOnPatch, MEDCouplingIMesh::CondenseFineToCoarse,fillCellFieldComingFromPatchGhost
*/
void MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const
{
MEDCouplingIMesh::CondenseFineToCoarse(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis);
}
+/*!
+ * This method is the extension of MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch managing the ghost cells. If this
+ * method is called with \a ghostLev equal to 0 it behaves exactly as MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch.
+ *
+ * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
+ * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId.
+ * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId.
+ * \param [in] ghostLev The size of ghost zone (must be >= 0 !)
+ *
+ * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
+ * \throw if \a cellFieldOnPatch is NULL or not allocated
+ * \sa fillCellFieldComingFromPatch
+ */
+void MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const
+{
+ if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated())
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatchGhost : the input cell field array is NULL or not allocated !");
+ const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
+ MEDCouplingIMesh::CondenseFineToCoarseGhost(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis,ghostLev);
+}
+
+/*!
+ * This method finds all patches (located by their ids) that are in the neighborhood of patch with id \a patchId. The neighborhood size is
+ * defined by ghostLev.
+ *
+ * \param [in] patchId - the id of the considered patch.
+ * \param [in] ghostLev - the size of the neighborhood.
+ * \return DataArrayInt * - the newly allocated array containing the list of patches in the neighborhood of the considered patch. This array is to be deallocated by the caller.
+ */
+DataArrayInt *MEDCouplingCartesianAMRMesh::findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const
+{
+ int nbp(getNumberOfPatches());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+ for(int i=0;i<nbp;i++)
+ {
+ if(i!=patchId)
+ if(isPatchInNeighborhoodOf(i,patchId,ghostLev))
+ ret->pushBackSilent(i);
+ }
+ return ret.retn();
+}
+
MEDCouplingUMesh *MEDCouplingCartesianAMRMesh::buildUnstructured() const
{
MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> part(_mesh->buildUnstructured());
}
}
+/*!
+ * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference.
+ * \param [in] factors - the factors per axis.
+ */
+void MEDCouplingCartesianAMRMesh::ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors)
+{
+ std::size_t sz(factors.size());
+ if(sz!=partBeforeFact.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !");
+ for(std::size_t i=0;i<sz;i++)
+ {
+ partBeforeFact[i].first*=factors[i];
+ partBeforeFact[i].second*=factors[i];
+ }
+}
+
+/*!
+ * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
+ * \param [in] ghostSize - the ghost size of zone for all axis.
+ */
+void MEDCouplingCartesianAMRMesh::ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
+{
+ if(ghostSize<0)
+ throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !");
+ std::size_t sz(partBeforeFact.size());
+ for(std::size_t i=0;i<sz;i++)
+ {
+ partBeforeFact[i].first+=ghostSize;
+ partBeforeFact[i].second+=ghostSize;
+ }
+}
+
std::size_t MEDCouplingCartesianAMRMesh::getHeapMemorySizeWithoutChildren() const
{
return sizeof(MEDCouplingCartesianAMRMesh);
{
class MEDCouplingIMesh;
class MEDCouplingUMesh;
+ class DataArrayInt;
class DataArrayByte;
class DataArrayDouble;
class MEDCoupling1SGTUMesh;
MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors);
// end of direct forward to _mesh
MEDCOUPLING_EXPORT int getNumberOfOverlapedCellsForFather() const;
+ MEDCOUPLING_EXPORT bool isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const;
// basic set/get
MEDCOUPLING_EXPORT const std::vector< std::pair<int,int> >& getBLTRRange() const { return _bl_tr; }
MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMesh *getMesh() const { return _mesh; }
MEDCOUPLING_EXPORT void removePatch(int patchId);
MEDCOUPLING_EXPORT int getNumberOfPatches() const;
MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRPatch *getPatch(int patchId) const;
+ MEDCOUPLING_EXPORT bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const;
MEDCOUPLING_EXPORT DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const;
MEDCOUPLING_EXPORT void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const;
+ MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const;
+ MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const;
MEDCOUPLING_EXPORT void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const;
+ MEDCOUPLING_EXPORT void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const;
+ MEDCOUPLING_EXPORT DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const;
//
MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const;
MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildMeshFromPatchEnvelop() const;
MEDCouplingCartesianAMRMesh(MEDCouplingCartesianAMRMesh *father, MEDCouplingIMesh *mesh);
void checkPatchId(int patchId) const;
void checkFactorsAndIfNotSetAssign(const std::vector<int>& factors);
+ static void ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors);
+ static void ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
protected:
MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildren() const;
*/
void MEDCouplingIMesh::CondenseFineToCoarse(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA)
{
+ if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : All input vectors (dimension) must have the same size !");
if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the parameters 1 or 3 are NULL or not allocated !");
int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
void MEDCouplingIMesh::CondenseFineToCoarseGhost(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA, int ghostSize)
{
if(ghostSize<0)
- throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level >= 0 !");
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level has to be >= 0 !");
+ if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : All input vectors (dimension) must have the same size !");
if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the parameters 1 or 3 are NULL or not allocated !");
std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
- //std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
- //std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
int nbCompo(fineDA->getNumberOfComponents());
if(coarseDA->getNumberOfComponents()!=nbCompo)
throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !");
if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp)
{
- std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
+ std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples in coarse DataArray having " << coarseDA->getNumberOfTuples() << " !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
- //int nbTuplesFine(fineDA->getNumberOfTuples());
- //int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
- /*if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
+ //
+ std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
+ std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+ int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
+ if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
{
- std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
+ std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
- }*/
+ }
+ //
double *outPtr(coarseDA->getPointer());
const double *inPtr(fineDA->begin());
//
*/
void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts)
{
+ if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !");
if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !");
int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse));
void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize)
{
if(ghostSize<0)
- throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level >= 0 !");
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !");
+ if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !");
if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated())
throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !");
std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
- //std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG));
int nbCompo(fineDA->getNumberOfComponents());
if(coarseDA->getNumberOfComponents()!=nbCompo)
std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
- /*int nbTuplesFine(fineDA->getNumberOfTuples());
- if(nbTuplesFine%nbOfTuplesInFineExp!=0)
- throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : Invalid nb of tuples in fine DataArray regarding its structure !");
- int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>()));
- if(nbTuplesFine!=fact*nbOfTuplesInFineExp)
+ //
+ std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse));
+ std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>());
+ std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+ int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG));
+ if(fineDA->getNumberOfTuples()!=nbTuplesFineExp)
{
- std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!";
+ std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
- }*/
+ }
//
double *outPtr(fineDA->getPointer());
const double *inPtr(coarseDA->begin());
* \param [in] partCompactFormat The compact subpart to be enabled.
* \param [out] fieldOut the result of the extraction.
*
- * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, SwitchOnIdsFrom
+ * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfDoubleFrom
*/
void MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom(const std::vector<int>& st, const std::vector<bool>& fieldOfBool, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& fieldOut)
{
}
}
+/*!
+ * This method is close to SwitchOnIdsFrom except that here, a sub field \a fieldOut is built starting from the input field \a fieldOfDbl having the structure \a st.
+ * The extraction is defined by \a partCompactFormat.
+ *
+ * \param [in] st The entity structure.
+ * \param [in] fieldOfDbl field of doubles having a number of tuples equal to \c MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(st).
+ * \param [in] partCompactFormat The compact subpart to be enabled.
+ * \return DataArrayDouble * -the result of the extraction.
+ *
+ * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfBoolFrom
+ */
+DataArrayDouble *MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(const std::vector<int>& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair<int,int> >& partCompactFormat)
+{
+ if(!fieldOfDbl || !fieldOfDbl->isAllocated())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : input array of double is NULL or not allocated!");
+ if(st.size()!=partCompactFormat.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : input arrays must have the same size !");
+ if(fieldOfDbl->getNumberOfTuples()!=DeduceNumberOfGivenStructure(st))
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : invalid size of input array of double regarding the structure !");
+ std::vector<int> dims(GetDimensionsFromCompactFrmt(partCompactFormat));
+ int nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims)),nbComp(fieldOfDbl->getNumberOfComponents());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuplesOfOutField,nbComp);
+ ret->copyStringInfoFrom(*fieldOfDbl);
+ double *ptRet(ret->getPointer());
+ const double *fieldOfDblPtr(fieldOfDbl->begin());
+ switch(st.size())
+ {
+ case 3:
+ {
+ for(int i=0;i<dims[2];i++)
+ {
+ int a=(partCompactFormat[2].first+i)*st[0]*st[1];
+ for(int j=0;j<dims[1];j++)
+ {
+ int b=(partCompactFormat[1].first+j)*st[0];
+ for(int k=0;k<dims[0];k++)
+ ptRet=std::copy(fieldOfDblPtr+(partCompactFormat[0].first+k+b+a)*nbComp,fieldOfDblPtr+(partCompactFormat[0].first+k+b+a+1)*nbComp,ptRet);
+ }
+ }
+ break;
+ }
+ case 2:
+ {
+ for(int j=0;j<dims[1];j++)
+ {
+ int b=(partCompactFormat[1].first+j)*st[0];
+ for(int k=0;k<dims[0];k++)
+ ptRet=std::copy(fieldOfDblPtr+(partCompactFormat[0].first+k+b)*nbComp,fieldOfDblPtr+(partCompactFormat[0].first+k+b+1)*nbComp,ptRet);
+ }
+ break;
+ }
+ case 1:
+ {
+ for(int k=0;k<dims[0];k++)
+ ptRet=std::copy(fieldOfDblPtr+(partCompactFormat[0].first+k)*nbComp,fieldOfDblPtr+(partCompactFormat[0].first+k+1)*nbComp,ptRet);
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : Dimension supported are 1,2 or 3 !");
+ }
+ return ret.retn();
+}
+
/*!
* This method changes the reference of a part of structured mesh \a partOfBigInAbs define in absolute reference to a new reference \a bigInAbs.
* So this method only performs a translation by doing \a partOfBigRelativeToBig = \a partOfBigInAbs - \a bigInAbs
* This method also checks that \a partOfBigInAbs is included in \a bigInAbs.
* This method is useful to extract a part from a field lying on a big mesh.
*
- * \sa ChangeReferenceToGlobalOfCompactFrmt, BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfBoolFrom
+ * \sa ChangeReferenceToGlobalOfCompactFrmt, BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom
*/
void MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigInAbs, std::vector< std::pair<int,int> >& partOfBigRelativeToBig)
{
* If the range contains invalid values regarding sructure an exception will be thrown.
*
* \return DataArrayInt * - a new object.
- * \sa MEDCouplingStructuredMesh::IsPartStructured, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt, SwitchOnIdsFrom, ExtractFieldOfBoolFrom
+ * \sa MEDCouplingStructuredMesh::IsPartStructured, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom
*/
DataArrayInt *MEDCouplingStructuredMesh::BuildExplicitIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat)
{
MEDCOUPLING_EXPORT static std::vector<int> GetDimensionsFromCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat);
MEDCOUPLING_EXPORT static void SwitchOnIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& vectToSwitchOn);
MEDCOUPLING_EXPORT static void ExtractFieldOfBoolFrom(const std::vector<int>& st, const std::vector<bool>& fieldOfBool, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& fieldOut);
+ MEDCOUPLING_EXPORT static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector<int>& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair<int,int> >& partCompactFormat);
MEDCOUPLING_EXPORT static void ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigInAbs, std::vector< std::pair<int,int> >& partOfBigRelativeToBig);
MEDCOUPLING_EXPORT static void ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigRelativeToBig, std::vector< std::pair<int,int> >& partOfBigInAbs);
MEDCOUPLING_EXPORT static DataArrayInt *BuildExplicitIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat);
%newobject ParaMEDMEM::MEDCouplingStructuredMesh::build1SGTUnstructured;
%newobject ParaMEDMEM::MEDCouplingStructuredMesh::build1SGTSubLevelMesh;
%newobject ParaMEDMEM::MEDCouplingStructuredMesh::BuildExplicitIdsFrom;
+%newobject ParaMEDMEM::MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom;
%newobject ParaMEDMEM::MEDCouplingStructuredMesh::Build1GTNodalConnectivity;
%newobject ParaMEDMEM::MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh;
%newobject ParaMEDMEM::MEDCouplingCMesh::New;
%newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::getFather;
%newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::getPatch;
%newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::createCellFieldOnPatch;
+%newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::findPatchesInTheNeighborhoodOf;
%newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::__getitem__;
%newobject ParaMEDMEM::DenseMatrix::New;
%newobject ParaMEDMEM::DenseMatrix::deepCpy;
return MEDCouplingStructuredMesh::BuildExplicitIdsFrom(tmp5,inp);
}
+ static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector<int>& st, const DataArrayDouble *fieldOfDbl, PyObject *partCompactFormat) throw(INTERP_KERNEL::Exception)
+ {
+ std::vector< std::pair<int,int> > inp;
+ convertPyToVectorPairInt(partCompactFormat,inp);
+ return MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,fieldOfDbl,inp);
+ }
+
static int DeduceNumberOfGivenRangeInCompactFrmt(PyObject *part) throw(INTERP_KERNEL::Exception)
{
std::vector< std::pair<int,int> > inp;
int getNumberOfCellsRecursiveWithoutOverlap() const throw(INTERP_KERNEL::Exception);
int getMaxNumberOfLevelsRelativeToThis() const throw(INTERP_KERNEL::Exception);
int getNumberOfOverlapedCellsForFather() const throw(INTERP_KERNEL::Exception);
+ bool isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const throw(INTERP_KERNEL::Exception);
%extend
{
PyObject *getBLTRRange() const throw(INTERP_KERNEL::Exception)
int getNumberOfCellsAtCurrentLevel() const throw(INTERP_KERNEL::Exception);
int getNumberOfCellsRecursiveWithOverlap() const throw(INTERP_KERNEL::Exception);
int getNumberOfCellsRecursiveWithoutOverlap() const throw(INTERP_KERNEL::Exception);
+ bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const throw(INTERP_KERNEL::Exception);
//
int getNumberOfPatches() const throw(INTERP_KERNEL::Exception);
MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception);
void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors) throw(INTERP_KERNEL::Exception);
DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception);
void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const throw(INTERP_KERNEL::Exception);
+ void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const throw(INTERP_KERNEL::Exception);
void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception);
+ void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const throw(INTERP_KERNEL::Exception);
+ DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception);
%extend
{
static MEDCouplingCartesianAMRMesh *New(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception)