// Author : Anthony Geay
#include "MEDCouplingCartesianAMRMesh.hxx"
+#include "MEDCoupling1GTUMesh.hxx"
#include "MEDCouplingIMesh.hxx"
#include "MEDCouplingUMesh.hxx"
#include <limits>
#include <sstream>
+#include <numeric>
using namespace ParaMEDMEM;
int getNumberOfCells() const { return (int)_crit.size(); }
void setNumberOfTrue(int nboft) { _nb_of_true=nboft; }
std::vector<bool>& getCriterion() { return _crit; }
+ const std::vector<bool>& getConstCriterion() const { return _crit; }
+ void setPart(const std::vector< std::pair<int,int> >& part) { _part=part; }
std::vector< std::pair<int,int> >& getPart() { return _part; }
const std::vector< std::pair<int,int> >& getConstPart() const { return _part; }
bool presenceOfTrue() const { return _nb_of_true>0; }
+ std::vector<int> computeCGS() const { return MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(_part); }
+ std::vector< std::vector<int> > computeSignature() const { return MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(computeCGS(),getConstCriterion()); }
+ double getEfficiencyPerAxis(int axisId) const { return (double)_nb_of_true/((double)(_part[axisId].second-_part[axisId].first)); }
+ void zipToFitOnCriterion();
+ void updateNumberOfTrue() const;
+ MEDCouplingAutoRefCountObjectPtr<InternalPatch> extractPart(const std::vector< std::pair<int,int> >&partInGlobal) const;
+ MEDCouplingAutoRefCountObjectPtr<InternalPatch> deepCpy() const;
protected:
~InternalPatch() { }
private:
- int _nb_of_true;
+ mutable int _nb_of_true;
std::vector<bool> _crit;
+ //! _part is global
std::vector< std::pair<int,int> > _part;
};
-#if 0
-void dissectBigPatch (const Mesh& mesh, const Field& fieldFlag, const unsigned int minCellDirection,
- const unsigned int big_dims, const int dissect_direction, int cut[3] ) const
+void InternalPatch::zipToFitOnCriterion()
{
- int cut_found = 0 ;
- int cut_place = -1 ;
- float * ratio = NULL ;
- float * ratio_inner = NULL ;
+ std::vector<int> cgs(computeCGS());
+ std::vector<bool> newCrit;
+ std::vector< std::pair<int,int> > newPart,newPart2;
+ int newNbOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(cgs,_crit,newCrit,newPart));
+ MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(_part,newPart,newPart2);
+ if(newNbOfTrue!=_nb_of_true)
+ throw INTERP_KERNEL::Exception("InternalPatch::zipToFitOnCrit : internal error !");
+ _crit=newCrit; _part=newPart2;
+}
+
+void InternalPatch::updateNumberOfTrue() const
+{
+ _nb_of_true=(int)std::count(_crit.begin(),_crit.end(),true);
+}
+
+MEDCouplingAutoRefCountObjectPtr<InternalPatch> InternalPatch::extractPart(const std::vector< std::pair<int,int> >&partInGlobal) const
+{
+ MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(new InternalPatch);
+ std::vector<int> cgs(computeCGS());
+ std::vector< std::pair<int,int> > newPart;
+ MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(_part,partInGlobal,newPart);
+ MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom(cgs,_crit,newPart,ret->getCriterion());
+ ret->setPart(partInGlobal);
+ ret->updateNumberOfTrue();
+ return ret;
+}
+
+MEDCouplingAutoRefCountObjectPtr<InternalPatch> InternalPatch::deepCpy() const
+{
+ MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(new InternalPatch);
+ (*ret)=*this;
+ return ret;
+}
- ratio = new float [big_dims-1];
- for(unsigned int id=0; id<big_dims-1; id++)
+void DissectBigPatch(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, bool& cutFound, int& cutPlace)
+{
+ cutFound=false; cutPlace=-1;
+ std::vector<double> ratio(rangeOfAxisId-1);
+ for(int id=0;id<rangeOfAxisId-1;id++)
{
- float efficiency[2] ;
- for(int h=0; h<2; h++)
+ double efficiency[2];
+ for(int h=0;h<2;h++)
{
- int rect_h[4] ;
- copy(getIndexCorners(),getIndexCorners()+4,rect_h) ;
- if (h == 0 )
- rect_h[dissect_direction+2] = _indexCorners[dissect_direction]+id ;
- else if ( h == 1)
- rect_h[dissect_direction] = _indexCorners[dissect_direction]+id+1;
-
- Patch patch_h(rect_h);
- patch_h.computeMesh(mesh);
- patch_h.computeFieldFlag(fieldFlag);
-
- int nb_cells_h ;
- if ( dissect_direction == 0 )
- nb_cells_h = patch_h.getNx() ;
+ std::vector< std::pair<int,int> > rectH(patchToBeSplit->getConstPart());
+ if(h==0)
+ rectH[axisId].second=patchToBeSplit->getConstPart()[axisId].first+id;
else
- nb_cells_h = patch_h.getNy() ;
+ rectH[axisId].first=patchToBeSplit->getConstPart()[axisId].first+id;
+ MEDCouplingAutoRefCountObjectPtr<InternalPatch> p(patchToBeSplit->deepCpy());
+ p->zipToFitOnCriterion();
+ //anouar rectH ?
+ efficiency[h]=p->getEfficiencyPerAxis(axisId);
+ }
+ ratio[id]=std::max(efficiency[0],efficiency[1])/std::min(efficiency[0],efficiency[1]);
+ }
+ int minCellDirection(bso.getMinCellDirection()),indexMin(-1);
+ int dimRatioInner(rangeOfAxisId-1-2*(minCellDirection-1));
+ std::vector<double > ratio_inner(dimRatioInner);
+ double minRatio(1.e10);
+ for(int i=0; i<dimRatioInner; i++)
+ {
+ if(ratio[minCellDirection-1+i]<minRatio)
+ {
+ minRatio=ratio[minCellDirection-1+i];
+ indexMin=i+minCellDirection;
+ }
+ }
+ cutFound=true; cutPlace=indexMin+patchToBeSplit->getConstPart()[axisId].first-1;
+}
- int nb_cells_flag_h = patch_h.getNumberOfCellsFlags();
- efficiency[h] = float (nb_cells_flag_h) / float(nb_cells_h) ;
+void FindHole(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, const int axisId, bool& cutFound, int& cutPlace)
+{
+ cutPlace=-1; cutFound=false;
+ int minCellDirection(bso.getMinCellDirection());
+
+ int sortedDims[2];
+ sortedDims[0]=axisId==0?1:0;
+ sortedDims[1]=axisId==0?0:1;
+ static const int dim(2);
+ std::vector< std::vector<int> > signatures(patchToBeSplit->computeSignature());
+ for(int id=0;id<dim;id++)
+ {
+ const std::vector<int>& signature(signatures[sortedDims[id]]);
+ std::vector<int> hole;
+ std::vector<double> distance ;
+ int len((int)signature.size());
+ for(int i=0;i<len;i++)
+ if(signature[i]==0)
+ if(len>= 2*minCellDirection && i >= minCellDirection-1 && i <= len-minCellDirection-1)
+ hole.push_back(i);
+ if (hole.size()>0)
+ {
+ double center(((double)len/2.)+0.5);
+ for(std::size_t i=0;i<hole.size();i++)
+ distance.push_back(fabs(hole[i]+1+0.5-center));//anouar ! why 0.5 ?
+
+ double distanceMin=*std::min_element(distance.begin(),distance.end());
+ int posDistanceMin=std::find(distance.begin(),distance.end(),distanceMin)-distance.begin()-1;
+
+ cutFound=true;
+ cutPlace=hole[posDistanceMin]+patchToBeSplit->getConstPart()[axisId].first+1;
+ return ;
}
- ratio[id] = max(efficiency[0],efficiency[1])/
- min(efficiency[0],efficiency[1]) ;
}
+}
+
+void FindInflection(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, bool& cutFound, int& cutPlace, int& axisId)
+{
+ cutFound=false; cutPlace=-1; axisId=-1;
- int dim_ratio_inner = big_dims-1-2*(minCellDirection-1) ;
- ratio_inner = new float [dim_ratio_inner];
- float min_ratio = 1.E10 ;
- int index_min = -1 ;
- for(int i=0; i<dim_ratio_inner; i++)
+ const std::vector< std::pair<int,int> >& part(patchToBeSplit->getConstPart());
+ int sign,minCellDirection(bso.getMinCellDirection());
+ static const int dim = 2 ;
+
+ std::vector<int> zeroCrossDims(2,-1);
+ std::vector<int> zeroCrossVals(2,-1);
+ std::vector< std::vector<int> > signatures(patchToBeSplit->computeSignature());
+ for (int id=0;id<dim;id++)
{
- if ( ratio[minCellDirection-1+i] < min_ratio )
+ const std::vector<int>& signature(signatures[id]);
+
+ std::vector<int> derivate_second_order,gradient_absolute,signe_change,zero_cross,edge,max_cross_list ;
+ std::vector<double> distance ;
+
+ for (unsigned int i=1;i<signature.size()-1;i++)
+ derivate_second_order.push_back(signature[i-1]-2*signature[i]+signature[i+1]) ;
+
+ // Gradient absolute value
+ for ( unsigned int i=1;i<derivate_second_order.size();i++)
+ gradient_absolute.push_back(fabs(derivate_second_order[i]-derivate_second_order[i-1])) ;
+ for (unsigned int i=0;i<derivate_second_order.size()-1;i++)
{
- min_ratio = ratio[minCellDirection-1+i] ;
- index_min = i+minCellDirection ;
+ if (derivate_second_order[i]*derivate_second_order[i+1] < 0 )
+ sign = -1 ;
+ if (derivate_second_order[i]*derivate_second_order[i+1] > 0 )
+ sign = 1 ;
+ if (derivate_second_order[i]*derivate_second_order[i+1] == 0 )
+ sign = 0 ;
+ if ( sign==0 || sign==-1 )
+ if ( i >= (unsigned int)minCellDirection-2 && i <= signature.size()-minCellDirection-2 )
+ {
+ zero_cross.push_back(i) ;
+ edge.push_back(gradient_absolute[i]) ;
+ }
+ signe_change.push_back(sign) ;
}
+ if ( zero_cross.size() > 0 )
+ {
+ int max_cross=*max_element(edge.begin(),edge.end()) ;
+ for (unsigned int i=0;i<edge.size();i++)
+ if (edge[i]==max_cross)
+ max_cross_list.push_back(zero_cross[i]+1) ;
+
+ float center = (signature.size()/2.0)+0.5;
+ for (unsigned int i=0;i<max_cross_list.size();i++)
+ distance.push_back(fabs(max_cross_list[i]+1+0.5-center));
+
+ float distance_min=*min_element(distance.begin(),distance.end()) ;
+ int pos_distance_min=find(distance.begin(),distance.end(),distance_min)-distance.begin();
+ int best_place = max_cross_list[pos_distance_min] + part[id].first ;
+ if ( max_cross >=0 )
+ {
+ zeroCrossDims[id] = best_place ;
+ zeroCrossVals[id] = max_cross ;
+ }
+ }
+ derivate_second_order.clear() ;
+ gradient_absolute.clear() ;
+ signe_change.clear() ;
+ zero_cross.clear() ;
+ edge.clear() ;
+ max_cross_list.clear() ;
+ distance.clear() ;
}
- cut_found = 1 ;
- cut_place = index_min + _indexCorners[dissect_direction] - 1 ;
- cut[0] = cut_found ;
- cut[1] = cut_place ;
- cut[2] = dissect_direction ;
- delete [] ratio ;
- delete [] ratio_inner ;
-}
-#endif
+
+ if ( zeroCrossDims[0]!=-1 || zeroCrossDims[1]!=-1 )
+ {
+ int max_cross_dims = *max_element(zeroCrossVals.begin(),zeroCrossVals.end()) ;
+
+ if (zeroCrossVals[0]==max_cross_dims && zeroCrossVals[1]==max_cross_dims )
+ {
+ int nl_left(part[0].second-part[0].first);
+ int nc_left(part[1].second-part[1].first);
+ if ( nl_left >= nc_left )
+ max_cross_dims = 0 ;
+ else
+ max_cross_dims = 1 ;
+ }
+ else
+ max_cross_dims=std::find(zeroCrossVals.begin(),zeroCrossVals.end(),max_cross_dims)-zeroCrossVals.begin();
+ cutFound=true;
+ cutPlace=zeroCrossDims[max_cross_dims];
+ axisId=max_cross_dims ;
+ }
+}
+
+void TryAction4(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, bool& cutFound, int& cutPlace)
+{
+ cutFound=false;
+ if(patchToBeSplit->getEfficiency() <= bso.getEffeciencySnd())
+ {
+ if(rangeOfAxisId>=2*bso.getMinCellDirection())
+ {
+ cutFound=true;
+ cutPlace=rangeOfAxisId/2+patchToBeSplit->getConstPart()[axisId].first-1;
+ }
+ }
+ else
+ {
+ if(patchToBeSplit->getNumberOfCells()>bso.getMaxCells())
+ {
+ DissectBigPatch(bso,patchToBeSplit,axisId,rangeOfAxisId,cutFound,cutPlace);
+ }
+ }
+}
+
+MEDCouplingAutoRefCountObjectPtr<InternalPatch> DealWithNoCut(const InternalPatch *patch)
+{
+ MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(const_cast<InternalPatch *>(patch));
+ ret->incrRef();
+ return ret;
+}
+
+void DealWithCut(const InternalPatch *patchToBeSplit, int axisId, int cutPlace, std::vector<MEDCouplingAutoRefCountObjectPtr<InternalPatch> >& listOfPatches)
+{
+ MEDCouplingAutoRefCountObjectPtr<InternalPatch> leftPart,rightPart;
+ std::vector< std::pair<int,int> > rect(patchToBeSplit->getConstPart());
+ std::vector< std::pair<int,int> > leftRect(rect),rightRect(rect);
+ leftRect[axisId].second=cutPlace+1;
+ rightRect[axisId].first=cutPlace+1;
+ leftPart=patchToBeSplit->extractPart(leftRect);
+ rightPart=patchToBeSplit->extractPart(rightRect);
+ leftPart->zipToFitOnCriterion(); rightPart->zipToFitOnCriterion();
+ listOfPatches.push_back(leftPart);
+ listOfPatches.push_back(rightPart);
+}
+
/// @endcond
/*!
- * This method creates patches in \a this (by destroying the patches if any). This method uses \a criterion
+ * This method creates patches in \a this (by destroying the patches if any). This method uses \a criterion array as a field on cells on this level.
*/
void MEDCouplingCartesianAMRMesh::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors)
{
for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::iterator it=listOfPatches.begin();it!=listOfPatches.end();it++)
{
//
- if((*it)->getEfficiency()>=bso.getEffeciency())
- {
- if((*it)->getNumberOfCells()>=bso.getMaxCells())
- {
-
- }
- }
+ int axisId,rangeOfAxisId;
+ bool cutFound;
+ int cutPlace;
+ MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt((*it)->getConstPart(),axisId,rangeOfAxisId);
+ if((*it)->getEfficiency()>=bso.getEffeciency() && (*it)->getNumberOfCells()<bso.getMaxCells())
+ { listOfPatchesOK.push_back(DealWithNoCut(*it)); continue; }//action 1
+ FindHole(bso,*it,axisId,cutFound,cutPlace);
+ if(cutFound)
+ { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 2
+ FindInflection(bso,*it,cutFound,cutPlace,axisId);//axisId overwritten here if cutFound equal to true !
+ if(cutFound)
+ { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 3
+ TryAction4(bso,*it,axisId,rangeOfAxisId,cutFound,cutPlace);
+ if(cutFound)
+ { DealWithCut(*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 4
+ listOfPatchesOK.push_back(DealWithNoCut(*it));
}
listOfPatches=listOfPatchesTmp;
}
return MEDCouplingUMesh::MergeUMeshes(ms);
}
+/*!
+ * This method returns a mesh containing as cells that there is patches at the current level.
+ * The patches are seen like 'boxes' that is too say the refinement will not appear here.
+ *
+ * \return MEDCoupling1SGTUMesh * - A new object to be managed by the caller containing as cells as there are patches in \a this.
+ */
+MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMesh::buildMeshFromPatchEnvelop() const
+{
+ std::vector<const MEDCoupling1SGTUMesh *> cells;
+ std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > cellsSafe;
+ for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++)
+ {
+ const MEDCouplingCartesianAMRPatch *patch(*it);
+ if(patch)
+ {
+ MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> cell(patch->getMesh()->getImageMesh()->asSingleCell());
+ MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> cell1SGT(cell->build1SGTUnstructured());
+ cellsSafe.push_back(cell1SGT); cells.push_back(cell1SGT);
+ }
+ }
+ return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(cells);
+}
+
MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop,
const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):_father(0)
{
{
if((int)crit.size()!=DeduceNumberOfGivenStructure(st))
throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : size of vector of boolean is invalid regarding the declared structure !");
+ int ret(-1);
switch((int)st.size())
{
case 1:
{
- return FindMinimalPartOf1D(st,crit,reducedCrit,partCompactFormat);
+ ret=FindMinimalPartOf1D(st,crit,partCompactFormat);
break;
}
case 2:
{
- return FindMinimalPartOf2D(st,crit,reducedCrit,partCompactFormat);
+ ret=FindMinimalPartOf2D(st,crit,partCompactFormat);
break;
}
case 3:
{
- return FindMinimalPartOf3D(st,crit,reducedCrit,partCompactFormat);
+ ret=FindMinimalPartOf3D(st,crit,partCompactFormat);
break;
}
default:
throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : only dimension 1, 2 and 3 are supported actually !");
}
+ ExtractFieldOfBoolFrom(st,crit,partCompactFormat,reducedCrit);
+ return ret;
+}
+
+/*!
+ * This method is \b NOT wrapped in python.
+ * This method considers \a crit input parameter as a matrix having dimensions specified by \a st. This method returns for each axis
+ * the signature, that is to say the number of elems equal to true in \a crit along this axis.
+ */
+std::vector< std::vector<int> > MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(const std::vector<int>& st, const std::vector<bool>& crit)
+{
+ int dim((int)st.size());
+ std::vector< std::vector<int> > ret(dim);
+ switch(dim)
+ {
+ case 1:
+ {
+ int nx(st[0]);
+ ret[0].resize(nx);
+ std::vector<int>& retX(ret[0]);
+ for(int i=0;i<nx;i++)
+ retX[i]=crit[i]?1:0;
+ break;
+ }
+ case 2:
+ {
+ int nx(st[0]),ny(st[1]);
+ ret[0].resize(nx); ret[1].resize(ny);
+ std::vector<int>& retX(ret[0]);
+ for(int i=0;i<nx;i++)
+ {
+ int cnt(0);
+ for(int j=0;j<ny;j++)
+ if(crit[j*nx+i])
+ cnt++;
+ retX[i]=cnt;
+ }
+ std::vector<int>& retY(ret[1]);
+ for(int j=0;j<ny;j++)
+ {
+ int cnt(0);
+ for(int i=0;i<nx;i++)
+ if(crit[j*nx+i])
+ cnt++;
+ retY[j]=cnt;
+ }
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeSignatureOf : only dimensions 1, 2 are supported !");
+ }
+ return ret;
}
DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity1D(const int *nodeStBg)
/*!
* \sa MEDCouplingStructuredMesh::FindMinimalPartOf
*/
-int MEDCouplingStructuredMesh::FindMinimalPartOf1D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat)
+int MEDCouplingStructuredMesh::FindMinimalPartOf1D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector< std::pair<int,int> >& partCompactFormat)
{
if(st.size()!=1)
throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf1D : the input size of st must be equal to 1 !");
return ret;
partCompactFormat.resize(1);
partCompactFormat[0].first=nxMin; partCompactFormat[0].second=nxMax+1;
- ExtractVecOfBool(st,crit,partCompactFormat,reducedCrit);
return ret;
}
/*!
* \sa MEDCouplingStructuredMesh::FindMinimalPartOf
*/
-int MEDCouplingStructuredMesh::FindMinimalPartOf2D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat)
+int MEDCouplingStructuredMesh::FindMinimalPartOf2D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector< std::pair<int,int> >& partCompactFormat)
{
if(st.size()!=2)
throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf2D : the input size of st must be equal to 2 !");
partCompactFormat.resize(2);
partCompactFormat[0].first=nxMin; partCompactFormat[0].second=nxMax+1;
partCompactFormat[1].first=nyMin; partCompactFormat[1].second=nyMax+1;
- ExtractVecOfBool(st,crit,partCompactFormat,reducedCrit);
return ret;
}
/*!
* \sa MEDCouplingStructuredMesh::FindMinimalPartOf
*/
-int MEDCouplingStructuredMesh::FindMinimalPartOf3D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat)
+int MEDCouplingStructuredMesh::FindMinimalPartOf3D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector< std::pair<int,int> >& partCompactFormat)
{
if(st.size()!=3)
throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf3D : the input size of st must be equal to 3 !");
partCompactFormat[0].first=nxMin; partCompactFormat[0].second=nxMax+1;
partCompactFormat[1].first=nyMin; partCompactFormat[1].second=nyMax+1;
partCompactFormat[2].first=nzMin; partCompactFormat[2].second=nzMax+1;
- ExtractVecOfBool(st,crit,partCompactFormat,reducedCrit);
return ret;
}
* \param [in] partCompactFormat The compact subpart to be enabled.
* \param [in,out] vectToSwitchOn Vector which fetched items are enabled.
*
- * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom
+ * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, ExtractFieldOfBoolFrom
*/
void MEDCouplingStructuredMesh::SwitchOnIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& vectToSwitchOn)
{
break;
}
default:
- throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : Dimension supported are 1,2 or 3 !");
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : Dimension supported are 1,2 or 3 !");
+ }
+}
+
+/*!
+ * Obviously this method is \b NOT wrapped in python.
+ * This method is close to SwitchOnIdsFrom except that here, a sub field \a fieldOut is built starting from the input field \a fieldOfBool having the structure \a st.
+ * The extraction is defined by \a partCompactFormat.
+ *
+ * \param [in] st The entity structure.
+ * \param [in] fieldOfBool field of booleans having the size equal to \c MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(st).
+ * \param [in] partCompactFormat The compact subpart to be enabled.
+ * \param [out] fieldOut the result of the extraction.
+ *
+ * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, SwitchOnIdsFrom
+ */
+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)
+{
+ if(st.size()!=partCompactFormat.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : input arrays must have the same size !");
+ if((int)fieldOfBool.size()!=DeduceNumberOfGivenStructure(st))
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : invalid size of input field of boolean regarding the structure !");
+ std::vector<int> dims(GetDimensionsFromCompactFrmt(partCompactFormat));
+ int nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims));
+ fieldOut.resize(nbOfTuplesOfOutField);
+ int it(0);
+ 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++)
+ fieldOut[it++]=fieldOfBool[partCompactFormat[0].first+k+b+a];
+ }
+ }
+ 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++)
+ fieldOut[it++]=fieldOfBool[partCompactFormat[0].first+k+b];
+ }
+ break;
+ }
+ case 1:
+ {
+ for(int k=0;k<dims[0];k++)
+ fieldOut[it++]=fieldOfBool[partCompactFormat[0].first+k];
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : Dimension supported are 1,2 or 3 !");
}
}
+/*!
+ * 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
+ */
+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)
+{
+ std::size_t dim(bigInAbs.size());
+ if(dim!=partOfBigInAbs.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : The size of parts (dimension) must be the same !");
+ partOfBigRelativeToBig.resize(dim);
+ for(std::size_t i=0;i<dim;i++)
+ {
+ if(bigInAbs[i].first>bigInAbs[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the input big part invalid, end before start !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ if(partOfBigInAbs[i].first<bigInAbs[i].first || partOfBigInAbs[i].first>=bigInAbs[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the part is not included in the big one (start) !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ partOfBigRelativeToBig[i].first=partOfBigInAbs[i].first-bigInAbs[i].first;
+ if(partOfBigInAbs[i].second<partOfBigInAbs[i].first || partOfBigInAbs[i].second>bigInAbs[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the part is not included in the big one (end) !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ partOfBigRelativeToBig[i].second=partOfBigInAbs[i].second-bigInAbs[i].first;
+ }
+}
+
+/*
+ * This method is performs the opposite reference modification than explained in ChangeReferenceFromGlobalOfCompactFrmt.
+ *
+ * \sa ChangeReferenceFromGlobalOfCompactFrmt
+ */
+void MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigRelativeToBig, std::vector< std::pair<int,int> >& partOfBigInAbs)
+{
+ std::size_t dim(bigInAbs.size());
+ if(dim!=partOfBigRelativeToBig.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : The size of parts (dimension) must be the same !");
+ partOfBigInAbs.resize(dim);
+ for(std::size_t i=0;i<dim;i++)
+ {
+ if(bigInAbs[i].first>bigInAbs[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the input big part invalid, end before start !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ if(partOfBigRelativeToBig[i].first<0 || partOfBigRelativeToBig[i].first>=bigInAbs[i].second-bigInAbs[i].first)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the start of part is not in the big one !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ partOfBigInAbs[i].first=partOfBigRelativeToBig[i].first+bigInAbs[i].first;
+ if(partOfBigRelativeToBig[i].second<partOfBigRelativeToBig[i].first || partOfBigRelativeToBig[i].second>bigInAbs[i].second-bigInAbs[i].first)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the end of part is not in the big one !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ partOfBigInAbs[i].second=partOfBigRelativeToBig[i].second+bigInAbs[i].first;
+ }
+}
+
/*!
* This method builds the explicit entity array from the structure in \a st and the range in \a partCompactFormat.
* If the range contains invalid values regarding sructure an exception will be thrown.
*
* \return DataArrayInt * - a new object.
- * \sa MEDCouplingStructuredMesh::IsPartStructured, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt, SwitchOnIdsFrom
+ * \sa MEDCouplingStructuredMesh::IsPartStructured, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt, SwitchOnIdsFrom, ExtractFieldOfBoolFrom
*/
DataArrayInt *MEDCouplingStructuredMesh::BuildExplicitIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat)
{
fine=DataArrayDouble(3*2*3*4*4*4) ; fine.iota(0) #X=3,Y=2,Z=3 refined by 4
MEDCouplingIMesh.SpreadCoarseToFine(coarse,[5,7,5],fine,[(1,4),(2,4),(1,4)],[4,4,4])
self.assertTrue(fine.isEqual(DataArrayDouble([46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.]),1e-12))
- #f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(MEDCouplingIMesh("",3,DataArrayInt([6,8,6]),[0.,0.,0.],DataArrayDouble((1.,1.,1.)))) ; f.setArray(coarse) ; f.setName("tutu") ; f.checkCoherency() ; f.writeVTK("coarse.vti")
- #f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(MEDCouplingIMesh("",3,DataArrayInt([13,9,13]),[1.,2.,1.],DataArrayDouble((0.25,0.25,0.25)))) ; f.setArray(fine) ; f.setName("tutu") ; f.checkCoherency() ; f.writeVTK("fine.vti")
+ f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(MEDCouplingIMesh("",3,DataArrayInt([6,8,6]),[0.,0.,0.],DataArrayDouble((1.,1.,1.)))) ; f.setArray(coarse) ; f.setName("tutu") ; f.checkCoherency()
+ f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(MEDCouplingIMesh("",3,DataArrayInt([13,9,13]),[1.,2.,1.],DataArrayDouble((0.25,0.25,0.25)))) ; f.setArray(fine) ; f.setName("tutu") ; f.checkCoherency()
# 1D
coarse=DataArrayDouble(5) ; coarse.iota(0) #X=5
fine=DataArrayDouble(3*4) ; fine.iota(0) #X=3 refined by 4
self.assertTrue(fine.isEqual(DataArrayDouble([1.,1.,1.,1.,2.,2.,2.,2.,3.,3.,3.,3.]),1e-12))
pass
+ def testAMR4(self):
+ """This test focuses on MEDCouplingCartesianAMRMesh.createPatchesFromCriterion method. To test it a field containing 0 everywhere except in the annulus (centered on the center of the mesh) value is 1."""
+ im=MEDCouplingIMesh("mesh",2,[51,51],[0.,0.],[0.04,0.04])
+ b=im.getBarycenterAndOwner() ; b-=[1.,1.] ; b=b.magnitude()
+ ids=b.getIdsInRange(0.4,0.7)
+ f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(im) ; f.setName("toto") ; arr=DataArrayDouble(im.getNumberOfCells()) ; arr[:]=0. ; arr[ids]=1. ; f.setArray(arr)
+ # f.write("test.vti")
+ amr=MEDCouplingCartesianAMRMesh("mesh",2,[51,51],[0.,0.],[0.04,0.04])
+ arr2=DataArrayByte(im.getNumberOfCells()) ; arr2[:]=0 ; arr2[ids]=1
+ bso=BoxSplittingOptions() ; bso.setEffeciency(0.8) ; bso.setEffeciencySnd(0.8) ; bso.setMaxCells(1000) ; bso.setMinCellDirection(3)
+ amr.createPatchesFromCriterion(bso,arr2,[2,2])
+ self.assertEqual(18,amr.getNumberOfPatches())
+ exp0=[[(8,14),(19,38)],[(19,31),(8,17)],[(19,31),(33,42)],[(10,14),(12,16)],[(9,14),(16,19)],[(14,19),(9,19)],[(14,17),(19,22)],[(14,19),(31,41)],[(36,42),(19,38)],[(14,15),(22,28)],[(14,17),(28,31)],[(31,36),(9,19)],[(33,36),(19,22)],[(31,36),(31,41)],[(36,40),(12,16)],[(36,41),(16,19)],[(35,36),(22,28)],[(33,36),(28,31)]]
+ for i,bltr in enumerate(exp0):
+ self.assertEqual(amr[i].getBLTRRange(),bltr)
+ pass
+ m=amr.buildMeshFromPatchEnvelop()
+ self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([1,0,2,3,5,4,6,7,9,8,10,11,13,12,14,15,17,16,18,19,21,20,22,23,25,24,26,27,29,28,30,31,33,32,34,35,37,36,38,39,41,40,42,43,45,44,46,47,49,48,50,51,53,52,54,55,57,56,58,59,61,60,62,63,65,64,66,67,69,68,70,71])))
+ self.assertTrue(m.getCoords().isEqualWithoutConsideringStr(DataArrayDouble([0.32,0.76,0.56,0.76,0.32,1.52,0.56,1.52,0.76,0.32,1.24,0.32,0.76,0.68,1.24,0.68,0.76,1.32,1.24,1.32,0.76,1.68,1.24,1.68,0.4,0.48,0.56,0.48,0.4,0.64,0.56,0.64,0.36,0.64,0.56,0.64,0.36,0.76,0.56,0.76,0.56,0.36,0.76,0.36,0.56,0.76,0.76,0.76,0.56,0.76,0.68,0.76,0.56,0.88,0.68,0.88,0.56,1.24,0.76,1.24,0.56,1.64,0.76,1.64,1.44,0.76,1.68,0.76,1.44,1.52,1.68,1.52,0.56,0.88,0.6,0.88,0.56,1.12,0.6,1.12,0.56,1.12,0.68,1.12,0.56,1.24,0.68,1.24,1.24,0.36,1.44,0.36,1.24,0.76,1.44,0.76,1.32,0.76,1.44,0.76,1.32,0.88,1.44,0.88,1.24,1.24,1.44,1.24,1.24,1.64,1.44,1.64,1.44,0.48,1.6,0.48,1.44,0.64,1.6,0.64,1.44,0.64,1.64,0.64,1.44,0.76,1.64,0.76,1.4,0.88,1.44,0.88,1.4,1.12,1.44,1.12,1.32,1.12,1.44,1.12,1.32,1.24,1.44,1.24],72,2),1e-12))
+ #
+ self.assertEqual(MEDCouplingStructuredMesh.ChangeReferenceToGlobalOfCompactFrmt([(8,32),(4,17)],[(0,24),(2,12)]),[(8,32),(6,16)])
+ self.assertEqual(MEDCouplingStructuredMesh.ChangeReferenceFromGlobalOfCompactFrmt([(8,32),(4,17)],[(8,32),(6,16)]),[(0,24),(2,12)])
+ pass
+
def setUp(self):
pass
pass