1 /**
2 * \class moab::DataCoupler
3 *
4 * \brief This class couples data between meshes.
5 *
6 * The coupler interpolates solution data at a set of points. Data being interpolated resides on a
7 * "source" mesh, in a tag or in vertex coords. Applications calling this coupler send in entities,
8 * and receive back data interpolated at those points. Entities in the source mesh containing those
9 * points do not have to reside on the same processor.
10 *
11 * To use, an application should:
12 * - instantiate this DataCoupler by calling the constructor collectively on all processors in the
13 * communicator
14 * - call locate_points, which locates the points to be interpolated and (optionally) caches the
15 * results in this class and SpatialLocator
16 * - call interpolate, which does the interpolation
17 *
18 * Multiple interpolations (of multiple tags, or element-average vs. true interpolation) can be done
19 * after locating the points.
20 *
21 * SpatialLocator is used for the spatial location portion of this work.
22 *
23 * This class is a next-generation implementation of Coupler.
24 */
25 #ifndef DATACOUPLER_HPP
26 #define DATACOUPLER_HPP
27
28 #include "moab/Range.hpp"
29 #include "moab/Interface.hpp"
30
31 #include <sstream>
32
33 namespace moab
34 {
35
36 class ParallelComm;
37 class SpatialLocator;
38
39 class DataCoupler
40 {
41 public:
42 enum Method
43 {
44 CONSTANT,
45 LINEAR_FE,
46 QUADRATIC_FE,
47 SPECTRAL
48 };
49
50 enum IntegType
51 {
52 VOLUME
53 };
54
55 /* Constructor
56 * Constructor, which also optionally initializes the coupler
57 * \param source_ents Elements in the source mesh
58 * \param coupler_id Id of this coupler, should be the same over all procs
59 * \param pc ParallelComm object to be used with this coupler, representing the union
60 * of processors containing source and target meshes
61 * \param init_locator If true, initializes a spatial locator inside the constructor
62 * \param dim Dimension of entities to be coupled; if -1, get from source_elems
63 */
64 DataCoupler( Interface* impl,
65 Range& source_ents,
66 int coupler_id,
67 ParallelComm* pc = NULL,
68 bool init_locator = true,
69 int dim = -1 );
70
71 /* Destructor
72 */
73 virtual ~DataCoupler();
74
75 /* \brief Locate points on the source mesh
76 * This is a pass-through function to SpatialLocator::locate_points
77 * \param xyz Point locations (interleaved) being located
78 * \param num_points Number of points in xyz
79 * \param rel_iter_tol Relative tolerance for non-linear iteration
80 * \param abs_iter_tol Relative tolerance for non-linear iteration, usually 10^-10 or so
81 * \param inside_tol Tolerance of is_inside evaluation, usually 10^-6 or so
82 * \param loc_results Tuple list containing the results; two types of results are possible,
83 * controlled by value of store_local parameter:
84 * store_local = true: each tuple T[j] consists of (p, i), p = proc with src element
85 * containing point j (or 0 if serial), i = index in stored list (in SpatialLocator) on src proc
86 * store_local = false: each tuple T[j] consists of (p, ht, hs, pr[3]), where ht = target
87 * mesh entity handle, hs = source mesh entity containing point (0 if not found), pr =
88 * parameters in hs \param store_local If true, stores the located points on SpatialLocator
89 */
90 ErrorCode locate_points( double* xyz,
91 int num_points,
92 const double rel_iter_tol = 1.0e-10,
93 const double abs_iter_tol = 1.0e-10,
94 const double inside_tol = 1.0e-6 );
95
96 /* \brief Locate points on the source mesh
97 * This is a pass-through function to SpatialLocator::locate_points
98 * \param ents Target entities being located
99 * \param rel_iter_tol Relative tolerance for non-linear iteration
100 * \param abs_iter_tol Relative tolerance for non-linear iteration, usually 10^-10 or so
101 * \param inside_tol Tolerance of is_inside evaluation, usually 10^-6 or so
102 * \param loc_results Tuple list containing the results; two types of results are possible,
103 * controlled by value of store_local parameter:
104 * store_local = true: each tuple T[j] consists of (p, i), p = proc with src element
105 * containing point j (or 0 if serial), i = index in stored list (in SpatialLocator) on src proc
106 * store_local = false: each tuple T[j] consists of (p, ht, hs, pr[3]), where ht = target
107 * mesh entity handle, hs = source mesh entity containing point (0 if not found), pr =
108 * parameters in hs \param store_local If true, stores the located points on SpatialLocator
109 */
110 ErrorCode locate_points( Range& ents,
111 const double rel_iter_tol = 1.0e-10,
112 const double abs_iter_tol = 1.0e-10,
113 const double inside_tol = 1.0e-6 );
114
115 /* \brief Interpolate data from the source mesh onto points
116 * All entities/points or, if tuple_list is input, only those points
117 * are interpolated from the source mesh. Application should
118 * allocate enough memory in interp_vals to hold interpolation results.
119 *
120 * If normalization is requested, technique used depends on the coupling
121 * method.
122 *
123 * \param method Interpolation/normalization method
124 * \param tag Tag on source mesh holding data to be interpolated
125 * \param interp_vals Memory holding interpolated data; if NULL, data is written to same tag on
126 * target ents \param point_indices If non-NULL, a set of indices of points input to
127 * locate_points at which to interpolate; if NULL, interpolates at all points
128 * input to locate_points
129 * \param normalize If true, normalization is done according to method
130 */
131 ErrorCode interpolate( /*DataCoupler::Method*/ int method,
132 Tag tag,
133 double* interp_vals = NULL,
134 std::vector< int >* point_indices = NULL,
135 bool normalize = true );
136
137 /* \brief Interpolate data from the source mesh onto points
138 * All entities/points or, if tuple_list is input, only those points
139 * are interpolated from the source mesh. Application should
140 * allocate enough memory in interp_vals to hold interpolation results.
141 *
142 * If normalization is requested, technique used depends on the coupling
143 * method.
144 *
145 * \param method Interpolation/normalization method
146 * \param tag_name Tag name on source mesh holding data to be interpolated
147 * \param interp_vals Memory holding interpolated data; if NULL, data is written to same tag on
148 * target ents \param point_indices If non-NULL, a set of indices of points input to
149 * locate_points at which to interpolate; if NULL, interpolates at all points
150 * input to locate_points
151 * \param normalize If true, normalization is done according to method
152 */
153 ErrorCode interpolate( /*DataCoupler::Method*/ int method,
154 const std::string& tag_name,
155 double* interp_vals = NULL,
156 std::vector< int >* point_indices = NULL,
157 bool normalize = true );
158
159 /* \brief Interpolate data from multiple tags
160 * All entities/points or, if tuple_list is input, only those points
161 * are interpolated from the source mesh. Application should
162 * allocate enough memory in interp_vals to hold interpolation results.
163 *
164 * In this variant, multiple tags, possibly with multiple interpolation
165 * methods, are specified. Sum of values in points_per_method should be
166 * the number of points in tl or, if NULL, targetPts.
167 *
168 * If normalization is requested, technique used depends on the coupling
169 * method.
170 *
171 * \param methods Vector of Interpolation/normalization methods
172 * \param tag_names Names of tag being interpolated for each method
173 * \param points_per_method Number of points for each method
174 * \param num_methods Length of vectors in previous 3 arguments
175 * \param interp_vals Memory holding interpolated data; if NULL, data is written to same tag on
176 * target ents \param point_indices If non-NULL, a set of indices of points input to
177 * locate_points at which to interpolate; if NULL, interpolates at all points
178 * input to locate_points
179 * \param normalize If true, normalization is done according to method
180 */
181 ErrorCode interpolate( /*DataCoupler::Method*/ int* methods,
182 const std::string* tag_names,
183 int* points_per_method,
184 int num_methods,
185 double* interp_vals = NULL,
186 std::vector< int >* point_indices = NULL,
187 bool normalize = true );
188
189 /* \brief Interpolate data from multiple tags
190 * All entities/points or, if tuple_list is input, only those points
191 * are interpolated from the source mesh. Application should
192 * allocate enough memory in interp_vals to hold interpolation results.
193 *
194 * In this variant, multiple tags, possibly with multiple interpolation
195 * methods, are specified. Sum of values in points_per_method should be
196 * the number of points in tl or, if NULL, targetPts.
197 *
198 * If normalization is requested, technique used depends on the coupling
199 * method.
200 *
201 * \param methods Vector of Interpolation/normalization methods
202 * \param tag_names Names of tag being interpolated for each method
203 * \param points_per_method Number of points for each method
204 * \param num_methods Length of vectors in previous 3 arguments
205 * \param interp_vals Memory holding interpolated data; if NULL, data is written to same tag on
206 * target ents \param point_indices If non-NULL, a set of indices of points input to
207 * locate_points at which to interpolate; if NULL, interpolates at all points
208 * input to locate_points
209 * \param normalize If true, normalization is done according to method
210 */
211 ErrorCode interpolate( /*DataCoupler::Method*/ int* methods,
212 Tag* tag_names,
213 int* points_per_method,
214 int num_methods,
215 double* interp_vals = NULL,
216 std::vector< int >* point_indices = NULL,
217 bool normalize = true );
218
219 /* Get functions */
220 inline SpatialLocator* spatial_locator()
221 {
222 return myLocator;
223 }
224 inline int my_id() const
225 {
226 return myId;
227 }
228 inline const Range& target_ents() const
229 {
230 return targetEnts;
231 }
232 inline Range& target_ents()
233 {
234 return targetEnts;
235 }
236 inline int get_dim() const
237 {
238 return myDim;
239 }
240
241 private:
242 /* \brief MOAB instance
243 */
244 Interface* mbImpl;
245
246 /* \brief ParallelComm object for this coupler
247 */
248 ParallelComm* myPcomm;
249
250 /* \brief SpatialLocator for local mesh
251 */
252 SpatialLocator* myLocator;
253
254 /* \brief Id of this coupler
255 */
256 int myId;
257
258 /* \brief Range of target entities
259 */
260 Range targetEnts;
261
262 // Entity dimension
263 int myDim;
264 };
265
266 inline ErrorCode DataCoupler::interpolate( /*DataCoupler::Method*/ int method,
267 Tag tag,
268 double* interp_vals,
269 std::vector< int >* point_indices,
270 bool normalize )
271 {
272 // No point indices input,
273 int num_pts = ( point_indices ? point_indices->size() : targetEnts.size() );
274 return interpolate( &method, &tag, &num_pts, 1, interp_vals, point_indices, normalize );
275 }
276
277 } // namespace moab
278
279 #endif