Version: 9.12.0
MEDCoupling::OverlapDEC Class Reference
Inheritance diagram for MEDCoupling::OverlapDEC:
Collaboration diagram for MEDCoupling::OverlapDEC:

Public Member Functions

void attachSourceLocalField (ICoCo::MEDDoubleField *field)
 
void attachSourceLocalField (MEDCouplingFieldDouble *field)
 
void attachSourceLocalField (ParaFIELD *field, bool ownPt=false)
 
void attachTargetLocalField (ICoCo::MEDDoubleField *field)
 
void attachTargetLocalField (MEDCouplingFieldDouble *field)
 
void attachTargetLocalField (ParaFIELD *field, bool ownPt=false)
 
void debugPrintWorkSharing (std::ostream &ostr) const
 
ProcessorGroupgetGroup ()
 
bool isInGroup () const
 
 OverlapDEC (const std::set< int > &procIds, const MPI_Comm &world_comm=MPI_COMM_WORLD)
 
void recvData ()
 
void release ()
 
void sendData ()
 
void sendRecvData (bool way=true)
 
void setDefaultValue (double val)
 
void setWorkSharingAlgo (int method)
 
void synchronize ()
 
virtual ~OverlapDEC ()
 
- Public Member Functions inherited from MEDCoupling::DEC
void copyFrom (const DEC &other)
 
 DEC ()
 
virtual ~DEC ()
 
- Public Member Functions inherited from MEDCoupling::DECOptions
 DECOptions ()
 
 DECOptions (const DECOptions &deco)
 
AllToAllMethod getAllToAllMethod () const
 
bool getAsynchronous () const
 
bool getForcedRenormalization () const
 
const std::string & getMethod () const
 
TimeInterpolationMethod getTimeInterpolationMethod () const
 
void setAllToAllMethod (AllToAllMethod sp)
 
void setAsynchronous (bool dr)
 
void setForcedRenormalization (bool dr)
 
void setMethod (const char *m)
 
void setTimeInterpolationMethod (TimeInterpolationMethod it)
 
- Public Member Functions inherited from INTERP_KERNEL::InterpolationOptions
void copyOptions (const InterpolationOptions &other)
 
std::string filterInterpolationMethod (const std::string &meth) const
 
double getBoundingBoxAdjustment () const
 
double getBoundingBoxAdjustmentAbs () const
 
bool getDoRotate () const
 
IntersectionType getIntersectionType () const
 
std::string getIntersectionTypeRepr () const
 
double getMaxDistance3DSurfIntersect () const
 
bool getMeasureAbsStatus () const
 
double getMedianPlane () const
 
double getMinDotBtwPlane3DSurfIntersect () const
 
int getOrientation () const
 
double getPrecision () const
 
int getPrintLevel () const
 
SplittingPolicy getSplittingPolicy () const
 
std::string getSplittingPolicyRepr () const
 
void init ()
 
 InterpolationOptions ()
 
std::string printOptions () const
 
void setBoundingBoxAdjustment (double bba)
 
void setBoundingBoxAdjustmentAbs (double bba)
 
void setDoRotate (bool dr)
 
bool setInterpolationOptions (int print_level, std::string intersection_type, double precision, double median_plane, bool do_rotate, double bounding_box_adjustment, double bounding_box_adjustment_abs, double max_distance_for_3Dsurf_intersect, int orientation, bool measure_abs, std::string splitting_policy)
 
void setIntersectionType (IntersectionType it)
 
void setMaxDistance3DSurfIntersect (double bba)
 
void setMeasureAbsStatus (bool newStatus)
 
void setMedianPlane (double mp)
 
void setMinDotBtwPlane3DSurfIntersect (double v)
 
bool setOptionDouble (const std::string &key, double value)
 
bool setOptionInt (const std::string &key, int value)
 
bool setOptionString (const std::string &key, const std::string &value)
 
void setOrientation (int o)
 
void setPrecision (double p)
 
void setPrintLevel (int pl)
 
void setSplittingPolicy (SplittingPolicy sp)
 

Additional Inherited Members

- Static Public Member Functions inherited from INTERP_KERNEL::InterpolationOptions
static void CheckAndSplitInterpolationMethod (const std::string &method, std::string &srcMeth, std::string &trgMeth)
 
- Static Public Attributes inherited from INTERP_KERNEL::InterpolationOptions
static const char BARYCENTRIC_INTERSECT_STR [] ="Barycentric"
 
static const char BARYCENTRICGEO2D_INTERSECT_STR [] ="BarycentricGeo2D"
 
static const char BOUNDING_BOX_ADJ_ABS_STR [] ="BoundingBoxAdjustmentAbs"
 
static const char BOUNDING_BOX_ADJ_STR [] ="BoundingBoxAdjustment"
 
static const char CONVEX_INTERSECT2D_STR [] ="Convex"
 
static const char DO_ROTATE_STR [] ="DoRotate"
 
static const char GENERAL_SPLIT_24_STR [] ="GENERAL_24"
 
static const char GENERAL_SPLIT_48_STR [] ="GENERAL_48"
 
static const char GEOMETRIC_INTERSECT2D_STR [] ="Geometric2D"
 
static const char INTERSEC_TYPE_STR [] ="IntersectionType"
 
static const char MAX_DISTANCE_3DSURF_INSECT_STR [] ="MaxDistance3DSurfIntersect"
 
static const char MEASURE_ABS_STR [] ="MeasureAbs"
 
static const char MEDIANE_PLANE_STR [] ="MedianPlane"
 
static const char MIN_DOT_BTW_3DSURF_INSECT_STR [] ="MinDotBetween3DSurfIntersect"
 
static const char ORIENTATION_STR [] ="Orientation"
 
static const char PLANAR_SPLIT_FACE_5_STR [] ="PLANAR_FACE_5"
 
static const char PLANAR_SPLIT_FACE_6_STR [] ="PLANAR_FACE_6"
 
static const char POINTLOCATOR_INTERSECT_STR [] ="PointLocator"
 
static const char PRECISION_STR [] ="Precision"
 
static const char PRINT_LEV_STR [] ="PrintLevel"
 
static const char SPLITTING_POLICY_STR [] ="SplittingPolicy"
 
static const char TRIANGULATION_INTERSECT2D_STR [] ="Triangulation"
 
- Protected Attributes inherited from MEDCoupling::DEC
const CommInterface_comm_interface
 
- Protected Attributes inherited from MEDCoupling::DECOptions
AllToAllMethod _allToAllMethod
 
bool _asynchronous
 
bool _forcedRenormalization
 
std::string _method
 
TimeInterpolationMethod _timeInterpolationMethod
 

Detailed Description

Overview

The OverlapDEC enables the conservative remapping of fields between two parallel codes. This remapping is based on the computation of intersection volumes on a single processor group. On this processor group are defined two field-templates called A and B. The computation is possible for 3D meshes, 2D meshes, 3D-surface meshes, 1D meshes and 2D-curve meshes. Dimensions must be similar for the distribution templates A and B.

The main difference with InterpKernelDEC is that this DEC works with a single processor group, in which processors will share the work. Consequently each processor manages two field templates (A and B) called source and target. Furthermore all processors in the processor group cooperate in the global interpolation matrix computation. In this respect InterpKernelDEC is a specialization of OverlapDEC.

Algorithm description

Let's consider the following use case that is ran in ParaMEDMEMTest_OverlapDEC.cxx to describes the different steps of the computation. The processor group contains 3 processors.

Example split of the source and target mesh among the 3 procs

Step 1 : Bounding box exchange and global interaction between procs computation.

In order to reduce as much as possible the amount of communications between distant processors, every processor computes a bounding box for A and B. Then a AllToAll communication is performed so that every processor can compute the global interactions between processor. This computation leads every processor to compute the same global TODO list expressed as a list of pair. A pair ( x, y ) means that proc x fieldtemplate A can interact with fieltemplate B of proc y because the two bounding boxes interact. In the example above this computation leads to the following a global TODO list :

(0,0),(0,1),(1,0),(1,2),(2,0),(2,1),(2,2)

Here the pair (0,2) does not appear because the bounding box of fieldtemplateA of proc#2 does not intersect that of fieldtemplate B on proc#0.

Stage performed by MEDCoupling::OverlapElementLocator::computeBoundingBoxes.

Step 2 : Computation of local TODO list

Starting from the global interaction previously computed in Step 1, each proc computes the TODO list per proc. The following rules is chosen : a pair (x,y) can be treated by either proc #x or proc #y, in order to reduce the amount of data transfers among processors. The algorithm chosen for load balancing is the following : Each processor has an empty local TODO list at the beginning. Then for each pair (k,m) in global TODO list, if proc#k has less temporary local list than proc#m pair, (k,m) is added to temporary local TODO list of proc#k. If proc#m has less temporary local TODO list than proc#k pair, (k,m) is added to temporary local TODO list of proc#m. If proc#k and proc#m have the same amount of temporary local TODO list pair, (k,m) is added to temporary local TODO list of proc#k.

In the example above this computation leads to the following local TODO list :

  • proc#0 : (0,0)
  • proc#1 : (0,1),(1,0)
  • proc#2 : (1,2),(2,0),(2,1),(2,2)

The algorithm described here is not perfect for this use case, we hope to enhance it soon.

At this stage each proc knows precisely its local TODO list (with regard to interpolation). The local TODO list of other procs than local is kept for future computations.

Step 3 : Matrix echange between procs

Knowing the local TODO list, the aim now is to exchange field-templates between procs. Each proc computes knowing TODO list per proc computed in Step 2 the exchange TODO list :

In the example above the exchange TODO list gives the following results :

Sending TODO list per proc :

  • proc #0 : Send fieldtemplate A to Proc#1, Send fieldtemplate B to Proc#1, Send fieldtemplate B to Proc#2
  • Proc #1 : Send fieldtemplate A to Proc#2, Send fieldtemplate B to Proc#2
  • Proc #2 : No send.

Receiving TODO list per proc :

  • proc #0 : No receiving
  • proc #1 : receiving fieldtemplate A from Proc#0, receiving fieldtemplate B from Proc#0
  • proc #2 : receiving fieldtemplate B from Proc#0, receiving fieldtemplate A from Proc#1, receiving fieldtemplate B from Proc#1

To avoid as much as possible large volumes of transfers between procs, only relevant parts of meshes are sent. In order for proc#k to send fieldtemplate A to fieldtemplate B of proc #m., proc#k computes the part of mesh A contained in the boundingbox B of proc#m. It implies that the corresponding cellIds or nodeIds of the corresponding part are sent to proc #m too.

Let's consider the couple (k,m) in the TODO list. This couple is treated by either k or m as seen in here in Step2.

As will be dealt in Step 6, for final matrix-vector computations, the resulting matrix of the couple (k,m) wherever it is computed (proc #k or proc #m) will be stored in proc#m.

  • If proc #k is in charge (performs the matrix computation) for this couple (k,m), target ids (cells or nodes) of the mesh in proc #m are renumbered, because proc #m has seelected a sub mesh of the target mesh to avoid large amounts of data to transfer. In this case as proc #m is ultimately in charge of the matrix, proc #k must keep preciously the source ids needed to be sent to proc#m. No problem will appear for matrix assembling in proc m for source ids because no restriction was done. Concerning source ids to be sent for the matrix-vector computation, proc k will know precisely which source ids field values to send to proc #m. This is embodied by OverlapMapping::keepTracksOfTargetIds in proc m.
  • If proc #m is in charge (performs matrix computation) for this couple (k,m), source ids (cells or nodes) of the mesh in proc #k are renumbered, because proc #k has selected a sub mesh of the source mesh to avoid large amounts of data to transfer. In this case as proc #k is ultimately in charge of the matrix, proc #m receives the source ids from remote proc #k, and thus the matrix is directly correct, no need for renumbering as in Step 5. However proc #k must keep track of the ids sent to proc #m for the matrix-vector computation. This is incarnated by OverlapMapping::keepTracksOfSourceIds in proc k.

This step is performed in MEDCoupling::OverlapElementLocator::exchangeMeshes method.

Step 4 : Computation of the interpolation matrix

After mesh exchange in Step3 each processor has all the required information to treat its local TODO list computed in Step2. This step is potentially CPU costly, which is why the local TODO list per proc is expected to be as well balanced as possible.

The interpolation is performed as the remapper does.

This operation is performed by OverlapInterpolationMatrix::addContribution method.

Step 5 : Global matrix construction.

After having performed the TODO list at the end of Step4 we need to assemble the final matrix.

The final aim is to have a distributed matrix $ M_k $ on each proc#k. In order to reduce data exchange during the matrix product process, $ M_k $ is built using sizeof(Proc group) std::vector< std::map<int,double> >.

For a proc#k, it is necessary to fetch info of all matrices built in Step4 where the first element in pair (i,j) is equal to k.

After this step, the matrix repartition is the following after a call to MEDCoupling::OverlapMapping::prepare :

  • proc#0 : (0,0),(1,0),(2,0)
  • proc#1 : (0,1),(2,1)
  • proc#2 : (1,2),(2,2)

Tuple (2,1) computed on proc 2 is stored in proc 1 after execution of the function "prepare". This is an example of item 0 in Step2. Tuple (0,1) computed on proc 1 is stored in proc 1 too. This is an example of item 1 in Step2.

In the end MEDCoupling::OverlapMapping::_proc_ids_to_send_vector_st will contain :

  • Proc#0 : 0,1
  • Proc#1 : 0,2
  • Proc#2 : 0,1,2

In the end MEDCoupling::OverlapMapping::_proc_ids_to_recv_vector_st will contain :

  • Proc#0 : 0,1,2
  • Proc#1 : 0,2
  • Proc#2 : 1,2

The method in charge to perform this is : MEDCoupling::OverlapMapping::prepare.

Constructor & Destructor Documentation

◆ OverlapDEC()

MEDCoupling::OverlapDEC::OverlapDEC ( const std::set< int > &  procIds,
const MPI_Comm &  world_comm = MPI_COMM_WORLD 
)

◆ ~OverlapDEC()

MEDCoupling::OverlapDEC::~OverlapDEC ( )
virtual

References release().

Member Function Documentation

◆ release()

void MEDCoupling::OverlapDEC::release ( )

Destructor involves MPI operations: make sure this is accessible from a proper method for Python wrapping.

References MEDCoupling::CommInterface::commFree().

Referenced by ~OverlapDEC().

◆ sendRecvData()

void MEDCoupling::OverlapDEC::sendRecvData ( bool  way = true)
virtual

Implements MEDCoupling::DEC.

References recvData(), and sendData().

◆ sendData()

void MEDCoupling::OverlapDEC::sendData ( )

Referenced by sendRecvData().

◆ recvData()

void MEDCoupling::OverlapDEC::recvData ( )

Referenced by sendRecvData().

◆ synchronize()

◆ attachSourceLocalField() [1/3]

void MEDCoupling::OverlapDEC::attachSourceLocalField ( ParaFIELD field,
bool  ownPt = false 
)

References isInGroup().

Referenced by attachSourceLocalField().

◆ attachTargetLocalField() [1/3]

void MEDCoupling::OverlapDEC::attachTargetLocalField ( ParaFIELD field,
bool  ownPt = false 
)

References isInGroup().

Referenced by attachTargetLocalField().

◆ attachSourceLocalField() [2/3]

◆ attachTargetLocalField() [2/3]

◆ attachSourceLocalField() [3/3]

void MEDCoupling::OverlapDEC::attachSourceLocalField ( ICoCo::MEDDoubleField field)

◆ attachTargetLocalField() [3/3]

void MEDCoupling::OverlapDEC::attachTargetLocalField ( ICoCo::MEDDoubleField field)

◆ getGroup()

ProcessorGroup* MEDCoupling::OverlapDEC::getGroup ( )

◆ isInGroup()

bool MEDCoupling::OverlapDEC::isInGroup ( ) const

◆ setDefaultValue()

void MEDCoupling::OverlapDEC::setDefaultValue ( double  val)

◆ setWorkSharingAlgo()

void MEDCoupling::OverlapDEC::setWorkSharingAlgo ( int  method)

0 means initial algo from Antho, 1 or 2 means Adrien's algo (2 should be better). Make your choice :-))

◆ debugPrintWorkSharing()

void MEDCoupling::OverlapDEC::debugPrintWorkSharing ( std::ostream &  ostr) const