Back to index

salome-med  6.5.0
Functions
InterpKernelDEC

Functions

 ParaMEDMEM::InterpKernelDEC::InterpKernelDEC ()
 ParaMEDMEM::InterpKernelDEC::InterpKernelDEC (ProcessorGroup &source_group, ProcessorGroup &target_group)
 This constructor creates an InterpKernelDEC which has source_group as a working side and target_group as an idle side.
 ParaMEDMEM::InterpKernelDEC::InterpKernelDEC (const std::set< int > &src_ids, const std::set< int > &trg_ids, const MPI_Comm &world_comm=MPI_COMM_WORLD)
virtual ParaMEDMEM::InterpKernelDEC::~InterpKernelDEC ()
void ParaMEDMEM::InterpKernelDEC::synchronize ()
 Synchronization process for exchanging topologies.
void ParaMEDMEM::InterpKernelDEC::recvData ()
 Receives the data whether the processor is on the working side or on the lazy side.
void ParaMEDMEM::InterpKernelDEC::recvData (double time)
 Receives the data at time time in asynchronous mode.
void ParaMEDMEM::InterpKernelDEC::sendData ()
 Sends the data whether the processor is on the working side or on the lazy side.
void ParaMEDMEM::InterpKernelDEC::sendData (double time, double deltatime)
 Sends the data available at time time in asynchronous mode.

Detailed Description

Overview

The InterpKernelDEC enables the conservativeremapping of fields between two parallel codes. This remapping is based on the computation of intersection volumes between elements from code A and elements from code B. The computation is possible for 3D meshes, 2D meshes, and 3D-surface meshes. Dimensions must be similar for code A and code B (for instance, though it could be desirable, it is not yet possible to couple 3D surfaces with 2D surfaces).

In the present version, only fields lying on elements are considered.

NonCoincident_small.png
Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values on quadrangles are weighted by their intersection area and summed.
A typical use of InterpKernelDEC encompasses two distinct phases :

The following code excerpt illutrates a typical use of the InterpKernelDEC class.

    ...
    InterpKernelDEC dec(groupA, groupB);
    dec.attachLocalField(field);
    dec.synchronize();
    if (groupA.containsMyRank())
    dec.recvData();
    else if (groupB.containsMyRank())
    dec.sendData();
    ...

A conservativeremapping of the field from the source mesh to the target mesh is performed by the function synchronise(), which computes the remappingmatrix.

Computing the field on the receiving side can be expressed in terms of a matrix-vector product : $ \phi_t=W.\phi_s$, with $ \phi_t $ the field on the target side and $ \phi_s $ the field on the source side. When remapping a 3D surface to another 3D surface, a projection phase is necessary to match elements from both sides. Care must be taken when defining this projection to obtain a conservative remapping.

In the P0-P0 case, this matrix is a plain rectangular matrix with coefficients equal to the intersection areas between triangle and quadrangles. For instance, in the above figure, the matrix is :

\[ \begin{tabular}{|cccc|} 0.72 & 0 & 0.2 & 0 \\ 0.46 & 0 & 0.51 & 0.03\\ 0.42 & 0.53 & 0 & 0.05\\ 0 & 0 & 0.92 & 0.05 \\ \end{tabular} \]

Options

On top of DEC Options, options supported by InterpKernelDEC objects are related to the underlying Intersector class. All the options available in the intersector objects are available for the InterpKernelDEC object. The various options available for * intersectors can be reviewed in Intersectors.

For instance :

    InterpKernelDEC dec(source_group, target_group);
    dec.attachLocalField(field);
    dec.setOptions("DoRotate",false);
    dec.setOptions("Precision",1e-12);
    dec.synchronize();
Warning:
{ Options must be set before calling the synchronize method. }

Function Documentation

Definition at line 107 of file InterpKernelDEC.cxx.

This constructor creates an InterpKernelDEC which has source_group as a working side and target_group as an idle side.

All the processors will actually participate, but intersection computations will be performed on the working side during the synchronize() phase. The constructor must be called synchronously on all processors of both processor groups.

Parameters:
source_groupworking side ProcessorGroup
target_grouplazy side ProcessorGroup

Definition at line 120 of file InterpKernelDEC.cxx.

ParaMEDMEM::InterpKernelDEC::InterpKernelDEC ( const std::set< int > &  src_ids,
const std::set< int > &  trg_ids,
const MPI_Comm &  world_comm = MPI_COMM_WORLD 
)

Definition at line 126 of file InterpKernelDEC.cxx.

                                                              :DisjointDEC(src_ids,trg_ids,world_comm),
                                                               _interpolation_matrix(0)
  {
  }

Receives the data whether the processor is on the working side or on the lazy side.

It must match a sendData() call on the other side.

Implements ParaMEDMEM::DisjointDEC.

Definition at line 223 of file InterpKernelDEC.cxx.

Here is the call graph for this function:

Here is the caller graph for this function:

Receives the data at time time in asynchronous mode.

The value of the field will be time-interpolated from the field values received.

Parameters:
timetime at which the value is desired

Definition at line 241 of file InterpKernelDEC.cxx.

Here is the call graph for this function:

Sends the data whether the processor is on the working side or on the lazy side.

It must match a recvData() call on the other side.

Implements ParaMEDMEM::DisjointDEC.

Definition at line 251 of file InterpKernelDEC.cxx.

Here is the call graph for this function:

Here is the caller graph for this function:

void ParaMEDMEM::InterpKernelDEC::sendData ( double  time,
double  deltatime 
)

Sends the data available at time time in asynchronous mode.

Parameters:
timetime at which the value is available
deltatimetime interval between the value presently sent and the next one.

Definition at line 270 of file InterpKernelDEC.cxx.

Here is the call graph for this function:

Synchronization process for exchanging topologies.

This method prepares all the structures necessary for sending data from a processor group to the other. It uses the mesh underlying the fields that have been set with attachLocalField method. It works in four steps :

  1. Bounding boxes are computed for each subdomain,
  2. The lazy side mesh parts that are likely to intersect the working side local processor are sent to the working side,
  3. The working side calls the interpolation kernel to compute the intersection between local and imported mesh.
  4. The lazy side is updated so that it knows the structure of the data that will be sent by the working side during a sendData() call.

Implements ParaMEDMEM::DisjointDEC.

Definition at line 150 of file InterpKernelDEC.cxx.

  {
    if(!isInUnion())
      return ;
    delete _interpolation_matrix;
    _interpolation_matrix = new InterpolationMatrix (_local_field, *_source_group,*_target_group,*this,*this); 

    //setting up the communication DEC on both sides  
    if (_source_group->containsMyRank())
      {
        //locate the distant meshes
        ElementLocator locator(*_local_field, *_target_group, *_source_group);
        //transfering option from InterpKernelDEC to ElementLocator   
        locator.copyOptions(*this);
        MEDCouplingPointSet* distant_mesh=0; 
        int* distant_ids=0;
        std::string distantMeth;
        for (int i=0; i<_target_group->size(); i++)
          {
            //        int idistant_proc = (i+_source_group->myRank())%_target_group->size();
            int idistant_proc=i;

            //gathers pieces of the target meshes that can intersect the local mesh
            locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids);
            if (distant_mesh !=0)
              {
                locator.exchangeMethod(_method,idistant_proc,distantMeth);
                //adds the contribution of the distant mesh on the local one
                int idistant_proc_in_union=_union_group->translateRank(_target_group,idistant_proc);
                std::cout <<"add contribution from proc "<<idistant_proc_in_union<<" to proc "<<_union_group->myRank()<<std::endl;
                _interpolation_matrix->addContribution(*distant_mesh,idistant_proc_in_union,distant_ids,_method,distantMeth);
                distant_mesh->decrRef();
                delete [] distant_ids;
                distant_mesh=0;
                distant_ids=0;
              }
          }
       _interpolation_matrix->finishContributionW(locator);
      }

    if (_target_group->containsMyRank())
      {
        ElementLocator locator(*_local_field, *_source_group, *_target_group);
        //transfering option from InterpKernelDEC to ElementLocator
        locator.copyOptions(*this);
        MEDCouplingPointSet* distant_mesh=0;
        int* distant_ids=0;
        for (int i=0; i<_source_group->size(); i++)
          {
            //        int idistant_proc = (i+_target_group->myRank())%_source_group->size();
            int  idistant_proc=i;
            //gathers pieces of the target meshes that can intersect the local mesh
            locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids);
            std::cout << " Data sent from "<<_union_group->myRank()<<" to source proc "<< idistant_proc<<std::endl;
            if (distant_mesh!=0)
              {
                std::string distantMeth;
                locator.exchangeMethod(_method,idistant_proc,distantMeth);
                distant_mesh->decrRef();
                delete [] distant_ids;
                distant_mesh=0;
                distant_ids=0;
              }
          }
        _interpolation_matrix->finishContributionL(locator);
      }
    _interpolation_matrix->prepare();
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 132 of file InterpKernelDEC.cxx.