![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /**
00002 * \class moab::Coupler
00003 * \author Tim Tautges
00004 *
00005 * \brief This class couples data between meshes.
00006 *
00007 * The coupler interpolates solution data at a set of points. Data
00008 * being interpolated resides on a source mesh, in a tag.
00009 * Applications calling this coupler send in entities, usually points
00010 * or vertices, and receive back the tag value interpolated at those
00011 * points. Entities in the source mesh containing those points
00012 * do not have to reside on the same processor.
00013 *
00014 * To use, an application should:
00015 * - instantiate this coupler by calling the constructor collectively
00016 * on all processors in the communicator
00017 * - call locate_points, which locates the points to be interpolated and
00018 * (optionally) caches the results in this object
00019 * - call interpolate, which does the interpolation
00020 *
00021 * Multiple interpolations can be done after locating the points.
00022 *
00023 */
00024 #ifndef COUPLER_HPP
00025 #define COUPLER_HPP
00026
00027 #include "moab/Range.hpp"
00028 #include "moab/Interface.hpp"
00029 #include "moab/CartVect.hpp"
00030 #include "moab/TupleList.hpp"
00031
00032 #include
00033
00034 namespace moab
00035 {
00036
00037 class ParallelComm;
00038
00039 class AdaptiveKDTree;
00040
00041 class TupleList;
00042
00043 class Coupler
00044 {
00045 public:
00046 enum Method
00047 {
00048 CONSTANT,
00049 LINEAR_FE,
00050 QUADRATIC_FE,
00051 SPECTRAL,
00052 SPHERICAL
00053 };
00054
00055 enum IntegType
00056 {
00057 VOLUME
00058 };
00059
00060 /* Constructor
00061 * Constructor, which also optionally initializes the coupler
00062 * \param pc ParallelComm object to be used with this coupler, representing the union
00063 * of processors containing source and target meshes
00064 * \param local_elems Local elements in the source mesh
00065 * \param coupler_id Id of this coupler, should be the same over all procs
00066 * \param init_tree If true, initializes kdtree inside the constructor
00067 */
00068 Coupler( Interface* impl,
00069 ParallelComm* pc,
00070 Range& local_elems,
00071 int coupler_id,
00072 bool init_tree = true,
00073 int max_ent_dim = 3 );
00074
00075 /* Destructor
00076 */
00077 virtual ~Coupler();
00078
00079 /**
00080 * \brief Initialize the kdtree, locally and across communicator
00081 */
00082 ErrorCode initialize_tree();
00083
00084 /* \brief Locate points on the source mesh
00085 * This function finds the element/processor/natural coordinates for the
00086 * source mesh element containing each point, optionally storing the results
00087 * on the target mesh processor. Relative tolerance is compared to bounding
00088 * box diagonal length. Tolerance is compared to [-1,1] parametric extent
00089 * in the reference element.
00090 * \param xyz Point locations (interleaved) being located
00091 * \param num_points Number of points in xyz
00092 * \param rel_eps Relative tolerance for the non-linear iteration inside a given element
00093 * \param abs_eps Absolute tolerance for the non-linear iteration inside a given element
00094 * \param tl Tuple list containing the results, with each tuple
00095 * consisting of (p, i), p = proc, i = index on that proc
00096 * \param store_local If true, stores the tuple list in targetPts
00097 */
00098 ErrorCode locate_points( double* xyz,
00099 unsigned int num_points,
00100 double rel_eps = 0.0,
00101 double abs_eps = 0.0,
00102 TupleList* tl = NULL,
00103 bool store_local = true );
00104
00105 /* \brief Locate entities on the source mesh
00106 * This function finds the element/processor/natural coordinates for the
00107 * source mesh element containing each entity, optionally storing the results
00108 * on the target mesh processor. Location of each target mesh entity passed in
00109 * is its centroid (for non-vertices, the avg of its vertex positions).
00110 * Relative tolerance is compared to bounding
00111 * box diagonal length. Tolerance is compared to [-1,1] parametric extent
00112 * in the reference element.
00113 * \param ents Entities being located
00114 * \param rel_eps Relative tolerance for the non-linear iteration inside a given element
00115 * \param abs_eps Absolute tolerance for the non-linear iteration inside a given element
00116 * \param tl Tuple list containing the results, with each tuple
00117 * consisting of (p, i), p = proc, i = index on that proc
00118 * \param store_local If true, stores the tuple list in targetPts
00119 *
00120 */
00121 ErrorCode locate_points( Range& ents,
00122 double rel_eps = 0.0,
00123 double abs_eps = 0.0,
00124 TupleList* tl = NULL,
00125 bool store_local = true );
00126
00127 /* \brief Interpolate data from the source mesh onto points
00128 * All entities/points or, if tuple_list is input, only those points
00129 * are interpolated from the source mesh. Application should
00130 * allocate enough memory in interp_vals to hold interpolation results.
00131 *
00132 * If normalization is requested, technique used depends on the coupling
00133 * method.
00134 *
00135 * \param method Interpolation/normalization method
00136 * \param tag Tag on source mesh holding data to be interpolated
00137 * \param interp_vals Memory holding interpolated data
00138 * \param tl Tuple list of points to be interpolated, in format used by targetPts
00139 * (see documentation for targetPts below); if NULL, all locations
00140 * in targetPts are interpolated
00141 * \param normalize If true, normalization is done according to method
00142 */
00143 ErrorCode interpolate( Coupler::Method method,
00144 Tag tag,
00145 double* interp_vals,
00146 TupleList* tl = NULL,
00147 bool normalize = true );
00148
00149 /* \brief Interpolate data from the source mesh onto points
00150 * All entities/points or, if tuple_list is input, only those points
00151 * are interpolated from the source mesh. Application should
00152 * allocate enough memory in interp_vals to hold interpolation results.
00153 *
00154 * If normalization is requested, technique used depends on the coupling
00155 * method.
00156 *
00157 * \param methods Interpolation/normalization method
00158 * \param tag_name Name of tag on source mesh holding data to be interpolated
00159 * \param interp_vals Memory holding interpolated data
00160 * \param tl Tuple list of points to be interpolated, in format used by targetPts
00161 * (see documentation for targetPts below); if NULL, all locations
00162 * in targetPts are interpolated
00163 * \param normalize If true, normalization is done according to method
00164 */
00165 ErrorCode interpolate( Coupler::Method method,
00166 const std::string& tag_name,
00167 double* interp_vals,
00168 TupleList* tl = NULL,
00169 bool normalize = true );
00170
00171 /* \brief Interpolate data from multiple tags
00172 * All entities/points or, if tuple_list is input, only those points
00173 * are interpolated from the source mesh. Application should
00174 * allocate enough memory in interp_vals to hold interpolation results.
00175 *
00176 * In this variant, multiple tags, possibly with multiple interpolation
00177 * methods, are specified. Sum of values in points_per_method should be
00178 * the number of points in tl or, if NULL, targetPts.
00179 *
00180 * If normalization is requested, technique used depends on the coupling
00181 * method.
00182 *
00183 * \param methods Vector of Interpolation/normalization methods
00184 * \param tag_names Names of tag being interpolated for each method
00185 * \param points_per_method Number of points for each method
00186 * \param num_methods Length of vectors in previous 3 arguments
00187 * \param interp_vals Memory holding interpolated data
00188 * \param tl Tuple list of points to be interpolated; if NULL, all locations
00189 * stored in this object are interpolated
00190 * \param normalize If true, normalization is done according to method
00191 */
00192 ErrorCode interpolate( Coupler::Method* methods,
00193 const std::string* tag_names,
00194 int* points_per_method,
00195 int num_methods,
00196 double* interp_vals,
00197 TupleList* tl = NULL,
00198 bool normalize = true );
00199
00200 /* \brief Interpolate data from multiple tags
00201 * All entities/points or, if tuple_list is input, only those points
00202 * are interpolated from the source mesh. Application should
00203 * allocate enough memory in interp_vals to hold interpolation results.
00204 *
00205 * In this variant, multiple tags, possibly with multiple interpolation
00206 * methods, are specified. Sum of values in points_per_method should be
00207 * the number of points in tl or, if NULL, targetPts.
00208 *
00209 * If normalization is requested, technique used depends on the coupling
00210 * method.
00211 *
00212 * \param methods Vector of Interpolation/normalization methods
00213 * \param tag_names Names of tag being interpolated for each method
00214 * \param points_per_method Number of points for each method
00215 * \param num_methods Length of vectors in previous 3 arguments
00216 * \param interp_vals Memory holding interpolated data
00217 * \param tl Tuple list of points to be interpolated; if NULL, all locations
00218 * stored in this object are interpolated
00219 * \param normalize If true, normalization is done according to method
00220 */
00221 ErrorCode interpolate( Coupler::Method* methods,
00222 Tag* tag_names,
00223 int* points_per_method,
00224 int num_methods,
00225 double* interp_vals,
00226 TupleList* tl = NULL,
00227 bool normalize = true );
00228
00229 /* \brief Normalize a field over an entire mesh
00230 * A field existing on the vertices of elements of a mesh is integrated
00231 * over all elements in the mesh. The integrated value is normalized
00232 * and the normalization factor is saved to a new tag
00233 * on the mesh entity set.
00234 *
00235 * \param root_set Entity Set representing the entire mesh
00236 * \param norm_tag Tag containing field data to integrate
00237 * \param integ_type Type of integration to perform
00238 * \param num_integ_pts The number of Gaussian integration points to use in each dimension
00239 */
00240 ErrorCode normalize_mesh( EntityHandle root_set,
00241 const char* norm_tag,
00242 Coupler::IntegType integ_type,
00243 int num_integ_pts );
00244
00245 /* \brief Normalize a field over subsets of entities
00246 * A field existing on the vertices of elements of a mesh is integrated
00247 * over subsets of elements identified by the tags and values. The integrated
00248 * values are normalized and the normalization factor is saved to a new tag
00249 * on the entity sets which contain the elements of a subset.
00250 *
00251 * \param root_set Entity Set from the mesh from which to select subsets
00252 * \param norm_tag Tag containing field data to integrate
00253 * \param tag_names Array of tag names used for selecting element subsets
00254 * \param num_tags Number of tag names
00255 * \param tag_values Array of tag values passed as strings; the array will be
00256 * the same length as that for tag names however some entries may be
00257 * NULL indicating that tag should be matched for existence and not value
00258 * \param integ_type Type of integration to perform
00259 * \param num_integ_pts The number of Gaussian integration points to use in each dimension
00260 */
00261 ErrorCode normalize_subset( EntityHandle root_set,
00262 const char* norm_tag,
00263 const char** tag_names,
00264 int num_tags,
00265 const char** tag_values,
00266 Coupler::IntegType integ_type,
00267 int num_integ_pts );
00268
00269 /* \brief Normalize a field over subsets of entities
00270 * A field existing on the vertices of elements of a mesh is integrated
00271 * over subsets of elements identified by the tags and values. The integrated
00272 * values are normalized and the normalization factor is saved to a new tag
00273 * on the entity sets which contain the elements of a subset.
00274 *
00275 * \param root_set Entity Set from the mesh from which to select subsets
00276 * \param norm_tag Tag containing field data to integrate
00277 * \param tag_handles Array of tag handles used for selecting element subsets
00278 * \param num_tags Number of tag handles
00279 * \param tag_values Array of tag values passed as strings; the array will be
00280 * the same length as that for tag handles however some entries may be
00281 * NULL indicating that tag should be matched for existence and not value
00282 * \param integ_type Type of integration to perform
00283 * \param num_integ_pts The number of Gaussian integration points to use in each dimension
00284 */
00285 ErrorCode normalize_subset( EntityHandle root_set,
00286 const char* norm_tag,
00287 Tag* tag_handles,
00288 int num_tags,
00289 const char** tag_values,
00290 Coupler::IntegType integ_type,
00291 int num_integ_pts );
00292
00293 /* \brief Retrieve groups of entities matching tags and values(if present)
00294 * Retrieve a vector of vectors of entity handles matching the
00295 * tags and values. The entity set passed is used as the search domain.
00296 *
00297 * \param norm_tag Tag containing field data to integrate
00298 * \param entity_sets Pointer to vector of vectors of entity set handles
00299 * \param entity_groups Pointer to vector of vectors of entity handles from each entity set
00300 * \param integ_type Type of integration to perform
00301 * \param num_integ_pts The number of Gaussian integration points to use in each dimension
00302 */
00303 ErrorCode do_normalization( const char* norm_tag,
00304 std::vector< std::vector< EntityHandle > >& entity_sets,
00305 std::vector< std::vector< EntityHandle > >& entity_groups,
00306 Coupler::IntegType integ_type,
00307 int num_integ_pts );
00308
00309 /* \brief Retrieve groups of entities matching tags and values(if present)
00310 * Retrieve a vector of vectors of entity handles matching the
00311 * tags and values. The entity set passed is used as the search domain.
00312 *
00313 * \param root_set Set from which to search for matching entities
00314 * \param tag_names Array of tag names used to select entities
00315 * \param tag_values Array of tag values used to select entities
00316 * \param num_tags Number of tag names
00317 * \param entity_sets Pointer to vector of vectors of entity set handles found in the search
00318 * \param entity_groups Pointer to vector of vectors of entity handles from each entity set
00319 */
00320 ErrorCode get_matching_entities( EntityHandle root_set,
00321 const char** tag_names,
00322 const char** tag_values,
00323 int num_tags,
00324 std::vector< std::vector< EntityHandle > >* entity_sets,
00325 std::vector< std::vector< EntityHandle > >* entity_groups );
00326
00327 /* \brief Retrieve groups of entities matching tags and values(if present)
00328 * Retrieve a vector of vectors of entity handles matching the
00329 * tags and values. The entity set passed is used as the search domain.
00330 *
00331 * \param root_set Set from which to search for matching entities
00332 * \param tag_handles Array of tag handles used to select entities
00333 * \param tag_values Array of tag values used to select entities
00334 * \param num_tags Number of tag handles
00335 * \param entity_sets Pointer to vector of vectors of entity set handles found in the search
00336 * \param entity_groups Pointer to vector of vectors of entity handles from each entity set
00337 */
00338 ErrorCode get_matching_entities( EntityHandle root_set,
00339 Tag* tag_handles,
00340 const char** tag_values,
00341 int num_tags,
00342 std::vector< std::vector< EntityHandle > >* entity_sets,
00343 std::vector< std::vector< EntityHandle > >* entity_groups );
00344
00345 /* \brief Return an array of tuples of tag values for each Entity Set
00346 * A list of n-tuples will be constructed with 1 n-tuple for each Entity Set.
00347 * The n-tuple will have an component for each tag given. It is assumed all
00348 * of the tags are integer tags.
00349 *
00350 * \param ent_sets Array of Entity Set handles to use for retrieving tag data
00351 * \param num_sets Number of Entity Sets
00352 * \param tag_names Array of tag names
00353 * \param num_tags Number of tag names
00354 * \param tuples The returned tuple_list structure
00355 */
00356 ErrorCode create_tuples( Range& ent_sets, const char** tag_names, unsigned int num_tags, TupleList** tuples );
00357
00358 /* \brief Return an array of tuples of tag values for each Entity Set
00359 * A list of n-tuples will be constructed with 1 n-tuple for each Entity Set.
00360 * The n-tuple will have an component for each tag given. It is assumed all
00361 * of the tags are integer tags.
00362 *
00363 * \param ent_sets Array of Entity Set handles to use for retrieving tag data
00364 * \param num_sets Number of Entity Sets
00365 * \param tag_handles Array of tag handles
00366 * \param num_tags Number of tag handles
00367 * \param tuples The returned tuple_list structure
00368 */
00369 ErrorCode create_tuples( Range& ent_sets, Tag* tag_handles, unsigned int num_tags, TupleList** tuples );
00370
00371 /* \brief Consolidate an array of n-tuples lists into one n-tuple list with no duplicates
00372 * An array of list of n-tuples are consolidated into a single list of n-tuples
00373 * with all duplicates removed. Only integer columns in the tuple_list are assumed to
00374 * be used.
00375 *
00376 * \param all_tuples Array of tuple_lists to consolidate to one
00377 * \param num_tuples Number of tuple_lists
00378 * \param unique_tuples The consolidated tuple_list with no duplicates
00379 */
00380 ErrorCode consolidate_tuples( TupleList** all_tuples, unsigned int num_tuples, TupleList** unique_tuples );
00381
00382 /* \brief Calculate integrated field values for groups of entities
00383 * An integrated field value, as defined by the field function,
00384 * is calculated for each group of entities passed in.
00385 *
00386 * \param groups The vector contains vectors of entity handles, each representing a group
00387 * \param integ_vals The integrated field values for each group
00388 * \param norm_tag The tag name of the vertex-based field to be integrated
00389 * \param num_integ_pts The number of Gaussian integration points to use in each dimension
00390 * \param integ_type Type of integration to perform
00391 */
00392 ErrorCode get_group_integ_vals( std::vector< std::vector< EntityHandle > >& groups,
00393 std::vector< double >& integ_vals,
00394 const char* norm_tag,
00395 int num_integ_pts,
00396 Coupler::IntegType integ_type );
00397
00398 /* \brief Apply a normalization factor to group of entities
00399 * Multiply a normalization factor with the value of norm_tag for each vertex
00400 * of each entity in a group. Save the value back to norm_tag on each vertex.
00401 *
00402 * \param entity_sets The vector contains vectors of entity set handles, each containing the
00403 * members of a group \param norm_factors The normalization factors for each group \param
00404 * norm_tag The tag to be normalized on each group \param integ_type Type of integration to
00405 * perform
00406 */
00407 ErrorCode apply_group_norm_factor( std::vector< std::vector< EntityHandle > >& entity_sets,
00408 std::vector< double >& norm_factors,
00409 const char* norm_tag,
00410 Coupler::IntegType integ_type );
00411
00412 /*
00413 * this method will look at source (and target sets?) sets, and look for the SEM_DIMS tag
00414 * if it exists, it will trigger a spectral element caching, with the order specified
00415 */
00416 ErrorCode initialize_spectral_elements( EntityHandle rootSource,
00417 EntityHandle rootTarget,
00418 bool& specSou,
00419 bool& specTar );
00420
00421 /*
00422 * this method will put in an array, interleaved, the points of interest for coupling
00423 * with a target mesh (so where do we need to compute the field of interest)
00424 */
00425 ErrorCode get_gl_points_on_elements( Range& targ_elems, std::vector< double >& vpos, int& numPointsOfInterest );
00426
00427 /* Get functions */
00428
00429 inline Interface* mb_impl() const
00430 {
00431 return mbImpl;
00432 }
00433 inline AdaptiveKDTree* my_tree() const
00434 {
00435 return myTree;
00436 }
00437 inline EntityHandle local_root() const
00438 {
00439 return localRoot;
00440 }
00441 inline const std::vector< double >& all_boxes() const
00442 {
00443 return allBoxes;
00444 }
00445 inline ParallelComm* my_pc() const
00446 {
00447 return myPc;
00448 }
00449 inline const Range& target_ents() const
00450 {
00451 return targetEnts;
00452 }
00453 inline int my_id() const
00454 {
00455 return myId;
00456 }
00457 inline const Range& my_range() const
00458 {
00459 return myRange;
00460 }
00461 inline TupleList* mapped_pts() const
00462 {
00463 return mappedPts;
00464 }
00465 inline int num_its() const
00466 {
00467 return numIts;
00468 }
00469 // used for spherical tests
00470 inline void set_spherical( bool arg1 = true )
00471 {
00472 spherical = arg1;
00473 }
00474
00475 private:
00476 // Given a coordinate position, find all entities containing
00477 // the point and the natural coords in those ents
00478 ErrorCode nat_param( double xyz[3],
00479 std::vector< EntityHandle >& entities,
00480 std::vector< CartVect >& nat_coords,
00481 double epsilon = 0.0 );
00482
00483 ErrorCode interp_field( EntityHandle elem, CartVect nat_coord, Tag tag, double& field );
00484
00485 ErrorCode constant_interp( EntityHandle elem, Tag tag, double& field );
00486
00487 ErrorCode test_local_box( double* xyz,
00488 int from_proc,
00489 int remote_index,
00490 int index,
00491 bool& point_located,
00492 double rel_eps = 0.0,
00493 double abs_eps = 0.0,
00494 TupleList* tl = NULL );
00495
00496 /* \brief MOAB instance
00497 */
00498 Interface* mbImpl;
00499
00500 /* \brief Kdtree for local mesh
00501 */
00502 AdaptiveKDTree* myTree;
00503
00504 /* \brief Local root of the kdtree
00505 */
00506 EntityHandle localRoot;
00507
00508 /* \brief Min/max bounding boxes for all proc tree roots
00509 */
00510 std::vector< double > allBoxes;
00511
00512 /* \brief ParallelComm object for this coupler
00513 */
00514 ParallelComm* myPc;
00515
00516 /* \brief Id of this coupler
00517 */
00518 int myId;
00519
00520 /* \brief Range of source elements
00521 */
00522 Range myRange;
00523
00524 /* \brief Range of target entities
00525 */
00526 Range targetEnts;
00527
00528 /* \brief List of locally mapped tuples
00529 * Tuples contain the following:
00530 * n = # mapped points
00531 * vul[i] = local handle of mapped entity
00532 * vr[3*i..3*i+2] = natural coordinates in mapped entity
00533 */
00534 TupleList* mappedPts;
00535
00536 /* \brief Tuple list of target points and interpolated data
00537 * Tuples contain the following:
00538 * n = # target points
00539 * vi[3*i] = remote proc mapping target point
00540 * vi[3*i+1] = local index of target point
00541 * vi[3*i+2] = remote index of target point
00542 */
00543 TupleList* targetPts;
00544
00545 /* \brief Number of iterations of tree building before failing
00546 *
00547 */
00548 int numIts;
00549
00550 // Entity dimension
00551 int max_dim;
00552
00553 // A cached spectral element for source and target, separate
00554 // Assume that their number of GL points (order + 1) does not change
00555 // If it does change, we need to reinitialize it
00556 void* _spectralSource;
00557 void* _spectralTarget;
00558 moab::Tag _xm1Tag, _ym1Tag, _zm1Tag;
00559 int _ntot;
00560
00561 // spherical coupling
00562 bool spherical;
00563 };
00564
00565 inline ErrorCode Coupler::interpolate( Coupler::Method method,
00566 Tag tag,
00567 double* interp_vals,
00568 TupleList* tl,
00569 bool normalize )
00570 {
00571 int num_pts = ( tl ? tl->get_n() : targetPts->get_n() );
00572 return interpolate( &method, &tag, &num_pts, 1, interp_vals, tl, normalize );
00573 }
00574
00575 } // namespace moab
00576
00577 #endif