Salome HOME
[bos #38048] [EDF] (2023-T3) PARAMEDMEM Ergonomy.
[tools/medcoupling.git] / src / ParaMEDMEM / InterpKernelDEC.hxx
1 // Copyright (C) 2007-2024  CEA, EDF
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #ifndef __INTERPKERNELDEC_HXX__
21 #define __INTERPKERNELDEC_HXX__
22
23 #include "DisjointDEC.hxx"
24 #include "MxN_Mapping.hxx"
25 #include "InterpolationOptions.hxx"
26
27 namespace MEDCoupling
28 {
29   class InterpolationMatrix;
30
31   /*!
32     \anchor InterpKernelDEC-det
33     \class InterpKernelDEC
34
35     \section InterpKernelDEC-over Overview
36
37     The InterpKernelDEC enables the \ref InterpKerRemapGlobal "remapping" (or interpolation) of fields between
38     two parallel codes.
39
40     The projection
41     methodology is based on the algorithms of %INTERP_KERNEL, that is to say, they work in a similar fashion than
42     what the \ref remapper "sequential remapper" does. The following \ref discretization "projection methods"
43     are supported: P0->P0 (the most common case), P1->P0, P0->P1.
44
45     The computation is possible for 3D meshes, 2D meshes, and 3D-surface
46     meshes. Dimensions must be identical for code A and code B (for instance, though it could be
47     desirable, it is not yet possible to couple 3D surfaces with 2D surfaces).
48
49     The name "InterpKernelDEC" comes from the fact that this class uses exactly the same algorithms
50     as the sequential remapper. Both this class and the sequential
51     \ref MEDCoupling::MEDCouplingRemapper "MEDCouplingRemapper" are built on top of the %INTERP_KERNEL
52     algorithms (notably the computation of the intersection volumes).
53
54     Among the important properties inherited from the parent abstract class \ref DisjointDEC-det "DisjointDEC",
55     the two \ref MPIProcessorGroup-det "processor groups" (source and target) must have a void intersection.
56
57     \image html NonCoincident_small.png "Transfer of a field supported by a quadrangular mesh to a triangular mesh".
58
59     \image latex NonCoincident_small.eps "Transfer of a field supported by a quadrangular mesh to a triangular mesh"
60
61     In the figure above we see the transfer of a field based on a quadrangular mesh to a new field supported by
62     a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values on the
63     quadrangles are weighted by their intersection area and summed.
64
65     A typical use of InterpKernelDEC encompasses two distinct phases :
66     - A setup phase during which the intersection volumes are computed and the communication structures are
67     setup. This corresponds to calling the InterpKernelDEC::synchronize() method.
68     - A running phase during which the projections are actually performed. This corresponds to the calls to
69     sendData() and recvData() which actually trigger the data exchange. The data exchange are synchronous
70     in the current version of the library so that recvData() and sendData() calls must be synchronized
71     on code A and code B processor groups.
72
73     The following code excerpt illustrates a typical use of the InterpKernelDEC class.
74
75     \code
76     ...
77     InterpKernelDEC dec(groupA, groupB);
78     dec.attachLocalField(field);
79     dec.synchronize();
80     if (groupA.containsMyRank())
81     dec.recvData();
82     else if (groupB.containsMyRank())
83     dec.sendData();
84     ...
85     \endcode
86     A \ref InterpKerRemapGlobal "remapping" of the field from the source mesh to the target mesh is performed by
87     the function synchronise(), which computes the interpolation matrix.
88
89     Computing the field on the receiving side can be expressed in terms of a matrix-vector product :
90     \f$ \phi_t=W.\phi_s\f$, with \f$ \phi_t \f$ the field on the target side and \f$ \phi_s \f$ the field
91     on the source side.
92     When remapping a 3D surface to another 3D surface, a projection phase is necessary to match elements
93     from both sides. Care must be taken when defining this projection to obtain a
94     \ref InterpKerRemapGlobal "conservative remapping".
95
96     In the P0-P0 case, this matrix is a plain rectangular matrix with coefficients equal to the
97     intersection areas between triangle and quadrangles. For instance, in the above figure, the matrix
98     is :
99
100     \f[
101     \begin{tabular}{|cccc|}
102     0.72 & 0 & 0.2 & 0 \\
103     0.46 & 0 & 0.51 & 0.03\\
104     0.42 & 0.53 & 0 & 0.05\\
105     0 & 0 & 0.92 & 0.05 \\
106     \end{tabular}
107     \f]
108
109     \section InterpKernelDEC-options Options
110     On top of the usual \ref MEDCoupling::DECOptions "DEC options", the options supported by %InterpKernelDEC objects are
111     related to the underlying \ref InterpKerIntersectors "intersector class".
112     All the options available in the intersector objects are
113     available for the %InterpKernelDEC object. The various options available for  intersectors can
114     be reviewed in \ref InterpKerIntersectors.
115
116     For instance :
117     \verbatim
118     InterpKernelDEC dec(source_group, target_group);
119     dec.attachLocalField(field);
120     dec.setDoRotate(false);
121     dec.setPrecision(1e-12);
122     dec.synchronize();
123     \endverbatim
124
125     \warning{  Options must be set before calling the synchronize method. }
126   */
127
128   class InterpKernelDEC : public DisjointDEC, public INTERP_KERNEL::InterpolationOptions
129   {
130   public:  
131     InterpKernelDEC();
132     InterpKernelDEC(ProcessorGroup& source_group, ProcessorGroup& target_group);
133     InterpKernelDEC(const std::set<int>& src_ids, const std::set<int>& trg_ids, const MPI_Comm& world_comm=MPI_COMM_WORLD);
134     InterpKernelDEC(ProcessorGroup& generic_group, const std::string& source_group, const std::string& target_group);
135     InterpKernelDEC(ProcessorGroup& generic_group, const std::string& interaction_group);
136     virtual ~InterpKernelDEC();
137     void release();
138
139     void synchronize();
140     void synchronizeWithDefaultValue(double val);
141     MCAuto<DataArrayIdType> retrieveNonFetchedIds() const;
142     void recvData();
143     void recvData(double time);
144     void sendData();
145     void sendData(double time , double deltatime);
146     void prepareSourceDE() { }
147     void prepareTargetDE() { }
148   private:
149     MCAuto<DataArrayIdType> retrieveNonFetchedIdsSource() const;
150     MCAuto<DataArrayIdType> retrieveNonFetchedIdsTarget() const;
151   private:
152     InterpolationMatrix* _interpolation_matrix;
153   };
154 }
155
156 #endif